update acl

This commit is contained in:
pycook 2019-11-15 16:54:56 +08:00
parent a8255d2b69
commit f1c2bcbd79
5 changed files with 57 additions and 11 deletions

View File

@ -17,6 +17,9 @@
- username: admin - username: admin
- password: admin - password: admin
> **重要提示**: `master` 分支在开发过程中可能处于 *不稳定的状态*
请通过[releases](https://github.com/pycook/cmdb/releases)获取
Overview Overview
---- ----
![基础资源视图](https://raw.githubusercontent.com/pycook/cmdb/master/ui/public/cmdb01.jpeg) ![基础资源视图](https://raw.githubusercontent.com/pycook/cmdb/master/ui/public/cmdb01.jpeg)

View File

@ -10,9 +10,9 @@ from api.lib.exception import CommitException
class FormatMixin(object): class FormatMixin(object):
def to_dict(self): def to_dict(self):
return dict([(k.name, return dict([(k.name, isinstance(getattr(self, k.name), datetime.datetime) and
getattr(self, k.name) if not isinstance(getattr(self, k.name), datetime.datetime) else getattr( getattr(self, k.name).strftime('%Y-%m-%d %H:%M:%S')) or
self, k.name).strftime('%Y-%m-%d %H:%M:%S')) for k in getattr(self, "__table__").columns]) getattr(self, k.name) for k in getattr(self, "__table__").columns])
@classmethod @classmethod
def get_columns(cls): def get_columns(cls):

View File

@ -1,7 +1,12 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*-
import uuid
import string
import random
from flask import abort from flask import abort
from flask import g
from api.extensions import db from api.extensions import db
from api.lib.perm.acl.cache import UserCache from api.lib.perm.acl.cache import UserCache
@ -20,12 +25,21 @@ class UserCRUD(object):
return numfound, query.offset((page - 1) * page_size).limit(page_size) return numfound, query.offset((page - 1) * page_size).limit(page_size)
@staticmethod @staticmethod
def add(**kwargs): def _gen_key_secret():
key = uuid.uuid4().hex
secret = ''.join(random.sample(string.ascii_letters + string.digits + '~!@#$%^&*?', 32))
return key, secret
@classmethod
def add(cls, **kwargs):
existed = User.get_by(username=kwargs['username'], email=kwargs['email']) existed = User.get_by(username=kwargs['username'], email=kwargs['email'])
existed and abort(400, "User <{0}> is already existed".format(kwargs['username'])) existed and abort(400, "User <{0}> is already existed".format(kwargs['username']))
kwargs['nickname'] = kwargs['username'] if not kwargs.get('nickname') else kwargs['nickname'] kwargs['nickname'] = kwargs.get('nickname') or kwargs['username']
kwargs['block'] = 0 kwargs['block'] = 0
kwargs['key'], kwargs['secret'] = cls._gen_key_secret()
return User.create(**kwargs) return User.create(**kwargs)
@staticmethod @staticmethod
@ -36,6 +50,13 @@ class UserCRUD(object):
return user.update(**kwargs) return user.update(**kwargs)
@classmethod
def reset_key_secret(cls):
key, secret = cls._gen_key_secret()
g.user.update(key=key, secret=secret)
return key, secret
@classmethod @classmethod
def delete(cls, uid): def delete(cls, uid):
user = User.get_by_id(uid) or abort(404, "User <{0}> does not exist".format(uid)) user = User.get_by_id(uid) or abort(404, "User <{0}> does not exist".format(uid))

View File

@ -11,6 +11,7 @@ from flask_sqlalchemy import BaseQuery
from api.extensions import db from api.extensions import db
from api.lib.database import CRUDModel from api.lib.database import CRUDModel
from api.lib.database import Model from api.lib.database import Model
from api.lib.database import SoftDeleteMixin
class App(Model): class App(Model):
@ -34,6 +35,7 @@ class UserQuery(BaseQuery):
authenticated = user.check_password(password) authenticated = user.check_password(password)
else: else:
authenticated = False authenticated = False
return user, authenticated return user, authenticated
def authenticate_with_key(self, key, secret, args, path): def authenticate_with_key(self, key, secret, args, path):
@ -45,6 +47,7 @@ class UserQuery(BaseQuery):
authenticated = True authenticated = True
else: else:
authenticated = False authenticated = False
return user, authenticated return user, authenticated
def search(self, key): def search(self, key):
@ -55,18 +58,21 @@ class UserQuery(BaseQuery):
def get_by_username(self, username): def get_by_username(self, username):
user = self.filter(User.username == username).first() user = self.filter(User.username == username).first()
return user return user
def get_by_nickname(self, nickname): def get_by_nickname(self, nickname):
user = self.filter(User.nickname == nickname).first() user = self.filter(User.nickname == nickname).first()
return user return user
def get(self, uid): def get(self, uid):
user = self.filter(User.uid == uid).first() user = self.filter(User.uid == uid).first()
return copy.deepcopy(user) return copy.deepcopy(user)
class User(CRUDModel): class User(CRUDModel, SoftDeleteMixin):
__tablename__ = 'users' __tablename__ = 'users'
__bind_key__ = "user" __bind_key__ = "user"
query_class = UserQuery query_class = UserQuery
@ -107,9 +113,7 @@ class User(CRUDModel):
def _set_password(self, password): def _set_password(self, password):
self._password = hashlib.md5(password.encode('utf-8')).hexdigest() self._password = hashlib.md5(password.encode('utf-8')).hexdigest()
password = db.synonym("_password", password = db.synonym("_password", descriptor=property(_get_password, _set_password))
descriptor=property(_get_password,
_set_password))
def check_password(self, password): def check_password(self, password):
if self.password is None: if self.password is None:

View File

@ -6,8 +6,8 @@ from flask import session
from flask_login import current_user from flask_login import current_user
from api.lib.decorator import args_required from api.lib.decorator import args_required
from api.lib.perm.acl.user import UserCRUD
from api.lib.perm.acl.role import RoleRelationCRUD from api.lib.perm.acl.role import RoleRelationCRUD
from api.lib.perm.acl.user import UserCRUD
from api.lib.utils import get_page from api.lib.utils import get_page
from api.lib.utils import get_page_size from api.lib.utils import get_page_size
from api.resource import APIView from api.resource import APIView
@ -36,11 +36,17 @@ class UserView(APIView):
id2parents = RoleRelationCRUD.get_parents(uids=[i.uid for i in users]) id2parents = RoleRelationCRUD.get_parents(uids=[i.uid for i in users])
users = [i.to_dict() for i in users]
for u in users:
u.pop('password', None)
u.pop('key', None)
u.pop('secret', None)
return self.jsonify(numfound=numfound, return self.jsonify(numfound=numfound,
page=page, page=page,
page_size=page_size, page_size=page_size,
id2parents=id2parents, id2parents=id2parents,
users=[i.to_dict() for i in users]) users=users)
@args_required('username') @args_required('username')
@args_required('email') @args_required('email')
@ -58,3 +64,15 @@ class UserView(APIView):
UserCRUD.delete(uid) UserCRUD.delete(uid)
return self.jsonify(uid=uid) return self.jsonify(uid=uid)
class UserResetKeySecretView(APIView):
url_prefix = "/users/reset_key_secret"
def post(self):
key, secret = UserCRUD.reset_key_secret()
return self.jsonify(key=key, secret=secret)
def put(self):
return self.post()