Initial YakPanel commit

This commit is contained in:
Niranjan
2026-04-07 02:04:22 +05:30
commit 2826d3e7f3
5359 changed files with 1390724 additions and 0 deletions

255
class/panelApi.py Normal file
View File

@@ -0,0 +1,255 @@
#coding: utf-8
# +-------------------------------------------------------------------
# | YakPanel
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2017 YakPanel(www.yakpanel.com) All rights reserved.
# +-------------------------------------------------------------------
# | Author: hwliang <hwl@yakpanel.com>
# +-------------------------------------------------------------------
import public,os,json,time
class panelApi:
save_path = '/www/server/panel/config/api.json'
timeout = 600
max_bind = 5
def get_token(self,get):
data = self.get_api_config()
if not 'key' in data:
data['key'] = public.GetRandomString(16)
public.writeFile(self.save_path,json.dumps(data))
if 'token_crypt' in data:
data['token'] = public.de_crypt(data['token'],data['token_crypt'])
else:
data['token'] = "***********************************"
data['limit_addr'] = '\n'.join(data['limit_addr'])
data['bind'] = self.get_bind_token()
qrcode = (public.getPanelAddr() + "|" + data['token'] + "|" + data['key'] + '|' + data['bind']['token']+'|yakpanel').encode('utf-8')
data['qrcode'] = public.base64.b64encode(qrcode).decode('utf-8')
data['apps'] = sorted(data['apps'],key=lambda x: x['time'],reverse=True)
del(data['key'])
return data
def login_for_app(self,get):
from YakPanel import cache
import uuid
tid = get.tid
if(len(tid) != 32): return public.return_msg_gettext(False, public.lang("Invalid login key1"))
session_id = cache.get(tid)
if not session_id: return public.return_msg_gettext(False, public.lang("The specified key does not exist or has expired1"))
if(len(session_id) != 64): return public.return_msg_gettext(False, public.lang("Invalid login key2"))
try:
if not os.path.exists('/www/server/panel/data/app_login_check.pl'):return public.returnMsg(False, public.lang("Invalid login key3"))
key, init_time, tid2, status = public.readFile('/www/server/panel/data/app_login_check.pl').split(':')
if session_id!=key:return public.returnMsg(False, public.lang("Invalid login key4"))
if tid != tid2: return public.returnMsg(False, public.lang("The specified key does not exist or has expired5"))
if time.time() - float(init_time) > 60:
return public.returnMsg(False, public.lang("QR code validity time expired6"))
cache.set(session_id,public.md5(uuid.UUID(int=uuid.getnode()).hex),120)
import uuid
data = key + ':' + init_time + ':' + tid2 + ':' + uuid.UUID(int=uuid.getnode()).hex[-12:]
public.writeFile("/www/server/panel/data/app_login_check.pl", data)
return public.return_msg_gettext(True, public.lang("Scan code successfully, log in!"))
except:
os.remove("/www/server/panel/data/app_login_check.pl")
return public.return_msg_gettext(False, public.lang("Invalid login key"))
def get_api_config(self):
tmp = public.ReadFile(self.save_path)
if not tmp or not os.path.exists(self.save_path):
data = { "open":False, "token":"", "limit_addr":[] }
public.WriteFile(self.save_path,json.dumps(data))
public.ExecShell("chmod 600 " + self.save_path)
tmp = public.ReadFile(self.save_path)
try:
data = json.loads(tmp)
except json.JSONDecodeError:
default_config = {"open": False, "token": "", "limit_addr": []}
return default_config
is_save = False
if not 'binds' in data:
data['binds'] = []
is_save = True
if not 'apps' in data:
data['apps'] = []
is_save = True
data['binds'] = sorted(data['binds'],key=lambda x: x['time'],reverse=True)
if len(data['binds']) > 5:
data['binds'] = data['binds'][:5]
is_save = True
if is_save:
self.save_api_config(data)
return data
def save_api_config(self,data):
public.WriteFile(self.save_path,json.dumps(data))
public.set_mode(self.save_path,'600')
return True
def check_bind(self,args):
if not 'bind_token' in args or not 'client_brand' in args or not 'client_model' in args:
return 0
if not args.client_brand or not args.client_model:
return 'Invalid device'
bind = self.get_bind_token(args.bind_token)
if bind['token'] != args.bind_token:
return public.lang("The current QR code has expired, please refresh the page and rescan the code!")
apps = self.get_apps()
if len(apps) >= self.max_bind:
return public.lang('This server is bound to a maximum of {} devices, which has reached the limit!',self.max_bind)
bind['status'] = 1
bind['brand'] = args.client_brand
bind['model'] = args.client_model
self.set_bind_token(bind)
return 1
def get_bind_status(self,args):
if not public.cache_get(public.Md5(os.uname().version)):
public.cache_set(public.Md5(os.uname().version),1,60)
bind = self.get_bind_token(args.bind_token)
return bind
def get_app_bind_status(self,args):
if not 'bind_token' in args:
return 0
if self.get_app_find(args.bind_token):
return 1
return 0
def set_bind_token(self,bind):
data = self.get_api_config()
is_save = False
for i in range(len(data['binds'])):
if data['binds'][i]['token'] == bind['token']:
data['binds'][i] = bind
is_save = True
break
if is_save:
self.save_api_config(data)
return True
def get_apps(self,args = None):
data = self.get_api_config()
return data['apps']
def get_app_find(self,bind_token):
apps = self.get_apps()
for s_app in apps:
if s_app['token'] == bind_token:
return s_app
return None
def add_bind_app(self,args):
bind = self.get_bind_token(args.bind_token)
if bind['status'] == 0:
return public.return_msg_gettext(False, public.lang("Failed verification!"))
apps = self.get_apps()
if len(apps) >= self.max_bind:
return public.return_msg_gettext(False, public.lang("A server allows up to {} device bindings!", self.max_bind))
args.bind_app = args.bind_token
self.remove_bind_app(args)
data = self.get_api_config()
data['apps'].append(bind)
self.save_api_config(data)
self.remove_bind_token(args.bind_token)
return public.return_msg_gettext(True, public.lang("Bind successfully!"))
def remove_bind_token(self,bind_token):
data = self.get_api_config()
tmp_binds = []
for s_bind in data['binds']:
if bind_token == s_bind['token']:
continue
tmp_binds.append(s_bind)
data['binds'] = tmp_binds
self.save_api_config(data)
def remove_bind_app(self,args):
data = self.get_api_config()
tmp_apps = []
for s_app in data['apps']:
if args.bind_app == s_app['token']:
continue
tmp_apps.append(s_app)
data['apps'] = tmp_apps
self.save_api_config(data)
s_file = '/dev/shm/{}'.format(args.bind_app)
if os.path.exists(s_file):
os.remove(s_file)
return public.return_msg_gettext(True, public.lang("Successfully deleted!"))
def get_bind_token(self,token = None):
data = self.get_api_config()
s_time = time.time()
binds = []
bind = None
is_write = False
for i in range(len(data['binds'])):
if s_time - data['binds'][i]['time'] > self.timeout:
is_write = True
continue
binds.append(data['binds'][i])
if token:
if token == data['binds'][i]['token']:
bind = data['binds'][i]
else:
if not bind:
bind = data['binds'][i]
if not bind:
if len(binds) > 0:
binds = sorted(binds,key=lambda x: x['time'],reverse=True)
bind = binds[0]
else:
bind = {"time":s_time,"token":public.GetRandomString(18),'status':0}
binds.append(bind)
is_write = True
if is_write:
data['binds'] = binds
self.save_api_config(data)
return bind
def set_token(self,get):
if 'request_token' in get: return public.return_msg_gettext(False, public.lang("Cannot configure API through API interface"))
data = self.get_api_config()
if get.t_type == '1':
token = public.GetRandomString(32)
data['token'] = public.md5(token)
data['token_crypt'] = public.en_crypt(data['token'],token).decode('utf-8')
public.write_log_gettext('API configuration','Regenerate API-Token')
public.add_security_logs('API configuration','Regenerate API-Token')
elif get.t_type == '2':
data['open'] = not data['open']
stats = {True:'Open',False:'Close'}
if not 'token_crypt' in data:
token = public.GetRandomString(32)
data['token'] = public.md5(token)
data['token_crypt'] = public.en_crypt(data['token'],token).decode('utf-8')
public.write_log_gettext('API configuration','{} API interface',(stats[data['open']],))
public.add_security_logs('API configuration', '{} API interface', (stats[data['open']],))
token = stats[data['open']] + ' success!'
elif get.t_type == '3':
data['limit_addr'] = get.limit_addr.split('\n')
public.write_log_gettext('API configuration','Change IP limit to [{}]',(get.limit_addr,))
public.add_security_logs('API configuration', 'Change IP limit to [{}]', (get.limit_addr,))
token ='Saved successfully!'
self.save_api_config(data)
return public.return_msg_gettext(True,token)
def get_tmp_token(self,get):
if not 'request_token' in get: return public.return_msg_gettext(False, public.lang("Temporary keys can only be obtained through the API interface"))
data = self.get_api_config()
data['tmp_token'] = public.GetRandomString(64)
data['tmp_time'] = time.time()
self.save_api_config(data)
return public.return_msg_gettext(True,data['tmp_token'])