Merge pull request #30 from capricornxl/feature/update_to_layui
更新一些小功能
This commit is contained in:
commit
cda291f075
|
@ -18,13 +18,16 @@ LDAP_LOGIN_USER = r'修改成自己的'
|
|||
LDAP_LOGIN_USER_PWD = r'修改为自己的'
|
||||
|
||||
# BASE DN,账号的查找DN路径,例如:'DC=abc,DC=com',可以指定到OU之下,例如:'OU=RD,DC=abc,DC=com'。
|
||||
# BASE_DN限制得越细,搜索用户的目录也就越小,一般情况下可以通过SEARCH_FILTER来过滤
|
||||
BASE_DN = r'修改成自己的'
|
||||
|
||||
# ldap的search_filter,如果需要修改,请保持用户账号部分为 点位符{} (代码中通过占位符引入账号)
|
||||
# 例如,AD的用户账号属性是sAMAccountName,那么匹配的账号请配置成sAMAccountName={}
|
||||
# LDAP中用户账号属性可能是uuid,那么匹配的账号请配置成uuid={}
|
||||
# 默认配置是AD环境的
|
||||
SEARCH_FILTER = r'(&(objectclass=user)(sAMAccountName={}))'
|
||||
# ldap的search_filter,如果需要修改,请保持用户账号部分为 点位符{0} (代码中通过占位符引入账号)
|
||||
# 例如,AD的用户账号属性是sAMAccountName,那么匹配的账号请配置成sAMAccountName={0}
|
||||
# LDAP中用户账号属性可能是uuid,那么匹配的账号请配置成uuid={0}
|
||||
# 如果想限制用户在哪个组的才能使用,可以写成这样:
|
||||
# r'(&(objectClass=user)(memberof=CN=mis,OU=Groups,OU=OnTheJob,DC=abc,DC=com)(sAMAccountName={0}))', memberof 是需要匹配的组
|
||||
# 默认配置是AD环境的,查询语句可以自行使用Apache Directory Studio测试后再配置
|
||||
SEARCH_FILTER = r'(&(objectclass=user)(sAMAccountName={0}))'
|
||||
|
||||
# 是否启用SSL,
|
||||
# 注意:AD中必须使用SSL才能修改密码(这里被坑了N久...),自行部署下AD的证书服务,并颁发CA证书,重启服务器生效。具体教程百度一下,有很多。
|
||||
|
|
|
@ -30,11 +30,10 @@ LOGGING = {
|
|||
'disable_existing_loggers': False,
|
||||
'formatters': {
|
||||
'verbose': {
|
||||
'format': '%(asctime)s %(levelname)s %(pathname)s %(module)s.%(funcName)s %(lineno)d: %(message)s'
|
||||
# 日志格式
|
||||
'format': '%(asctime)s %(levelname)s %(message)s'
|
||||
},
|
||||
'simple': {
|
||||
'format': '%(asctime)s %(levelname)s %(pathname)s %(module)s.%(funcName)s %(lineno)d: %(message)s'
|
||||
'format': '%(asctime)s %(levelname)s %(message)s'
|
||||
},
|
||||
},
|
||||
'filters': {
|
||||
|
@ -54,7 +53,7 @@ LOGGING = {
|
|||
'level': 'DEBUG',
|
||||
'class': 'logging.FileHandler',
|
||||
# 日志保存文件
|
||||
'filename': '%s/log.log' % LOG_PATH,
|
||||
'filename': '%s/all.log' % LOG_PATH,
|
||||
# 日志格式,与上边的设置对应选择
|
||||
'formatter': 'verbose'
|
||||
}
|
||||
|
|
|
@ -37,6 +37,13 @@ AD必须使用SSL才能修改密码(这里被坑了N久...)
|
|||
### 2023/01/15 -- 更新:
|
||||
+ 兼容PC与移动端的显示(使用Layui)
|
||||
+ 修复一些BUG
|
||||
+ 移除auto-install.sh中的redis部署步骤
|
||||
+ 抽出应用中的授权验证跳转的代码,单独做成一个auth页面,可实现选择首页是进入修改密码,还是自动跳转重置页面。
|
||||
+ 调整部分文件说明
|
||||
+ 添加日志装饰器记录请求日志
|
||||
+ 优化ad_ops中异常的处理
|
||||
|
||||
**如果想在点击应用之后自动跳转到重置页面,请将回调接口配置成YOURDOMAIN.com/auth**
|
||||
|
||||
|
||||
## 线上环境需要的基础环境:
|
||||
|
@ -118,7 +125,6 @@ chmod +x auto-install.sh
|
|||
#### 以上配置修改完成之后,则可以通过配置的域名直接访问。
|
||||
|
||||
|
||||
|
||||
# 手动部署:
|
||||
#### 自行安装完python3之后,使用python3目录下的pip3进行安装依赖:
|
||||
#### 我自行安装的Python路径为/usr/local/python3
|
||||
|
|
|
@ -3,12 +3,12 @@ import logging
|
|||
import os
|
||||
from django.shortcuts import render
|
||||
from utils.ad_ops import AdOps
|
||||
from ldap3.core.exceptions import LDAPException
|
||||
import urllib.parse as url_encode
|
||||
from utils.format_username import format2username, get_user_is_active, get_email_from_userinfo
|
||||
from .form import CheckForm
|
||||
from .utils import code_2_user_detail, ops_account
|
||||
from django.conf import settings
|
||||
from utils.logger_filter import decorator_request_logger
|
||||
|
||||
APP_ENV = os.getenv('APP_ENV')
|
||||
if APP_ENV == 'dev':
|
||||
|
@ -43,6 +43,7 @@ scan_params = PARAMS()
|
|||
_ops = scan_params.ops
|
||||
|
||||
|
||||
@decorator_request_logger(logger)
|
||||
def auth(request):
|
||||
home_url = '%s://%s' % (request.scheme, HOME_URL)
|
||||
corp_id = scan_params.corp_id
|
||||
|
@ -69,6 +70,7 @@ def auth(request):
|
|||
logger.error('[异常] 请求方法:%s,请求路径%s' % (request.method, request.path))
|
||||
|
||||
|
||||
@decorator_request_logger(logger)
|
||||
def index(request):
|
||||
"""
|
||||
用户自行修改密码/首页
|
||||
|
@ -79,10 +81,8 @@ def index(request):
|
|||
|
||||
if request.method == 'GET':
|
||||
return render(request, 'index.html', locals())
|
||||
else:
|
||||
logger.error('[异常] 请求方法:%s,请求路径%s' % (request.method, request.path))
|
||||
|
||||
if request.method == 'POST':
|
||||
elif request.method == 'POST':
|
||||
# 对前端提交的数据进行二次验证,防止恶意提交简单密码或篡改账号。
|
||||
check_form = CheckForm(request.POST)
|
||||
if check_form.is_valid():
|
||||
|
@ -127,6 +127,7 @@ def index(request):
|
|||
return render(request, msg_template, context)
|
||||
|
||||
|
||||
@decorator_request_logger(logger)
|
||||
def reset_password(request):
|
||||
"""
|
||||
钉钉扫码并验证信息通过之后,在重置密码页面将用户账号进行绑定
|
||||
|
@ -242,6 +243,7 @@ def reset_password(request):
|
|||
return render(request, msg_template, context)
|
||||
|
||||
|
||||
@decorator_request_logger(logger)
|
||||
def unlock_account(request):
|
||||
"""
|
||||
解锁账号
|
||||
|
@ -292,6 +294,7 @@ def unlock_account(request):
|
|||
return render(request, msg_template, context)
|
||||
|
||||
|
||||
@decorator_request_logger(logger)
|
||||
def messages(request):
|
||||
_msg = request.GET.get('msg')
|
||||
button_click = request.GET.get('button_click')
|
||||
|
|
|
@ -136,6 +136,8 @@ class AdOps(object):
|
|||
self.__conn()
|
||||
return True, self.conn.search(BASE_DN, SEARCH_FILTER.format(username),
|
||||
attributes=['sAMAccountName'])
|
||||
except IndexError:
|
||||
return False, "AdOps Exception: Connect.search未能检索到任何信息,当前账号可能被排除在<SEARCH_FILTER>之外,请联系管理员处理。"
|
||||
except Exception as e:
|
||||
return False, "AdOps Exception: {}".format(e)
|
||||
|
||||
|
@ -149,6 +151,8 @@ class AdOps(object):
|
|||
self.__conn()
|
||||
self.conn.search(BASE_DN, SEARCH_FILTER.format(username), attributes=['name'])
|
||||
return True, self.conn.entries[0]['name']
|
||||
except IndexError:
|
||||
return False, "AdOps Exception: Connect.search未能检索到任何信息,当前账号可能被排除在<SEARCH_FILTER>之外,请联系管理员处理。"
|
||||
except Exception as e:
|
||||
return False, "AdOps Exception: {}".format(e)
|
||||
|
||||
|
@ -163,6 +167,8 @@ class AdOps(object):
|
|||
self.conn.search(BASE_DN, SEARCH_FILTER.format(username),
|
||||
attributes=['distinguishedName'])
|
||||
return True, str(self.conn.entries[0]['distinguishedName'])
|
||||
except IndexError:
|
||||
return False, "AdOps Exception: Connect.search未能检索到任何信息,当前账号可能被排除在<SEARCH_FILTER>之外,请联系管理员处理。"
|
||||
except Exception as e:
|
||||
return False, "AdOps Exception: {}".format(e)
|
||||
|
||||
|
@ -177,6 +183,8 @@ class AdOps(object):
|
|||
self.conn.search(BASE_DN, SEARCH_FILTER.format(username),
|
||||
attributes=['userAccountControl'])
|
||||
return True, self.conn.entries[0]['userAccountControl']
|
||||
except IndexError:
|
||||
return False, "AdOps Exception: Connect.search未能检索到任何信息,当前账号可能被排除在<SEARCH_FILTER>之外,请联系管理员处理。"
|
||||
except Exception as e:
|
||||
return False, "AdOps Exception: {}".format(e)
|
||||
|
||||
|
@ -190,6 +198,8 @@ class AdOps(object):
|
|||
if _status:
|
||||
try:
|
||||
return True, self.conn.extend.microsoft.unlock_account(user='%s' % user_dn)
|
||||
except IndexError:
|
||||
return False, "AdOps Exception: Connect.search未能检索到任何信息,当前账号可能被排除在<SEARCH_FILTER>之外,请联系管理员处理。"
|
||||
except Exception as e:
|
||||
return False, "AdOps Exception: {}".format(e)
|
||||
else:
|
||||
|
@ -247,5 +257,7 @@ class AdOps(object):
|
|||
return True, 'unlocked'
|
||||
else:
|
||||
return False, locked_status
|
||||
except IndexError:
|
||||
return False, "AdOps Exception: Connect.search未能检索到任何信息,当前账号可能被排除在<SEARCH_FILTER>之外,请联系管理员处理。"
|
||||
except Exception as e:
|
||||
return False, "AdOps Exception: {}".format(e)
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
from functools import wraps
|
||||
from traceback import format_exc
|
||||
|
||||
|
||||
def decorator_request_logger(logger):
|
||||
def decorator(func):
|
||||
@wraps(func)
|
||||
def wrapper(request, *args, **kwargs):
|
||||
try:
|
||||
rsp = func(request, *args, **kwargs)
|
||||
logger.info(
|
||||
f'Request Arguments: {args} {kwargs}')
|
||||
# logger.info(
|
||||
# f'Request: {request.META["REMOTE_ADDR"]} {request.method} "{request.META["PATH_INFO"]}'
|
||||
# f'{request.META["QUERY_STRING"]} {request.META["SERVER_PROTOCOL"]}" {rsp.status_code} {rsp.content}')
|
||||
logger.info(rsp)
|
||||
return rsp
|
||||
except Exception as e:
|
||||
logger.error(format_exc())
|
||||
raise e
|
||||
|
||||
return wrapper
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
def decorator_default_logger(logger):
|
||||
def decorator(func):
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
logger.info(f'{args}, {kwargs}')
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except Exception as e:
|
||||
logger.error(format_exc())
|
||||
raise e
|
||||
|
||||
return wrapper
|
||||
|
||||
return decorator
|
Loading…
Reference in New Issue