mirror of https://github.com/openspug/spug
U 更新ldap登录
parent
6fb9430129
commit
edad14e2c7
|
@ -11,7 +11,7 @@ class User(models.Model, ModelMixin):
|
||||||
username = models.CharField(max_length=100)
|
username = models.CharField(max_length=100)
|
||||||
nickname = models.CharField(max_length=100)
|
nickname = models.CharField(max_length=100)
|
||||||
password_hash = models.CharField(max_length=100) # hashed password
|
password_hash = models.CharField(max_length=100) # hashed password
|
||||||
type = models.CharField(max_length=20, default='系统用户')
|
type = models.CharField(max_length=20, default='default')
|
||||||
is_supper = models.BooleanField(default=False)
|
is_supper = models.BooleanField(default=False)
|
||||||
is_active = models.BooleanField(default=True)
|
is_active = models.BooleanField(default=True)
|
||||||
access_token = models.CharField(max_length=32)
|
access_token = models.CharField(max_length=32)
|
||||||
|
|
|
@ -6,10 +6,10 @@ from django.views.generic import View
|
||||||
from django.db.models import F
|
from django.db.models import F
|
||||||
from libs import JsonParser, Argument, human_datetime, json_response
|
from libs import JsonParser, Argument, human_datetime, json_response
|
||||||
from apps.account.models import User, Role
|
from apps.account.models import User, Role
|
||||||
|
from libs.ldap import LDAP
|
||||||
import time
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
import json
|
import json
|
||||||
from libs.ldap import LDAP
|
|
||||||
|
|
||||||
|
|
||||||
class UserView(View):
|
class UserView(View):
|
||||||
|
@ -31,7 +31,6 @@ class UserView(View):
|
||||||
if error is None:
|
if error is None:
|
||||||
form.password_hash = User.make_password(form.pop('password'))
|
form.password_hash = User.make_password(form.pop('password'))
|
||||||
form.created_by = request.user
|
form.created_by = request.user
|
||||||
form.type = '系统用户'
|
|
||||||
User.objects.create(**form)
|
User.objects.create(**form)
|
||||||
return json_response(error=error)
|
return json_response(error=error)
|
||||||
|
|
||||||
|
@ -140,80 +139,50 @@ def login(request):
|
||||||
Argument('type')
|
Argument('type')
|
||||||
).parse(request.body)
|
).parse(request.body)
|
||||||
if error is None:
|
if error is None:
|
||||||
user = User.objects.filter(username=form.username)
|
x_real_ip = request.headers.get('x-real-ip', '')
|
||||||
|
user = User.objects.filter(username=form.username, type=form.type).first()
|
||||||
|
if user and not user.is_active:
|
||||||
|
return json_response(error="账户已被系统禁用")
|
||||||
if form.type == 'ldap':
|
if form.type == 'ldap':
|
||||||
u = LDAP()
|
ldap = LDAP()
|
||||||
valid = u.valid_user(form.username, form.password)
|
is_success, message = ldap.valid_user(form.username, form.password)
|
||||||
if valid['status']:
|
if is_success:
|
||||||
user = user.filter(type='LDAP').first()
|
if not user:
|
||||||
if user:
|
user = User.objects.create(username=form.username, nickname=form.username)
|
||||||
if not user.is_active:
|
return handle_user_info(user, x_real_ip)
|
||||||
return json_response(error="账户已被系统禁用")
|
|
||||||
if not user.role_id:
|
|
||||||
return json_response(error="LDAP用户角色未分配")
|
|
||||||
|
|
||||||
x_real_ip = request.headers.get('x-real-ip', '')
|
|
||||||
ret = handle_user_info(user, form.username, x_real_ip)
|
|
||||||
return json_response(ret)
|
|
||||||
|
|
||||||
x_real_ip = request.headers.get('x-real-ip', '')
|
|
||||||
form.access_token = uuid.uuid4().hex
|
|
||||||
form.nickname = form.username
|
|
||||||
form.token_expired = time.time() + 8 * 60 * 60
|
|
||||||
form.last_login = human_datetime()
|
|
||||||
form.last_ip = x_real_ip
|
|
||||||
form.type = 'LDAP'
|
|
||||||
form.pop('password')
|
|
||||||
User.objects.create(**form)
|
|
||||||
return json_response({
|
|
||||||
'access_token': form.access_token,
|
|
||||||
'nickname': form.username,
|
|
||||||
'is_supper': False,
|
|
||||||
'has_real_ip': True if x_real_ip else False,
|
|
||||||
'permissions': []
|
|
||||||
})
|
|
||||||
return json_response(error=valid['info'])
|
|
||||||
else:
|
else:
|
||||||
user = user.filter(type='系统用户').first()
|
|
||||||
if user and user.deleted_by is None:
|
if user and user.deleted_by is None:
|
||||||
if not user.is_active:
|
|
||||||
return json_response(error="账户已被系统禁用")
|
|
||||||
if user.verify_password(form.password):
|
if user.verify_password(form.password):
|
||||||
cache.delete(form.username)
|
return handle_user_info(user, x_real_ip)
|
||||||
x_real_ip = request.headers.get('x-real-ip', '')
|
|
||||||
ret = handle_user_info(user, form.username, x_real_ip)
|
|
||||||
return json_response(ret)
|
|
||||||
|
|
||||||
value = cache.get_or_set(form.username, 0, 86400)
|
value = cache.get_or_set(form.username, 0, 86400)
|
||||||
if value >= 3:
|
if value >= 3:
|
||||||
if user and user.is_active:
|
if user and user.is_active:
|
||||||
user.is_active = False
|
user.is_active = False
|
||||||
user.save()
|
user.save()
|
||||||
return json_response(error='账户已被系统禁用')
|
return json_response(error='账户已被系统禁用')
|
||||||
cache.set(form.username, value + 1, 86400)
|
cache.set(form.username, value + 1, 86400)
|
||||||
return json_response(error="用户名或密码错误,连续多次错误账户将会被禁用")
|
return json_response(error="用户名或密码错误,连续多次错误账户将会被禁用")
|
||||||
return json_response(error=error)
|
|
||||||
|
|
||||||
|
|
||||||
def handle_user_info(user, username, x_real_ip):
|
def handle_user_info(user, x_real_ip):
|
||||||
cache.delete(username)
|
cache.delete(user.username)
|
||||||
token_isvalid = user.access_token and len(user.access_token) == 32 and user.token_expired >= time.time()
|
token_isvalid = user.access_token and len(user.access_token) == 32 and user.token_expired >= time.time()
|
||||||
user.access_token = user.access_token if token_isvalid else uuid.uuid4().hex
|
user.access_token = user.access_token if token_isvalid else uuid.uuid4().hex
|
||||||
user.token_expired = time.time() + 8 * 60 * 60
|
user.token_expired = time.time() + 8 * 60 * 60
|
||||||
user.last_login = human_datetime()
|
user.last_login = human_datetime()
|
||||||
user.last_ip = x_real_ip
|
user.last_ip = x_real_ip
|
||||||
user.save()
|
user.save()
|
||||||
return {
|
return json_response({
|
||||||
'access_token': user.access_token,
|
'access_token': user.access_token,
|
||||||
'nickname': user.nickname,
|
'nickname': user.nickname,
|
||||||
'is_supper': user.is_supper,
|
'is_supper': user.is_supper,
|
||||||
'has_real_ip': True if x_real_ip else False,
|
'has_real_ip': True if x_real_ip else False,
|
||||||
'permissions': [] if user.is_supper else user.page_perms
|
'permissions': [] if user.is_supper else user.page_perms
|
||||||
}
|
})
|
||||||
|
|
||||||
|
|
||||||
def logout(request):
|
def logout(request):
|
||||||
request.user.token_expired = 0
|
request.user.token_expired = 0
|
||||||
request.user.save()
|
request.user.save()
|
||||||
return json_response()
|
return json_response()
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
# Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug
|
# Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug
|
||||||
# Copyright: (c) <spug.dev@gmail.com>
|
# Copyright: (c) <spug.dev@gmail.com>
|
||||||
# Released under the MIT License.
|
# Released under the MIT License.
|
||||||
|
|
||||||
import ldap
|
|
||||||
from apps.setting.models import Setting
|
from apps.setting.models import Setting
|
||||||
|
import ldap
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
class LDAP:
|
class LDAP:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
server_info = Setting.objects.exclude(key__in=('public_key', 'private_key')) \
|
server_info = Setting.objects.filter(key='ldap_service').first()
|
||||||
.filter(key='ldap_service').first()
|
|
||||||
ldap_info_dict = json.loads(server_info.value)
|
ldap_info_dict = json.loads(server_info.value)
|
||||||
self.server = ldap_info_dict['server']
|
self.server = ldap_info_dict['server']
|
||||||
self.port = ldap_info_dict['port']
|
self.port = ldap_info_dict['port']
|
||||||
|
@ -18,37 +16,18 @@ class LDAP:
|
||||||
self.admin_dn = ldap_info_dict['admin_dn']
|
self.admin_dn = ldap_info_dict['admin_dn']
|
||||||
self.password = ldap_info_dict['password']
|
self.password = ldap_info_dict['password']
|
||||||
self.base_dn = ldap_info_dict['base_dn']
|
self.base_dn = ldap_info_dict['base_dn']
|
||||||
self.con = ldap.initialize("ldap://{0}:{1}".format(self.server, self.port), bytes_mode=False)
|
|
||||||
try:
|
|
||||||
self.con.simple_bind_s(self.admin_dn, self.password)
|
|
||||||
except Exception as error:
|
|
||||||
self.error = error
|
|
||||||
|
|
||||||
def get_user_info(self, username):
|
|
||||||
try:
|
|
||||||
search_scope = ldap.SCOPE_SUBTREE
|
|
||||||
search_filter_name = self.rules
|
|
||||||
retrieve_attributes = None
|
|
||||||
search_filter = '(' + search_filter_name + "=" + username + ')'
|
|
||||||
ldap_result_id = self.con.search(self.base_dn, search_scope, search_filter, retrieve_attributes)
|
|
||||||
result_type, result_data = self.con.result(ldap_result_id, 0)
|
|
||||||
if result_type == ldap.RES_SEARCH_ENTRY:
|
|
||||||
return {'status': True, 'info': result_data[0][0]}
|
|
||||||
else:
|
|
||||||
return {'status': False, 'info': 'LDAP用户未找到'}
|
|
||||||
except Exception as error:
|
|
||||||
error = eval(str(error))
|
|
||||||
return {'status': False, 'info': error['desc']}
|
|
||||||
|
|
||||||
def valid_user(self, username, password):
|
def valid_user(self, username, password):
|
||||||
user = self.get_user_info(username)
|
try:
|
||||||
if user['status']:
|
conn = ldap.initialize("ldap://{0}:{1}".format(self.server, self.port), bytes_mode=False)
|
||||||
try:
|
conn.simple_bind_s(self.admin_dn, self.password)
|
||||||
self.con.simple_bind_s(user['info'], password)
|
search_filter = f'({self.rules}={username})'
|
||||||
return {'status': True, 'info': ''}
|
ldap_result_id = conn.search(self.base_dn, ldap.SCOPE_SUBTREE, search_filter, None)
|
||||||
except Exception as error:
|
result_type, result_data = conn.result(ldap_result_id, 0)
|
||||||
error = eval(str(error))
|
if result_type == ldap.RES_SEARCH_ENTRY:
|
||||||
return {'status': False, 'info': error['desc']}
|
conn.simple_bind_s(result_data[0][0], password)
|
||||||
else:
|
return True, None
|
||||||
return {'status': False, 'info': user['info']}
|
else:
|
||||||
|
return False, 'LDAP用户未找到'
|
||||||
|
except Exception as error:
|
||||||
|
return False, '%s' % error
|
||||||
|
|
Loading…
Reference in New Issue