From 3fb8f51455943a96703bbb10666d5dc672d7b4b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E5=9D=A1?= Date: Sun, 27 Oct 2019 18:24:13 +0800 Subject: [PATCH] =?UTF-8?q?A=20-=20=E5=A2=9E=E5=8A=A0=E6=94=AF=E6=8C=81LDA?= =?UTF-8?q?P=E7=94=A8=E6=88=B7=E7=99=BB=E5=BD=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spug_api/apps/account/models.py | 10 +++ spug_api/apps/account/user.py | 87 +++++++++++++------ spug_api/apps/assets/models.py | 10 ++- spug_api/apps/configuration/models.py | 6 ++ spug_api/apps/deploy/models.py | 12 +++ spug_api/apps/schedule/models.py | 6 ++ spug_api/apps/setting/models.py | 5 +- spug_api/apps/system/models.py | 5 +- spug_api/config.py.example | 18 +++- spug_api/libs/sql/permissions.sql | 5 +- spug_api/libs/sql/update.sql | 10 ++- spug_api/public.py | 14 ++- spug_api/requirements.txt | 1 + spug_web/src/components/Login.vue | 105 ++++++++++++++++------- spug_web/src/components/account/User.vue | 4 +- 15 files changed, 226 insertions(+), 72 deletions(-) diff --git a/spug_api/apps/account/models.py b/spug_api/apps/account/models.py index 3ff4f43..77b9d8c 100644 --- a/spug_api/apps/account/models.py +++ b/spug_api/apps/account/models.py @@ -16,6 +16,7 @@ class User(db.Model, ModelMixin): email = db.Column(db.String(120)) mobile = db.Column(db.String(30)) is_supper = db.Column(db.Boolean, default=False) + type = db.Column(db.String(20), default='系统用户') is_active = db.Column(db.Boolean, default=True) access_token = db.Column(db.String(32)) token_expired = db.Column(db.Integer) @@ -49,6 +50,9 @@ class User(db.Model, ModelMixin): def __repr__(self): return '' % self.username + class Meta: + ordering = ('-id',) + class Role(db.Model, ModelMixin): __tablename__ = 'account_roles' @@ -68,6 +72,9 @@ class Role(db.Model, ModelMixin): def __repr__(self): return '' % self.name + class Meta: + ordering = ('-id',) + class Permission(db.Model, ModelMixin): __tablename__ = 'account_permissions' @@ -79,6 +86,9 @@ class Permission(db.Model, ModelMixin): def __repr__(self): return '' % self.name + class Meta: + ordering = ('-id',) + class RolePermissionRel(db.Model, ModelMixin): __tablename__ = 'account_role_permission_rel' diff --git a/spug_api/apps/account/user.py b/spug_api/apps/account/user.py index ac42664..7cd6c23 100644 --- a/spug_api/apps/account/user.py +++ b/spug_api/apps/account/user.py @@ -6,6 +6,8 @@ from collections import defaultdict from datetime import datetime import uuid import time +from public import ldap + blueprint = Blueprint('account_page', __name__) login_limit = defaultdict(int) @@ -118,38 +120,67 @@ def get_self(): @blueprint.route('/login/', methods=['POST']) def login(): - form, error = JsonParser('username', 'password').parse() + form, error = JsonParser('username', 'password', 'type').parse() if error is None: - user = User.query.filter_by(username=form.username).first() - if user: - if user.is_active: - if user.verify_password(form.password): - login_limit.pop(form.username, None) - token = uuid.uuid4().hex - # token = user.access_token - user.access_token = token - user.token_expired = time.time() + 8 * 60 * 60 - user.save() - return json_response({ - 'token': token, - 'is_supper': user.is_supper, - 'nickname': user.nickname, - 'permissions': list(user.permissions) - }) + if form.type == 'ldap': + ldap_login = ldap.bind_user(form.username, form.password) + if ldap_login: + token = uuid.uuid4().hex + # user = User.query.filter_by(username=form.username).filter_by(type='LDAP').first() + user = User.query.filter_by(username=form.username).first() + if not user: + form.nickname = form.username + form.type = 'LDAP' + form.role_id = 1 + form.is_supper = False + is_supper = False + nickname = form.username + permissions = [] + User(**form).save() else: - login_limit[form.username] += 1 - if login_limit[form.username] >= 3: - user.update(is_active=False) - return json_response(message='用户名或密码错误,连续3次错误将会被禁用') + user.access_token = token + user.token_expired = time.time() + 80 * 60 * 6000 + is_supper = user.is_supper, + nickname = user.nickname, + permissions = list(user.permissions) + user.save() + + return json_response({ + 'token': token, + 'is_supper': is_supper, + 'nickname': nickname, + 'permissions': permissions + }) else: - return json_response(message='用户已被禁用,请联系管理员') - elif login_limit[form.username] >= 3: - return json_response(message='用户已被禁用,请联系管理员') + return json_response(message='用户名或密码错误,确认输入的是LDAP的账号密码?') else: - login_limit[form.username] += 1 - return json_response(message='用户名或密码错误,连续3次错误将会被禁用') - else: - return json_response(message='请输入用户名和密码') + user = User.query.filter_by(username=form.username).filter_by(type='系统用户').first() + if user: + if user.is_active: + if user.verify_password(form.password): + login_limit.pop(form.username, None) + token = uuid.uuid4().hex + user.access_token = token + user.token_expired = time.time() + 80 * 60 * 6000 + user.save() + return json_response({ + 'token': token, + 'is_supper': user.is_supper, + 'nickname': user.nickname, + 'permissions': list(user.permissions) + }) + else: + login_limit[form.username] += 1 + if login_limit[form.username] >= 3: + user.update(is_active=False) + return json_response(message='用户名或密码错误,连续3次错误将会被禁用') + else: + return json_response(message='用户已被禁用,请联系管理员') + elif login_limit[form.username] >= 3: + return json_response(message='用户已被禁用,请联系管理员') + else: + login_limit[form.username] += 1 + return json_response(message='用户名不存在,请确认用户名') @blueprint.route('/logout/') diff --git a/spug_api/apps/assets/models.py b/spug_api/apps/assets/models.py index 181507f..825dcd6 100644 --- a/spug_api/apps/assets/models.py +++ b/spug_api/apps/assets/models.py @@ -18,6 +18,8 @@ class Host(db.Model, ModelMixin): def __repr__(self): return '' % self.name + class Meta: + ordering = ('-id',) class HostExtend(db.Model, ModelMixin): __tablename__ = 'assets_hosts_extend' @@ -33,6 +35,9 @@ class HostExtend(db.Model, ModelMixin): hosts = db.relationship(Host, backref=db.backref('host')) + class Meta: + ordering = ('-id',) + class HostExecTemplate(db.Model, ModelMixin): __tablename__ = 'assets_hosts_exec_template' @@ -44,4 +49,7 @@ class HostExecTemplate(db.Model, ModelMixin): tpl_content = db.Column(db.Text()) def __repr__(self): - return '' % self.tpl_name \ No newline at end of file + return '' % self.tpl_name + + class Meta: + ordering = ('-id',) diff --git a/spug_api/apps/configuration/models.py b/spug_api/apps/configuration/models.py index d7c46cd..062ab37 100644 --- a/spug_api/apps/configuration/models.py +++ b/spug_api/apps/configuration/models.py @@ -14,6 +14,9 @@ class Environment(db.Model, ModelMixin): def __repr__(self): return '' % self.name + class Meta: + ordering = ('-id',) + class Service(db.Model, ModelMixin): __tablename__ = 'configuration_services' @@ -24,6 +27,9 @@ class Service(db.Model, ModelMixin): desc = db.Column(db.String(255)) group = db.Column(db.String(50)) + class Meta: + ordering = ('-id',) + class ConfigValue(db.Model, ModelMixin): __tablename__ = 'configuration_values' diff --git a/spug_api/apps/deploy/models.py b/spug_api/apps/deploy/models.py index ba7be50..d4f85b6 100644 --- a/spug_api/apps/deploy/models.py +++ b/spug_api/apps/deploy/models.py @@ -20,6 +20,9 @@ class Image(db.Model, ModelMixin): def __repr__(self): return '' % self.name + class Meta: + ordering = ('-id',) + class ImageConfig(db.Model, ModelMixin): __tablename__ = 'deploy_image_configs' @@ -63,6 +66,9 @@ class History(db.Model, ModelMixin): deploy_success = db.Column(db.Boolean) created = db.Column(db.String(20)) + class Meta: + ordering = ('-id',) + class App(db.Model, ModelMixin): __tablename__ = 'deploy_apps' @@ -84,6 +90,9 @@ class App(db.Model, ModelMixin): def __repr__(self): return '' % self.name + class Meta: + ordering = ('-id',) + class AppHostRel(db.Model, ModelMixin): __tablename__ = 'deploy_app_host_rel' @@ -123,6 +132,9 @@ class DeployMenu(db.Model, ModelMixin): def __repr__(self): return '' % self.name + class Meta: + ordering = ('-id',) + class AppMenuRel(db.Model, ModelMixin): __tablename__ = 'deploy_app_menu_rel' diff --git a/spug_api/apps/schedule/models.py b/spug_api/apps/schedule/models.py index 666c166..a1209f7 100644 --- a/spug_api/apps/schedule/models.py +++ b/spug_api/apps/schedule/models.py @@ -21,6 +21,9 @@ class Job(db.Model, ModelMixin): def __repr__(self): return '' % (self.name, self.trigger) + class Meta: + ordering = ('-id',) + class JobHistory(db.Model, ModelMixin): __tablename__ = 'schedule_jobs_history' @@ -48,3 +51,6 @@ class JobHistory(db.Model, ModelMixin): def __repr__(self): return '' % (self.id, self.job_id) + + class Meta: + ordering = ('-id',) diff --git a/spug_api/apps/setting/models.py b/spug_api/apps/setting/models.py index 9635f99..195327b 100644 --- a/spug_api/apps/setting/models.py +++ b/spug_api/apps/setting/models.py @@ -23,4 +23,7 @@ class NoticeWay(db.Model, ModelMixin): desc = db.Column(db.String(255)) def __repr__(self): - return '' % self.name \ No newline at end of file + return '' % self.name + + class Meta: + ordering = ('-id',) diff --git a/spug_api/apps/system/models.py b/spug_api/apps/system/models.py index 47ef613..7435280 100644 --- a/spug_api/apps/system/models.py +++ b/spug_api/apps/system/models.py @@ -11,4 +11,7 @@ class NotifyWay(db.Model, ModelMixin): desc = db.Column(db.String(255)) def __repr__(self): - return '' % self.name \ No newline at end of file + return '' % self.name + + class Meta: + ordering = ('-id',) diff --git a/spug_api/config.py.example b/spug_api/config.py.example index 25b516f..a7f4966 100644 --- a/spug_api/config.py.example +++ b/spug_api/config.py.example @@ -4,10 +4,20 @@ import os DEBUG = True TIME_ZONE = timezone('Asia/Shanghai') BASE_DIR = os.path.dirname(os.path.abspath(__file__)) -#SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:redhat@127.0.0.1/doms' -SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(BASE_DIR, 'test.db') +SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://spug:spugpwd@123.12.13.18:3306/spug' +# SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(BASE_DIR, 'test.db') SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_ECHO = False -DOCKER_REGISTRY_SERVER = 'localhost:5000' -DOCKER_REGISTRY_AUTH = {'username': 'user', 'password': 'password'} \ No newline at end of file +DOCKER_REGISTRY_SERVER = 'hub.qbangmang.com' +DOCKER_REGISTRY_AUTH = {'username': 'hubuser', 'password': 'hubpassword'} + +LDAP_CONFIG = { + 'host': '', + 'port': 389, + 'is_openldap': True, + 'base_dn': 'dc=spug,dc=com', + 'admin_dn': 'cn=admin,dc=spug,dc=com', + 'admin_password': 'spugpwd', + 'user_filter': 'cn', +} diff --git a/spug_api/libs/sql/permissions.sql b/spug_api/libs/sql/permissions.sql index e742e0c..e18a555 100644 --- a/spug_api/libs/sql/permissions.sql +++ b/spug_api/libs/sql/permissions.sql @@ -1,3 +1,6 @@ +-- system role +INSERT INTO account_roles (id, name, `desc`) VALUES (1, '系统默认角色', '系统默认角色'); + -- Dashboard INSERT INTO account_permissions (id, name, `desc`) VALUES (100, 'home_view', 'Dashboard'); @@ -118,4 +121,4 @@ INSERT INTO account_permissions (id, name, `desc`) VALUES (1206, 'publish_field_ INSERT INTO account_permissions (id, name, `desc`) VALUES (1301, 'system_notify_view', '系统通知列表'); INSERT INTO account_permissions (id, name, `desc`) VALUES (1302, 'system_notify_add', '添加通知设置'); INSERT INTO account_permissions (id, name, `desc`) VALUES (1303, 'system_notify_edit', '编辑通知设置'); -INSERT INTO account_permissions (id, name, `desc`) VALUES (1304, 'system_notify_del', '删除通知设置'); \ No newline at end of file +INSERT INTO account_permissions (id, name, `desc`) VALUES (1304, 'system_notify_del', '删除通知设置'); diff --git a/spug_api/libs/sql/update.sql b/spug_api/libs/sql/update.sql index bf0221b..fb4f7cd 100644 --- a/spug_api/libs/sql/update.sql +++ b/spug_api/libs/sql/update.sql @@ -17,4 +17,12 @@ INSERT INTO account_permissions (id, name, `desc`) VALUES (1302, 'system_notify_ INSERT INTO account_permissions (id, name, `desc`) VALUES (1303, 'system_notify_edit', '编辑通知设置'); INSERT INTO account_permissions (id, name, `desc`) VALUES (1304, 'system_notify_del', '删除通知设置'); --- end update 1.0.0 -- \ No newline at end of file +-- end update 1.0.0 -- + +-- start update 1.1.0 -- + +INSERT INTO account_roles (id, name, `desc`) VALUES (1, '系统默认角色', '系统默认角色'); + +ALTER TABLE `spug`.`account_users` ADD COLUMN `type` varchar(20) NULL DEFAULT '系统用户' AFTER `is_supper`; + +-- end update 1.0.1 -- diff --git a/spug_api/public.py b/spug_api/public.py index c4b3d9f..be6e7ba 100644 --- a/spug_api/public.py +++ b/spug_api/public.py @@ -1,8 +1,20 @@ from flask import Flask from flask_sqlalchemy import SQLAlchemy import config - +from flask_simpleldap import LDAP app = Flask(__name__) app.config.from_object(config) + +app.config['LDAP_BASE_DN'] = app.config['LDAP_CONFIG'].get('base_dn') +app.config['LDAP_USERNAME'] = app.config['LDAP_CONFIG'].get('admin_dn') +app.config['LDAP_PASSWORD'] = app.config['LDAP_CONFIG'].get('admin_password') +app.config['LDAP_OPENLDAP'] = app.config['LDAP_CONFIG'].get('is_openldap') +app.config['LDAP_USER_OBJECT_FILTER'] = '(&(objectclass=inetOrgPerson)({0}=%s))'\ + .format(app.config['LDAP_CONFIG'].get('user_filter')) +app.config['LDAP_HOST'] = app.config['LDAP_CONFIG'].get('host') +app.config['LDAP_PORT'] = app.config['LDAP_CONFIG'].get('port') + + db = SQLAlchemy(app) +ldap = LDAP(app) diff --git a/spug_api/requirements.txt b/spug_api/requirements.txt index dd58166..cfc6d04 100644 --- a/spug_api/requirements.txt +++ b/spug_api/requirements.txt @@ -41,3 +41,4 @@ tzlocal==1.5.1 urllib3==1.24.3 websocket-client==0.56.0 Werkzeug==0.16.0 +python-ldap==3.2.0 diff --git a/spug_web/src/components/Login.vue b/spug_web/src/components/Login.vue index 33a46b0..2533da3 100644 --- a/spug_web/src/components/Login.vue +++ b/spug_web/src/components/Login.vue @@ -1,31 +1,61 @@ \ No newline at end of file + diff --git a/spug_web/src/components/account/User.vue b/spug_web/src/components/account/User.vue index 3382211..75a4982 100644 --- a/spug_web/src/components/account/User.vue +++ b/spug_web/src/components/account/User.vue @@ -19,12 +19,12 @@ - + +