# coding: utf-8 import psutil import time import os import sys import public import re import json import pwd from flask import session from flask import request class config_api: # 本版解决自启动问题 # 文件管理重命名 __version = '0.7.2' def __init__(self): pass ##### ----- start ----- ### # 取面板列表 def getPanelListApi(self): data = public.M('panel').field( 'id,title,url,username,password,click,addtime').order('click desc').select() return public.getJson(data) def addPanelInfoApi(self): title = request.form.get('title', '') url = request.form.get('url', '') username = request.form.get('username', '') password = request.form.get('password', '') # 校验是还是重复 isAdd = public.M('panel').where( 'title=? OR url=?', (title, url)).count() if isAdd: return public.returnJson(False, '备注或面板地址重复!') isRe = public.M('panel').add('title,url,username,password,click,addtime', (title, url, username, password, 0, int(time.time()))) if isRe: return public.returnJson(True, '添加成功!') return public.returnJson(False, '添加失败!') # 删除面板资料 def delPanelInfoApi(self): mid = request.form.get('id', '') isExists = public.M('panel').where('id=?', (mid,)).count() if not isExists: return public.returnJson(False, '指定面板资料不存在!') public.M('panel').where('id=?', (mid,)).delete() return public.returnJson(True, '删除成功!') # 修改面板资料 def setPanelInfoApi(self): title = request.form.get('title', '') url = request.form.get('url', '') username = request.form.get('username', '') password = request.form.get('password', '') mid = request.form.get('id', '') # 校验是还是重复 isSave = public.M('panel').where( '(title=? OR url=?) AND id!=?', (title, url, mid)).count() if isSave: return public.returnJson(False, '备注或面板地址重复!') # 更新到数据库 isRe = public.M('panel').where('id=?', (mid,)).save( 'title,url,username,password', (title, url, username, password)) if isRe: return public.returnJson(True, '修改成功!') return public.returnJson(False, '修改失败!') def syncDateApi(self): if public.isAppleSystem(): return public.returnJson(True, '开发系统不必同步时间!') data = public.execShell('ntpdate -s time.nist.gov') if data[0] == '': return public.returnJson(True, '同步成功!') return public.returnJson(False, '同步失败:' + data[0]) def setPasswordApi(self): password1 = request.form.get('password1', '') password2 = request.form.get('password2', '') if password1 != password2: return public.returnJson(False, '两次输入的密码不一致,请重新输入!') if len(password1) < 5: return public.returnJson(False, '用户密码不能小于5位!') public.M('users').where("username=?", (session['username'],)).setField( 'password', public.md5(password1.strip())) return public.returnJson(True, '密码修改成功!') def setNameApi(self): name1 = request.form.get('name1', '') name2 = request.form.get('name2', '') if name1 != name2: return public.returnJson(False, '两次输入的用户名不一致,请重新输入!') if len(name1) < 3: return public.returnJson(False, '用户名长度不能少于3位') public.M('users').where("username=?", (session['username'],)).setField( 'username', name1.strip()) session['username'] = name1 return public.returnJson(True, '用户修改成功!') def setApi(self): webname = request.form.get('webname', '') port = request.form.get('port', '') host_ip = request.form.get('host_ip', '') domain = request.form.get('domain', '') sites_path = request.form.get('sites_path', '') backup_path = request.form.get('backup_path', '') if domain != '': reg = "^([\w\-\*]{1,100}\.){1,4}(\w{1,10}|\w{1,10}\.\w{1,10})$" if not re.match(reg, domain): return public.returnJson(False, '主域名格式不正确') if int(port) >= 65535 or int(port) < 100: return public.returnJson(False, '端口范围不正确!') if webname != public.getConfig('title'): public.setConfig('title', webname) if sites_path != public.getWwwDir(): public.setWwwDir(sites_path) if backup_path != public.getWwwDir(): public.setBackupDir(backup_path) if port != public.getHostPort(): import system_api public.setHostPort(port) system_api.system_api().restartMw() if host_ip != public.getHostAddr(): public.setHostAddr(host_ip) mhost = public.getHostAddr() info = { 'uri': '/config', 'host': mhost + ':' + port } return public.returnJson(True, '保存成功!', info) def setAdminPathApi(self): admin_path = request.form.get('admin_path', '').strip() admin_path_checks = ['/', '/close', '/login', '/do_login', '/site', '/sites', '/download_file', '/control', '/crontab', '/firewall', '/files', 'config', '/soft', '/system', '/code', '/ssl', '/plugins'] if admin_path == '': admin_path = '/' if admin_path != '/': if len(admin_path) < 6: return public.returnJson(False, '安全入口地址长度不能小于6位!') if admin_path in admin_path_checks: return public.returnJson(False, '该入口已被面板占用,请使用其它入口!') if not re.match("^/[\w\./-_]+$", admin_path): return public.returnJson(False, '入口地址格式不正确,示例: /my_panel') else: domain = public.readFile('data/domain.conf') if not domain: domain = '' limitip = public.readFile('data/limitip.conf') if not limitip: limitip = '' if not domain.strip() and not limitip.strip(): return public.returnJson(False, '警告,关闭安全入口等于直接暴露你的后台地址在外网,十分危险,至少开启以下一种安全方式才能关闭:
1、绑定访问域名
2、绑定授权IP
') admin_path_file = 'data/admin_path.pl' admin_path_old = '/' if os.path.exists(admin_path_file): admin_path_old = public.readFile(admin_path_file).strip() if admin_path_old != admin_path: public.writeFile(admin_path_file, admin_path) public.restartMw() return public.returnJson(True, '修改成功!') def closePanelApi(self): filename = 'data/close.pl' if os.path.exists(filename): os.remove(filename) return public.returnJson(True, '开启成功') public.writeFile(filename, 'True') public.execShell("chmod 600 " + filename) public.execShell("chown root.root " + filename) return public.returnJson(True, '面板已关闭!') def setIpv6StatusApi(self): ipv6_file = 'data/ipv6.pl' if os.path.exists('data/ipv6.pl'): os.remove(ipv6_file) public.writeLog('面板设置', '关闭面板IPv6兼容!') else: public.writeFile(ipv6_file, 'True') public.writeLog('面板设置', '开启面板IPv6兼容!') public.restartMw() return public.returnJson(True, '设置成功!') # 获取面板证书 def getPanelSslApi(self): cert = {} cert['privateKey'] = public.readFile('ssl/privateKey.pem') cert['certPem'] = public.readFile('ssl/certificate.pem') cert['rep'] = os.path.exists('ssl/input.pl') return public.getJson(cert) # 保存面板证书 def savePanelSslApi(self): keyPath = 'ssl/privateKey.pem' certPath = 'ssl/certificate.pem' checkCert = '/tmp/cert.pl' certPem = request.form.get('certPem', '').strip() privateKey = request.form.get('privateKey', '').strip() public.writeFile(checkCert, certPem) if privateKey: public.writeFile(keyPath, privateKey) if certPem: public.writeFile(certPath, certPem) if not public.checkCert(checkCert): return public.returnJson(False, '证书错误,请检查!') public.writeFile('ssl/input.pl', 'True') return public.returnJson(True, '证书已保存!') # 设置面板SSL def setPanelSslApi(self): sslConf = public.getRunDir() + '/data/ssl.pl' if os.path.exists(sslConf): os.system('rm -f ' + sslConf) return public.returnJson(True, 'SSL已关闭,请使用http协议访问面板!') else: os.system('pip install cffi==1.10') os.system('pip install cryptography==2.1') os.system('pip install pyOpenSSL==16.2') try: if not self.createSSL(): return public.returnJson(False, '开启失败,无法自动安装pyOpenSSL组件!

