123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885 |
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # @Author: wushuiyong
- # @Created Time : 日 1/ 1 23:43:12 2017
- # @Description:
- from flask_login import UserMixin
- from sqlalchemy import String, Integer, DateTime, or_
- from werkzeug.security import check_password_hash, generate_password_hash
- # from flask_cache import Cache
- from datetime import datetime
- from walle.service.extensions import login_manager
- from walle.model.database import SurrogatePK, db, Model
- from walle.model.tag import TagModel
- from sqlalchemy.orm import aliased
- from walle.service.rbac.access import Access as AccessRbac
- from flask import current_app, session, abort
- from walle.service.rbac.role import *
- from walle.service.error import WalleError
- from flask_login import current_user as g
- from walle.service.extensions import permission
- import walle.model
- class UserModel(UserMixin, SurrogatePK, Model):
- # 表的名字:
- __tablename__ = 'users'
- status_active = 1
- status_blocked = 2
- current_time = datetime.now()
- password_hash = 'sadfsfkk'
- # 表的结构:
- id = db.Column(Integer, primary_key=True, autoincrement=True)
- username = db.Column(String(50))
- is_email_verified = db.Column(Integer, default=0)
- email = db.Column(String(50), unique=True, nullable=False)
- password = db.Column(String(50), nullable=False)
- avatar = db.Column(String(100))
- role = db.Column(String(10))
- status = db.Column(Integer, default=1)
- last_space = db.Column(Integer, default=0)
- # role_info = relationship("walle.model.user.RoleModel", back_populates="users")
- created_at = db.Column(DateTime, default=current_time)
- updated_at = db.Column(DateTime, default=current_time, onupdate=current_time)
- status_mapping = {
- -1: '删除',
- 0: '新建',
- 1: '正常',
- 2: '冻结',
- }
- '''
- current_user 基础方法
- "__abstract__",
- "__class__",
- "__delattr__",
- "__dict__",
- "__doc__",
- "__eq__",
- "__format__",
- "__getattribute__",
- "__hash__",
- "__init__",
- "__mapper__",
- "__module__",
- "__ne__",
- "__new__",
- "__reduce__",
- "__reduce_ex__",
- "__repr__",
- "__setattr__",
- "__sizeof__",
- "__str__",
- "__subclasshook__",
- "__table__",
- "__table_args__",
- "__tablename__",
- "__weakref__",
- "_cached_tablename",
- "_decl_class_registry",
- "_sa_class_manager",
- "_sa_instance_state",
- "avatar",
- "avatar_url",
- "block_active",
- "column_name_set",
- "create",
- "create_from_dict",
- "create_or_update",
- "created_at",
- "current_time",
- "delete",
- "dump_schema",
- "email",
- "enable",
- "fetch_access_list_by_role_id",
- "fetch_by_uid",
- "general_password",
- "get_by_id",
- "get_common_fields",
- "get_id",
- "id",
- "is_active",
- "is_anonymous",
- "is_authenticated",
- "is_email_verified",
- "item",
- "list",
- "metadata",
- "password",
- "password_hash",
- "query",
- "query_class",
- "query_paginate",
- "query_paginate_and_dump_schema",
- "remove",
- "save",
- "set_password",
- "status",
- "status_active",
- "status_available",
- "status_blocked",
- "status_default",
- "status_mapping",
- "status_remove",
- "to_dict",
- "to_json",
- "uid2name",
- "update",
- "update_avatar",
- "update_name_pwd",
- "updated_at",
- "username",
- "verify_password"
- '''
- def add(self, *args, **kwargs):
- data = dict(*args)
- user = UserModel(**data)
- db.session.add(user)
- db.session.commit()
- return user
- def item(self, user_id=None):
- """
- 获取单条记录
- :param role_id:
- :return:
- """
- data = self.query.filter_by(id=self.id).filter(UserModel.status.notin_([self.status_remove])).first()
- return data.to_json() if data else []
- def update(self, *args, **kwargs):
- # todo permission_ids need to be formated and checked
- # a new type to update a model
- update_data = dict(*args)
- return super(UserModel, self).update(**update_data)
- def update_avatar(self, avatar):
- d = {'avatar': avatar}
- user = self.query.get(self.id).update(**d)
- current_app.logger.info(user)
- def update_name_pwd(self, username, password=None):
- # todo permission_ids need to be formated and checked
- user = self.query.filter_by(id=self.id).first()
- user.username = username
- if password:
- self.set_password(password)
- db.session.commit()
- return user.to_json()
- def block_active(self, status):
- user = self.query.filter_by(id=self.id).first()
- user.status = status
- db.session.commit()
- return user.to_json()
- def remove(self):
- """
- :param role_id:
- :return:
- """
- self.query.filter_by(id=self.id).update({'status': self.status_remove})
- ret = db.session.commit()
- return ret
- def verify_password(self, password):
- """
- 检查密码是否正确
- :param password:
- :return:
- """
- if self.password is None:
- return False
- return check_password_hash(self.password, password)
- def set_password(self, password):
- """Set password."""
- self.password = generate_password_hash(password)
- def general_password(self, password):
- """
- 检查密码是否正确
- :param password:
- :return:
- """
- self.password = generate_password_hash(password)
- return generate_password_hash(password)
- def fetch_access_list_by_role_id(self, role_id):
- module = aliased(MenuModel)
- controller = aliased(MenuModel)
- action = aliased(MenuModel)
- role = RoleModel.query.get(role_id)
- access_ids = role.access_ids.split(',')
- data = db.session \
- .query(controller.name_en, controller.name_cn,
- action.name_en, action.name_cn) \
- .outerjoin(action, action.pid == controller.id) \
- .filter(module.type == MenuModel.type_module) \
- .filter(controller.id.in_(access_ids)) \
- .filter(action.id.in_(access_ids)) \
- .all()
- return [AccessRbac.resource(a_en, c_en) for c_en, c_cn, a_en, a_cn in data if c_en and a_en]
- def is_authenticated(self):
- return True
- def is_active(self):
- return True
- def is_anonymous(self):
- return False
- def get_id(self):
- try:
- return unicode(self.id) # python 2
- except NameError:
- return str(self.id) # python 3
- def list(self, uids=[], page=0, size=10, kw=None):
- """
- 获取分页列表
- :param page:
- :param size:
- :return:
- """
- query = UserModel.query.filter(UserModel.status.notin_([self.status_remove]))
- if kw:
- query = query.filter(or_(UserModel.username.like('%' + kw + '%'), UserModel.email.like('%' + kw + '%')))
- if uids:
- query = query.filter(UserModel.id.in_(uids))
- count = query.count()
- data = query.order_by('id desc').offset(int(size) * int(page)).limit(size).all()
- user_list = [p.to_json() for p in data]
- return user_list, count
- def has_spaces(self):
- return MemberModel().spaces(user_id=self.id)
- @classmethod
- def fresh_session(cls):
- spaces = current_user.has_spaces()
- # 1.无空间权限
- if not spaces:
- raise WalleError(Code.space_empty)
- default_space = spaces.keys()[0]
- # 2.第一次登录无空间
- if not current_user.last_space:
- current_user.last_space = default_space
- current_user.save()
- session['space_id'] = default_space
- session['space_info'] = spaces[session['space_id']]
- # 3.空间权限有修改
- if current_user.last_space and current_user.last_space not in spaces.keys():
- raise WalleError(Code.space_error)
- session['space_id'] = current_user.last_space
- session['space_info'] = spaces[current_user.last_space]
- session['space_list'] = spaces.values()
- current_app.logger.info('============ SecurityResource.__init__ ============')
- @classmethod
- def avatar_url(cls, avatar):
- avatar = avatar if avatar else 'default.jpg'
- return '/' + current_app.config['AVATAR_PATH'] + avatar
- @classmethod
- def fetch_by_uid(cls, uids=None):
- """
- 用户列表
- :param uids: []
- :return:
- """
- if not uids:
- return []
- query = UserModel.query.filter(UserModel.id.in_(uids)).filter(UserModel.status.notin_([cls.status_remove]))
- data = query.order_by('id desc').all()
- return [p.to_json() for p in data]
- @classmethod
- def uid2name(cls, data):
- """
- 把uid转换成名字
- :param data: [{'user_id':1, 'xx':'yy'}] 至少包含user_id
- :return:
- """
- user_ids = []
- uid2name = {}
- for items in data:
- user_ids.append(items.user_id)
- user_info = cls.fetch_by_uid(uids=user_ids)
- for user in user_info:
- uid2name[user['id']] = user['username']
- return uid2name
- def to_json(self):
- item = {
- 'id': int(self.id),
- 'user_id': int(self.id),
- 'username': self.username,
- 'is_email_verified': self.is_email_verified,
- 'email': self.email,
- 'avatar': self.avatar_url(self.avatar),
- # TODO 当前登录用户的空间
- # 'role_id': self.role_id,
- 'status': self.status_mapping[self.status],
- 'last_space': self.last_space,
- # 'status': self.status,
- # 'role_name': self.role_id,
- 'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S'),
- 'updated_at': self.updated_at.strftime('%Y-%m-%d %H:%M:%S'),
- }
- item.update(self.enable())
- return item
- def enable(self):
- return {
- 'enable_update': permission.enable_role(DEVELOPER),
- 'enable_delete': permission.enable_role(DEVELOPER),
- 'enable_create': False,
- 'enable_online': False,
- 'enable_audit': False,
- 'enable_block': False,
- }
- class MenuModel(SurrogatePK, Model):
- __tablename__ = 'menus'
- type_module = 'module'
- type_controller = 'controller'
- type_action = 'action'
- status_open = 1
- status_close = 2
- current_time = datetime.now()
- # 表的结构:
- id = db.Column(Integer, primary_key=True, autoincrement=True)
- name_cn = db.Column(String(30))
- name_en = db.Column(String(30))
- pid = db.Column(Integer)
- type = db.Column(String(30))
- sequence = db.Column(Integer)
- archive = db.Column(Integer)
- icon = db.Column(String(30))
- url = db.Column(String(30))
- visible = db.Column(Integer)
- role = db.Column(Integer)
- created_at = db.Column(DateTime, default=current_time)
- updated_at = db.Column(DateTime, default=current_time, onupdate=current_time)
- def menu(self, role):
- data = {}
- filters = {
- MenuModel.visible == 1,
- MenuModel.role >= role
- }
- query = self.query \
- .filter(*filters) \
- .order_by('sequence asc') \
- .all()
- for item in query:
- if item.type == self.type_module:
- module = {
- 'title': item.name_cn,
- 'icon': item.icon,
- 'sub_menu': [],
- }
- if item.url:
- module['url'] = RoleModel.menu_url(item.url)
- data[item.id] = module
- elif item.type == self.type_controller:
- data[item.pid]['sub_menu'].append({
- 'title': item.name_cn,
- 'icon': item.icon,
- 'url': RoleModel.menu_url(item.url),
- })
- return data.values()
- def list(self):
- """
- 获取分页列表
- :param page:
- :param size:
- :param kw:
- :return:
- """
- menus_module = {}
- menus_controller = {}
- module = aliased(MenuModel)
- controller = aliased(MenuModel)
- action = aliased(MenuModel)
- data = db.session.query(module.id, module.name_cn, controller.id, controller.name_cn, action.id, action.name_cn) \
- .outerjoin(controller, controller.pid == module.id) \
- .outerjoin(action, action.pid == controller.id) \
- .filter(module.type == self.type_module) \
- .all()
- for m_id, m_name, c_id, c_name, a_id, a_name in data:
- # module
- if not menus_module.has_key(m_id):
- menus_module[m_id] = {
- 'id': m_id,
- 'title': m_name,
- 'sub_menu': {},
- }
- # controller
- if not menus_module[m_id]['sub_menu'].has_key(c_id) and c_name:
- menus_module[m_id]['sub_menu'][c_id] = {
- 'id': c_id,
- 'title': c_name,
- 'sub_menu': {},
- }
- # action
- if not menus_controller.has_key(c_id):
- menus_controller[c_id] = []
- if a_name:
- menus_controller[c_id].append({
- 'id': a_id,
- 'title': a_name,
- })
- menus = []
- for m_id, m_info in menus_module.items():
- for c_id, c_info in m_info['sub_menu'].items():
- m_info['sub_menu'][c_id]['sub_menu'] = menus_controller[c_id]
- menus.append({
- 'id': m_id,
- 'title': m_info['title'],
- 'sub_menu': m_info['sub_menu'].values(),
- })
- return menus
- def to_json(self):
- return {
- 'id': self.id,
- 'name_cn': self.name_cn,
- 'name_en': self.name_en,
- 'pid': self.pid,
- 'type': self.type,
- 'sequence': self.sequence,
- 'archive': self.archive,
- 'icon': self.icon,
- 'url': self.url,
- 'visible': self.visible,
- 'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S'),
- 'updated_at': self.updated_at.strftime('%Y-%m-%d %H:%M:%S'),
- }
- class RoleModel(object):
- _role_super = 'SUPER'
- _role_owner = 'OWNER'
- _role_master = 'MASTER'
- _role_developer = 'DEVELOPER'
- _role_reporter = 'REPORTER'
- @classmethod
- def list(cls):
- roles = [
- {'id': cls._role_super, 'name': '超级管理员'},
- {'id': cls._role_owner, 'name': '空间所有者'},
- {'id': cls._role_master, 'name': '项目管理员'},
- {'id': cls._role_developer, 'name': '开发者'},
- {'id': cls._role_reporter, 'name': '访客'},
- ]
- return roles, len(roles)
- @classmethod
- def item(cls, role_id):
- return None
- @classmethod
- def menu_url(cls, url):
- if url == '/':
- return url
- prefix = 'admin' if g.role == SUPER else session['space_info']['name']
- return '/' + prefix + url
- # 项目配置表
- class MemberModel(SurrogatePK, Model):
- __tablename__ = 'members'
- current_time = datetime.now()
- group_id = None
- project_id = None
- source_type_project = 'project'
- source_type_group = 'group'
- # 表的结构:
- id = db.Column(Integer, primary_key=True, autoincrement=True)
- user_id = db.Column(Integer, db.ForeignKey('users.id'))
- source_id = db.Column(Integer)
- source_type = db.Column(String(10))
- access_level = db.Column(String(10))
- status = db.Column(Integer)
- created_at = db.Column(DateTime, default=current_time)
- updated_at = db.Column(DateTime, default=current_time, onupdate=current_time)
- group_name = None
- # TODO group id全局化
- def spaces(self, user_id=None):
- """
- 获取分页列表
- :param page:
- :param size:
- :return:
- """
- filters = {
- MemberModel.status.notin_([self.status_remove]),
- MemberModel.source_type == self.source_type_group
- }
- query = self.query.filter(*filters).with_labels().with_entities(MemberModel.source_id, MemberModel.access_level, SpaceModel.name)
- if user_id:
- query = query.filter_by(user_id=user_id)
- query = query.join(SpaceModel, SpaceModel.id==MemberModel.source_id)
- spaces = query.all()
- current_app.logger.info(spaces)
- return {space[0]: {'id': space[0], 'role': space[1], 'name': space[2]} for space in spaces}
- def projects(self, user_id=None, space_id=None):
- """
- 获取分页列表
- :param page:
- :param size:
- :return:
- """
- filters = {
- MemberModel.status.notin_([self.status_remove]),
- MemberModel.source_type == self.source_type_project
- }
- query = self.query.filter(*filters)
- if user_id:
- query = query.filter_by(user_id=user_id)
- # if project_id:
- # query = query.filter_by(source_id=project_id)
- projects = query.all()
- current_app.logger.info(projects)
- return projects
- group, count = MemberModel.query_paginate(page=page, limit=size, filter_name_dict=filters)
- list = [p.to_json() for p in group]
- return list, count
- def add(self, space_name, members):
- """
- :param space_name:
- :param members: [{'user_id': 1, 'project_id': 2}]
- :return:
- """
- tag = TagModel(name=space_name, label='user_group')
- db.session.add(tag)
- db.session.commit()
- for member in members:
- user_group = MemberModel(group_id=tag.id, user_id=member['user_id'], project_id=member['project_id'])
- db.session.add(user_group)
- db.session.commit()
- if tag.id:
- self.group_id = tag.id
- return tag.id
- def update_group(self, members, group_name=None):
- # 修复空间名称
- if group_name:
- SpaceModel(id=self.group_id).update({'name': group_name})
- # # 修改tag信息
- # if group_name:
- # tag_model = TagModel.query.filter_by(label='user_group').filter_by(id=self.group_id).first()
- # if tag_model.name != group_name:
- # tag_model.name = group_name
- # 修改用户组成员
- # clean up
- filters = {
- MemberModel.source_id == self.group_id,
- MemberModel.source_type == self.source_type_group,
- }
- MemberModel.query.filter(*filters).delete()
- # insert all
- for member in members:
- update = {
- 'user_id': member['user_id'],
- 'source_id': self.group_id,
- 'source_type': self.source_type_group,
- 'access_level': member['role'].upper(),
- 'status': self.status_available,
- }
- m = MemberModel(**update)
- db.session.add(m)
- ret = db.session.commit()
- return ret
- def update_project(self, project_id, members, group_name=None):
- space_info = walle.model.deploy.ProjectModel.query.filter_by(id=project_id).first().to_json()
- group_model = self.members(group_id=space_info['space_id'])
- user_update = []
- for member in members:
- user_update.append(member['user_id'])
- # project新增用户是否在space's group中,无则抛出
- if list(set(user_update).difference(set(group_model['user_ids']))):
- raise ValueError('用户不存在')
- # 修改用户组成员
- # clean up
- filters = {
- MemberModel.source_id == project_id,
- MemberModel.source_type == self.source_type_project,
- }
- MemberModel.query.filter(*filters).delete()
- # insert all
- for member in members:
- insert = {
- 'user_id': member['user_id'],
- 'source_id': project_id,
- 'source_type': self.source_type_project,
- 'access_level': member['role'].upper(),
- 'status': self.status_available,
- }
- group = MemberModel(**insert)
- db.session.add(group)
- ret = db.session.commit()
- return ret
- def members(self, group_id=None, project_id=None):
- """
- 获取单条记录
- :param role_id:
- :return:
- """
- group_id = group_id if group_id else self.group_id
- project_id = project_id if project_id else self.project_id
- source_id = group_id if group_id else project_id
- source_type = self.source_type_group if group_id else self.source_type_project
- filters = {
- 'status': {'nin': [self.status_remove]},
- 'source_id': {'=': source_id},
- 'source_type': {'=': source_type},
- }
- # TODO
- page = 1
- size = 10
- groups, count = MemberModel.query_paginate(page=page, limit=size, filter_name_dict=filters)
- user_ids = []
- user_role = members = {}
- current_app.logger.info(groups)
- for group_info in groups:
- user_ids.append(group_info.user_id)
- # TODO
- user_role[group_info.user_id] = group_info.access_level
- current_app.logger.info(user_ids)
- user_model = UserModel()
- user_info = user_model.fetch_by_uid(uids=set(user_ids))
- if user_info:
- for user in user_info:
- if user_role.has_key(user['id']):
- user['role'] = user_role[user['id']]
- members['user_ids'] = user_ids
- members['members'] = user_info
- members['users'] = len(user_ids)
- return members
- def remove(self, group_id=None, user_id=None, project_id=None):
- """
- :param role_id:
- :return:
- """
- if group_id:
- MemberModel.query.filter_by(group_id=group_id).update({'status': self.status_remove})
- elif user_id:
- MemberModel.query.filter_by(user_id=user_id).update({'status': self.status_remove})
- elif self.group_id:
- MemberModel.query.filter_by(group_id=self.group_id).update({'status': self.status_remove})
- elif project_id:
- MemberModel.query.filter_by(project_id=project_id).update({'status': self.status_remove})
- ret = db.session.commit()
- return ret
- def to_json(self):
- return {
- 'id': self.id,
- 'user_id': self.user_id,
- 'group_id': self.group_id,
- 'group_name': self.group_name,
- 'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S'),
- 'updated_at': self.updated_at.strftime('%Y-%m-%d %H:%M:%S'),
- }
- # 项目配置表
- class SpaceModel(SurrogatePK, Model):
- # 表的名字:
- __tablename__ = 'spaces'
- current_time = datetime.now()
- status_close = 0
- status_open = 1
- # 表的结构:
- id = db.Column(Integer, primary_key=True, autoincrement=True)
- user_id = db.Column(Integer)
- name = db.Column(String(100))
- status = db.Column(Integer)
- created_at = db.Column(DateTime, default=current_time)
- updated_at = db.Column(DateTime, default=current_time, onupdate=current_time)
- def list(self, page=0, size=10, kw=None):
- """
- 获取分页列表
- :param page:
- :param size:
- :return:
- """
- query = self.query.filter(SpaceModel.status.notin_([self.status_remove]))
- if kw:
- query = query.filter(SpaceModel.name.like('%' + kw + '%'))
- # TODO 如果是超管,可以全量,否则需要过滤自己有权限的空间列表
- if g.role <> SUPER:
- query = query.filter_by(user_id=g.id)
- count = query.count()
- data = query.order_by('id desc').offset(int(size) * int(page)).limit(size).all()
- uid2name = UserModel.uid2name(data=data)
- list = [p.to_json(uid2name) for p in data]
- return list, count
- def item(self, id=None):
- """
- 获取单条记录
- :param role_id:
- :return:
- """
- id = id if id else self.id
- data = self.query.filter_by(id=id).first()
- members = MemberModel(group_id=id).members()
- if not data:
- return []
- data = data.to_json()
- return dict(data, **members)
- def add(self, *args, **kwargs):
- # todo permission_ids need to be formated and checked
- data = dict(*args)
- # tag = TagModel(name=data['name'], label='user_group')
- # db.session.add(tag)
- # db.session.commit()
- data = dict(*args)
- space = SpaceModel(**data)
- db.session.add(space)
- db.session.commit()
- self.id = space.id
- return self.id
- def update(self, *args, **kwargs):
- # todo permission_ids need to be formated and checked
- # a new type to update a model
- update_data = dict(*args)
- return super(SpaceModel, self).update(**update_data)
- def remove(self, space_id=None):
- """
- :param space_id:
- :return:
- """
- space_id = space_id if space_id else self.id
- SpaceModel.query.filter_by(id=space_id).update({'status': self.status_remove})
- ret = db.session.commit()
- return ret
- def to_json(self, uid2name=None):
- item = {
- 'id': self.id,
- 'user_id': self.user_id,
- 'user_name': uid2name[self.user_id] if uid2name and uid2name.has_key(self.user_id) else '',
- # TODO
- 'group_id': 'self.group_id',
- 'name': self.name,
- 'status': self.status,
- 'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S'),
- 'updated_at': self.updated_at.strftime('%Y-%m-%d %H:%M:%S'),
- }
- item.update(self.enable())
- return item
- def enable(self):
- return {
- 'enable_update': permission.enable_uid(self.user_id) or permission.enable_role(OWNER),
- 'enable_delete': permission.enable_uid(self.user_id) or permission.enable_role(OWNER),
- 'enable_create': False,
- 'enable_online': False,
- 'enable_audit': False,
- 'enable_block': permission.enable_role(MASTER),
- }
|