Initial YakPanel commit
This commit is contained in:
419
class_v2/site_dir_auth_v2.py
Normal file
419
class_v2/site_dir_auth_v2.py
Normal file
@@ -0,0 +1,419 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# YakPanel
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2017 YakPanel(www.yakpanel.com) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: zhwen <zhw@yakpanel.com>
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#------------------------------
|
||||
# 站点目录密码保护
|
||||
#------------------------------
|
||||
import public,re,os,json,shutil
|
||||
from public.validate import Param
|
||||
|
||||
class SiteDirAuth:
|
||||
# 取目录加密状态
|
||||
def __init__(self):
|
||||
self.setup_path = public.GetConfigValue('setup_path')
|
||||
self.conf_file = self.setup_path + "/panel/data/site_dir_auth.json"
|
||||
# 读取配置
|
||||
def _read_conf(self):
|
||||
conf = public.readFile(self.conf_file)
|
||||
if not conf:
|
||||
conf = {}
|
||||
public.writeFile(self.conf_file,json.dumps(conf))
|
||||
return conf
|
||||
try:
|
||||
conf = json.loads(conf)
|
||||
if not isinstance(conf,dict):
|
||||
conf = {}
|
||||
public.writeFile(self.conf_file, json.dumps(conf))
|
||||
except:
|
||||
conf = {}
|
||||
public.writeFile(self.conf_file, json.dumps(conf))
|
||||
return conf
|
||||
|
||||
def _write_conf(self,conf,site_name):
|
||||
c = self._read_conf()
|
||||
if not c or site_name not in c:
|
||||
c[site_name] = [conf]
|
||||
else:
|
||||
if site_name in c:
|
||||
c[site_name].append(conf)
|
||||
public.writeFile(self.conf_file,json.dumps(c))
|
||||
|
||||
def _check_site_authorization(self,site_name):
|
||||
webserver=public.get_webserver()
|
||||
conf_file = "{setup_path}/panel/vhost/{webserver}/{site_name}.conf".format(
|
||||
setup_path=self.setup_path, site_name=site_name,webserver=webserver)
|
||||
if "Authorization" in public.readFile(conf_file):
|
||||
return True
|
||||
|
||||
|
||||
# 设置目录加密
|
||||
def set_dir_auth(self,get):
|
||||
'''
|
||||
get.name auth_name
|
||||
get.site_dir auth_dir
|
||||
get.username username
|
||||
get.password password
|
||||
get.id site id
|
||||
:param get:
|
||||
:return:
|
||||
'''
|
||||
# 校验参数
|
||||
try:
|
||||
get.validate([
|
||||
Param('site_dir').String(),
|
||||
Param('name').String(),
|
||||
Param('username').String(),
|
||||
Param('password').String(),
|
||||
Param('id').Integer(),
|
||||
], [
|
||||
public.validate.trim_filter(),
|
||||
])
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
return public.return_message(-1, 0, str(ex))
|
||||
# if len(get.username) < 3 or len(get.password) < 3:
|
||||
# return public.return_msg_gettext(False, public.lang("Username or password cannot be less than 3 characters"))
|
||||
# name = get.name
|
||||
param = self.__check_param(get)
|
||||
if param['status']==-1:
|
||||
return param
|
||||
param = param['message']
|
||||
password = param['password']
|
||||
username = param['username']
|
||||
name = param['name']
|
||||
site_dir = get.site_dir
|
||||
if public.get_webserver() == "openlitespeed":
|
||||
return public.return_message(-1, 0, public.lang("OpenLiteSpeed is currently not supported"))
|
||||
# if not hasattr(get,"password") or not get.password or not hasattr(get,"username") or not get.username:
|
||||
# return public.return_msg_gettext(False, public.lang("Please enter an account or password"))
|
||||
if not get.site_dir:
|
||||
return public.return_message(-1, 0, public.lang("Please enter the directory to be protected"))
|
||||
if not get.name:
|
||||
return public.return_message(-1, 0, public.lang("Please enter the Name"))
|
||||
passwd = public.hasPwd(password)
|
||||
site_info = self.get_site_info(get.id)
|
||||
site_name = site_info["site_name"]
|
||||
if self._check_site_authorization(site_name):
|
||||
return public.return_message(-1, 0, public.lang("Site password protection has been set, please cancel and then set. Site directory --> Password access"))
|
||||
if self._check_dir_auth(site_name, name,site_dir):
|
||||
return public.return_message(-1, 0, public.lang("Directory has been protected"))
|
||||
auth = "{user}:{passwd}".format(user=username,passwd=passwd)
|
||||
auth_file = '{setup_path}/pass/{site_name}'.format(setup_path=self.setup_path,site_name=site_name)
|
||||
if not os.path.exists(auth_file):
|
||||
os.makedirs(auth_file)
|
||||
auth_file = auth_file+"/{}.pass".format(name)
|
||||
public.writeFile(auth_file,auth)
|
||||
# 配置独立认证文件
|
||||
self.set_dir_auth_file(site_info["site_path"],site_name,name,username,site_dir,auth_file)
|
||||
# 配置站点主文件
|
||||
result = self.set_conf(site_name,"create")
|
||||
if result:
|
||||
return public.return_message(0,0,result)
|
||||
# 检查配置
|
||||
webserver = public.get_webserver()
|
||||
result=self.check_site_conf(webserver,site_name,name)
|
||||
if result:
|
||||
return public.return_message(0,0,result)
|
||||
# 写配置
|
||||
conf = {"name":name,"site_dir":get.site_dir,"auth_file":auth_file}
|
||||
self._write_conf(conf,site_name)
|
||||
public.serviceReload()
|
||||
return public.return_message(0, 0, public.lang("Successfully created"))
|
||||
|
||||
# 检查配置是否存在
|
||||
def _check_dir_auth(self, site_name, name,site_dir):
|
||||
conf = self._read_conf()
|
||||
if not conf:
|
||||
return False
|
||||
if site_name in conf:
|
||||
for i in conf[site_name]:
|
||||
if name in i.values() or site_dir == i["site_dir"]:
|
||||
return True
|
||||
|
||||
# 获取当前站点php版本
|
||||
def get_site_php_version(self,siteName):
|
||||
try:
|
||||
conf = public.readFile(self.setup_path + '/panel/vhost/'+public.get_webserver()+'/'+siteName+'.conf');
|
||||
if public.get_webserver() == 'nginx':
|
||||
rep = r"enable-php-(\w{2,5})\.conf"
|
||||
tmp = re.search(rep,conf)
|
||||
if not tmp:
|
||||
rep = r"enable-php-(\d+-wpfastcgi).conf"
|
||||
re.search(rep, conf)
|
||||
else:
|
||||
rep = r"php-cgi-(\w{2,5})\.sock"
|
||||
tmp = re.search(rep,conf).groups()
|
||||
if tmp:
|
||||
return tmp[0]
|
||||
else:
|
||||
return ""
|
||||
except:
|
||||
return public.return_msg_gettext(False, public.lang("Apache2.2 does NOT support MultiPHP!"))
|
||||
|
||||
# 获取站点名
|
||||
def get_site_info(self,id):
|
||||
site_info = public.M('sites').where('id=?', (id,)).field('name,path').find()
|
||||
return {"site_name":site_info["name"],"site_path":site_info["path"]}
|
||||
|
||||
def change_dir_auth_file_nginx_phpver(self,site_name,phpv,auth_name):
|
||||
file_path = "{setup_path}/panel/vhost/nginx/dir_auth/{site_name}/{auth_name}.conf".format(
|
||||
setup_path=self.setup_path,site_name=site_name,auth_name=auth_name)
|
||||
conf = public.readFile(file_path)
|
||||
if not conf:
|
||||
return False
|
||||
|
||||
if phpv == 'other':
|
||||
php_conf = "include /www/server/panel/vhost/other_php/{}/enable-php-other.conf;".format(site_name)
|
||||
else:
|
||||
php_conf = 'include enable-php-{}.conf;'.format(phpv)
|
||||
|
||||
rep = r"include\s+(enable-php-\w+|/www/server/panel/vhost/other_php/{}/enable-php-other)\.conf;".format(site_name)
|
||||
conf = re.sub(rep,php_conf,conf)
|
||||
|
||||
public.writeFile(file_path,conf)
|
||||
|
||||
# 设置独立认证文件
|
||||
def set_dir_auth_file(self,site_path,site_name,name,username,site_dir,auth_file):
|
||||
php_ver = self.get_site_php_version(site_name)
|
||||
php_conf = ""
|
||||
if php_ver:
|
||||
if php_ver == 'other':
|
||||
php_conf = "include /www/server/panel/vhost/other_php/{}/enable-php-{}.conf;".format(site_name,php_ver)
|
||||
else:
|
||||
php_conf = "include enable-php-{}.conf;".format(php_ver)
|
||||
|
||||
for i in ["nginx","apache"]:
|
||||
file_path = "{setup_path}/panel/vhost/{webserver}/dir_auth/{site_name}"
|
||||
if i == "nginx":
|
||||
# 设置nginx
|
||||
conf = '''location ~* ^%s* {
|
||||
#AUTH_START
|
||||
auth_basic "Authorization";
|
||||
auth_basic_user_file %s;
|
||||
%s
|
||||
#AUTH_END
|
||||
}''' % (site_dir,auth_file,php_conf)
|
||||
else:
|
||||
# 设置apache
|
||||
conf = '''<Directory "{site_path}{site_dir}">
|
||||
#AUTH_START
|
||||
AuthType basic
|
||||
AuthName "Authorization "
|
||||
AuthUserFile {auth_file}
|
||||
Require user {username}
|
||||
#AUTH_END
|
||||
SetOutputFilter DEFLATE
|
||||
Options FollowSymLinks
|
||||
AllowOverride All
|
||||
#Require all granted
|
||||
DirectoryIndex index.php index.html index.htm default.php default.html default.htm
|
||||
</Directory>'''.format(site_path=site_path,site_dir=site_dir,auth_file=auth_file,username=username,site_name=site_name)
|
||||
conf_file = file_path.format(setup_path=self.setup_path,site_name=site_name,webserver=i)
|
||||
if not os.path.exists(conf_file):
|
||||
os.makedirs(conf_file)
|
||||
conf_file = conf_file + '/{}.conf'.format(name)
|
||||
public.writeFile(conf_file,conf)
|
||||
|
||||
# 设置apache配置
|
||||
def set_conf(self,site_name,act):
|
||||
for i in ["nginx", "apache"]:
|
||||
dir_auth_file = "%s/panel/vhost/%s/dir_auth/%s/*.conf" % (self.setup_path,i,site_name,)
|
||||
file = self.setup_path + "/panel/vhost/{}/".format(i) + site_name + ".conf"
|
||||
shutil.copyfile(file, '/tmp/{}_file_bk.conf'.format(i))
|
||||
|
||||
if os.path.exists(file):
|
||||
conf = public.readFile(file)
|
||||
if i == "apache":
|
||||
if act == "create":
|
||||
rep = "IncludeOptional.*\\/dir_auth\\/.*conf(\n|.)+<\\/VirtualHost>"
|
||||
rep1 = "</VirtualHost>"
|
||||
if not re.search(rep, conf):
|
||||
conf = conf.replace(rep1,
|
||||
"\n\t#Directory protection rules, do not manually delete\n\tIncludeOptional {}\n</VirtualHost>".format(
|
||||
dir_auth_file))
|
||||
else:
|
||||
rep = "\n*#Directory protection rules, do not manually delete\n+\\s+IncludeOptional[\\s\\w\\/\\.\\*]+"
|
||||
conf = re.sub(rep, '', conf)
|
||||
public.writeFile(file, conf)
|
||||
else:
|
||||
if act == "create":
|
||||
rep = "#SSL-END(\n|.)+include.*\\/dir_auth\\/.*conf;"
|
||||
rep1 = "#SSL-END"
|
||||
if not re.search(rep,conf):
|
||||
conf = conf.replace(rep1, rep1 + "\n\t#Directory protection rules, do not manually delete\n\tinclude {};".format(dir_auth_file))
|
||||
else:
|
||||
rep = "\n*#Directory protection rules, do not manually delete\n+\\s+include[\\s\\w\\/\\.\\*]+;"
|
||||
conf = re.sub(rep, '', conf)
|
||||
public.writeFile(file, conf)
|
||||
|
||||
# 验证站点配置
|
||||
def check_site_conf(self,webserver,site_name,name):
|
||||
isError = public.checkWebConfig()
|
||||
auth_file = "{setup_path}/panel/vhost/{webserver}/dir_auth/{site_name}/{name}.conf".format(setup_path=self.setup_path,webserver=webserver,site_name=site_name,name=name)
|
||||
if (isError != True):
|
||||
os.remove(auth_file)
|
||||
# a_conf = self._read_conf()
|
||||
# for i in range(len(a_conf)-1,-1,-1):
|
||||
# if site_name == a_conf[i]["sitename"] and a_conf[i]["proxyname"]:
|
||||
# del a_conf[i]
|
||||
return public.return_msg_gettext(False, public.lang('ERROR: %s<br><a style="color:red;">' % public.lang("Configuration ERROR") + isError.replace("\n", '<br>') + '</a>'))
|
||||
|
||||
# 删除密码保护
|
||||
def delete_dir_auth(self,get):
|
||||
'''
|
||||
get.id
|
||||
get.name
|
||||
:param get:
|
||||
:return:
|
||||
'''
|
||||
try:
|
||||
get.validate([
|
||||
Param('name').String(),
|
||||
Param('id').Integer(),
|
||||
], [
|
||||
public.validate.trim_filter(),
|
||||
])
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
return public.return_message(-1, 0, str(ex))
|
||||
|
||||
name = get.name
|
||||
site_info = self.get_site_info(get.id)
|
||||
site_name = site_info["site_name"]
|
||||
conf = self._read_conf()
|
||||
if site_name not in conf:
|
||||
return public.return_message(-1,0,"The website does not exist in the configuration:{}",(site_name,))
|
||||
for i in range(len(conf[site_name])):
|
||||
if name in conf[site_name][i].values():
|
||||
print(conf[site_name][i])
|
||||
del(conf[site_name][i])
|
||||
if not conf[site_name]:
|
||||
del(conf[site_name])
|
||||
break
|
||||
public.writeFile(self.conf_file,json.dumps(conf))
|
||||
for i in ["nginx", "apache"]:
|
||||
file_path = "{setup_path}/panel/vhost/{webserver}/dir_auth/{site_name}/{name}.conf".format(webserver=i,
|
||||
setup_path=self.setup_path,
|
||||
site_name=site_name,
|
||||
name=name)
|
||||
os.remove(file_path)
|
||||
if not conf:
|
||||
self.set_conf(site_name,"delete")
|
||||
if not hasattr(get,'multiple'):
|
||||
public.serviceReload()
|
||||
return public.return_message(0, 0, public.lang("Successfully deleted!"))
|
||||
|
||||
# 修改目录保护密码
|
||||
def modify_dir_auth_pass(self,get):
|
||||
'''
|
||||
get.id
|
||||
get.name
|
||||
get.username
|
||||
get.password
|
||||
:param get:
|
||||
:return:
|
||||
'''
|
||||
# 校验参数
|
||||
try:
|
||||
get.validate([
|
||||
Param('name').String(),
|
||||
Param('username').String(),
|
||||
Param('password').String(),
|
||||
Param('id').Integer(),
|
||||
|
||||
], [
|
||||
public.validate.trim_filter(),
|
||||
])
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
return public.return_message(-1, 0, str(ex))
|
||||
|
||||
# if not hasattr(get,"password") or not get.password or not hasattr(get,"username") or not get.username:
|
||||
# return public.return_msg_gettext(False, public.lang("Username or password cannot be less than 3 characters"))
|
||||
param = self.__check_param(get)
|
||||
if param['status']==-1:
|
||||
return param
|
||||
param = param['message']
|
||||
password = param['password']
|
||||
username = param['username']
|
||||
name = get.name
|
||||
site_info = self.get_site_info(get.id)
|
||||
site_name = site_info["site_name"]
|
||||
passwd = public.hasPwd(get.password)
|
||||
auth = "{user}:{passwd}".format(user=get.username,passwd=passwd)
|
||||
auth_file = '{setup_path}/pass/{site_name}/{name}.pass'.format(setup_path=self.setup_path,site_name=site_name,name=name)
|
||||
public.writeFile(auth_file,auth)
|
||||
public.serviceReload()
|
||||
return public.return_message(0, 0, public.lang("Setup successfully!"))
|
||||
|
||||
# 获取目录保护列表
|
||||
def get_dir_auth(self,get):
|
||||
'''
|
||||
get.id
|
||||
get.sitename
|
||||
:param get:
|
||||
:return:
|
||||
'''
|
||||
# 校验参数
|
||||
try:
|
||||
get.validate([
|
||||
Param('id').Integer(),
|
||||
|
||||
], [
|
||||
public.validate.trim_filter(),
|
||||
])
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
return public.return_message(-1, 0, str(ex))
|
||||
|
||||
if not hasattr(get, 'siteName'):
|
||||
site_info = self.get_site_info(get.id)
|
||||
site_name = site_info["site_name"]
|
||||
else:
|
||||
site_name = get.siteName
|
||||
conf = self._read_conf()
|
||||
if site_name in conf:
|
||||
return public.return_message(0,0,{site_name:conf[site_name]})
|
||||
return public.return_message(0,0,{})
|
||||
|
||||
def __check_param(self, get):
|
||||
values = {}
|
||||
if hasattr(get, "password"):
|
||||
if not get.password:
|
||||
return public.return_message(-1, 0, public.lang("Please enter password!"))
|
||||
password = get.password.strip()
|
||||
if len(password) < 3:
|
||||
return public.return_message(-1, 0, public.lang("Password cannot be less than 3 characters"))
|
||||
if re.search(r'\s', password):
|
||||
return public.return_message(-1, 0, public.lang("Password cannot contain spaces"))
|
||||
values['password'] = password
|
||||
|
||||
if hasattr(get, "username"):
|
||||
if not get.username:
|
||||
return public.return_message(-1, 0, public.lang("Please enter username!"))
|
||||
username = get.username.strip()
|
||||
if len(username) < 3:
|
||||
return public.return_message(-1, 0, public.lang("Username cannot be less than 3 characters"))
|
||||
if re.search(r'\s', username):
|
||||
return public.return_message(-1, 0, public.lang("Username cannot contain spaces"))
|
||||
values['username'] = username
|
||||
|
||||
if hasattr(get, "name"):
|
||||
if not get.name:
|
||||
return public.return_message(-1, 0, public.lang("Please enter a name!"))
|
||||
name = get.name.strip()
|
||||
if len(name) < 3:
|
||||
return public.return_message(-1, 0, public.lang("Name cannot be less than 3 characters"))
|
||||
if re.search(r'\s', name):
|
||||
return public.return_message(-1, 0, public.lang("Name cannot contain spaces"))
|
||||
if re.search('[\\/\"\'\\!@#$%^&*()+={}\\[\\]\\:\\;\\?><,./\\\\]+', name):
|
||||
return public.return_message(-1, 0, public.lang("Name format must be [ aaa_bbb ]"))
|
||||
values['name'] = name
|
||||
|
||||
return public.return_message(0,0, values)
|
||||
Reference in New Issue
Block a user