请尝试手动安装: pip install pyOpenSSL

') public.writeFile(sslConf, 'True') except Exception as ex: return public.returnJson(False, '开启失败,无法自动安装pyOpenSSL组件!

请尝试手动安装: pip install pyOpenSSL

') return public.returnJson(True, '开启成功,请使用https协议访问面板!') def getApi(self): data = {} return public.getJson(data) ##### ----- end ----- ### # 自签证书 def createSSL(self): if os.path.exists('ssl/input.pl'): return True import OpenSSL key = OpenSSL.crypto.PKey() key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048) cert = OpenSSL.crypto.X509() cert.set_serial_number(0) cert.get_subject().CN = '120.27.27.98' cert.set_issuer(cert.get_subject()) cert.gmtime_adj_notBefore(0) cert.gmtime_adj_notAfter(86400 * 3650) cert.set_pubkey(key) cert.sign(key, 'md5') cert_ca = OpenSSL.crypto.dump_certificate( OpenSSL.crypto.FILETYPE_PEM, cert) private_key = OpenSSL.crypto.dump_privatekey( OpenSSL.crypto.FILETYPE_PEM, key) if len(cert_ca) > 100 and len(private_key) > 100: public.writeFile('ssl/certificate.pem', cert_ca) public.writeFile('ssl/privateKey.pem', private_key) print cert_ca, private_key return True return False def getVersion(self): return self.__version def get(self): data = {} data['title'] = public.getConfig('title') data['site_path'] = public.getWwwDir() data['backup_path'] = public.getBackupDir() sformat = 'date +"%Y-%m-%d %H:%M:%S %Z %z"' data['systemdate'] = public.execShell(sformat)[0].strip() data['port'] = public.getHostPort() data['ip'] = public.getHostAddr() admin_path_file = 'data/admin_path.pl' if not os.path.exists(admin_path_file): data['admin_path'] = '/' else: data['admin_path'] = public.readFile(admin_path_file) ipv6_file = 'data/ipv6.pl' if os.path.exists('data/ipv6.pl'): data['ipv6'] = 'checked' else: data['ipv6'] = '' ssl_file = 'data/ssl.pl' if os.path.exists('data/ssl.pl'): data['ssl'] = 'checked' else: data['ssl'] = '' data['site_count'] = public.M('sites').count() data['username'] = public.M('users').where( "id=?", (1,)).getField('username') return data