Esempio n. 1
0
class EmailTemplate(Model, SurrogatePK):
    """
    电子邮件模板

    :attr name: str(128) 电子邮件模板名称
    """

    __tablename__ = "email_templates"

    name = db.Column(db.String(length=128),
                     nullable=False,
                     unique=True,
                     doc="email_templates的名称")
    template = db.Column(db.Text, nullable=False, doc="模板")

    @classmethod
    def get_by_name(cls, name: str) -> EmailTemplate:
        """根据名称获取电子邮箱模板"""
        return cls.where(name=name).first_or_404()

    @classmethod
    def get_template(cls, name: str) -> str:
        """获取模板"""
        template = cls.get_by_name(name)
        return template.template

    def __repr__(self) -> str:
        return self.name
Esempio n. 2
0
class Permission(Model, SurrogatePK):
    """
    角色表

    :attr name: str(80) 权限名称
    :attr description: str(255) 权限描述
    :attr roles: Role 所有角色
    :attr users: User 所有用户
    """

    __tablename__ = "permissions"

    name = db.Column(db.String(80), unique=True, doc="权限名称", nullable=True)
    description = db.Column(db.String(255), doc="权限描述")

    @classmethod
    def get_by_name(cls, name: str) -> Model:
        return cls.query.filter_by(name=name).first()

    @classmethod
    def get_by_names(cls, *names: List[str]) -> Model:
        return cls.query.filter(cls.name.in_(names)).all()

    def __str__(self) -> str:
        return self.name
Esempio n. 3
0
class Log(Model, SurrogatePK):
    """
    日志

    :attr module: str(128) 请求模块
    :attr line: int 行
    :attr level 日志等级
    :attr message 日志消息
    """

    __tablename__ = "logs"

    module = db.Column(db.String(length=128), nullable=False, doc="请求模块")
    line = db.Column(db.Integer,
                     nullable=False,
                     doc="行",
                     info={"marshmallow": {
                         "dump_only": True
                     }})
    level = db.Column(db.String(length=20), nullable=False, doc="日志等级")
    message = db.Column(db.TEXT,
                        nullable=False,
                        doc="日志消息",
                        info={"marshmallow": {
                            "dump_only": True
                        }})
Esempio n. 4
0
class EmailTemplate(Model, SurrogatePK):
    """
    电子邮件模板

    :attr name: str(128) 电子邮件模板名称
    """

    __tablename__ = "email_templates"

    name = db.Column(
        db.String(length=128), nullable=False, unique=True, doc="email_templates的名称"
    )
    template = db.Column(db.Text, nullable=False, doc="模板")

    @classmethod
    def get_by_name(cls, name):
        return cls.query.filter_by(name=name).one()

    @classmethod
    def get_template(cls, name):
        """获取模板"""
        template = cls.get_by_name(name)
        return template.template

    def __repr__(self):
        return self.name
Esempio n. 5
0
class Role(Model, SurrogatePK):
    """
    角色表

    :attr name: str(80) 角色名称
    :attr description: str(255) 角色描述
    :attr permissions: Permission 所有权限
    :attr user_default: bool 用户默认角色
    :attr group_default: bool 组默认角色
    """

    __tablename__ = "roles"

    name = db.Column(db.String(80), unique=True, doc="角色名称", nullable=True)
    description = db.Column(db.String(255), doc="角色描述")
    user_default = db.Column(db.Boolean, doc="用户默认角色", default=False)
    group_default = db.Column(db.Boolean, doc="组默认角色", default=False)
    permissions = db.relationship(
        "Permission",
        secondary=permission_roles,
        doc="所有权限",
        primaryjoin="foreign(permission_roles.c.role_id) == Role.id",
        secondaryjoin=
        "foreign(permission_roles.c.permission_id) == Permission.id",
        backref=db.backref("roles", lazy="dynamic", doc="所有角色"),
        info={"marshmallow": {
            "column": ["id", "name"]
        }})

    @classmethod
    def get_by_name(cls, name: str) -> Model:
        return cls.query.filter_by(name=name).first()

    @classmethod
    def get_by_user_default(cls, is_admin=False) -> Model:
        if is_admin:
            return cls.query.filter_by(name=ROLES.SuperUser).all()
        return cls.query.filter_by(user_default=True).all()

    def add_permissions(self,
                        permissions: List[Permission]) -> List[Permission]:
        """
        获取权限

        兼容flask-security
        """
        for permission in permissions:
            if permission not in self.permissions:
                self.permissions.append(permission)
        return list(permission.name for permission in self.permissions)

    def __str__(self) -> str:
        return self.name
Esempio n. 6
0
class Group(Model, SurrogatePK, BaseNestedSets):
    """
    用户组

    :attr name: str(128) 用户组名称
    :attr description str(255) 组描述
    :attr default bool 是否为初始化默认组
    :attr roles 所有角色
    :attr users 所有用户
    """

    sqlalchemy_mptt_pk_name = "id_"
    __tablename__ = "groups"

    name = db.Column(db.String(length=128), nullable=False, doc="用户组名称")
    description = db.Column(db.String(255), doc="组描述")
    default = db.Column(db.Boolean, default=False, doc="初始化默认组")
    users = db.relationship(
        "User",
        secondary="groups_users",
        primaryjoin="Group.id_ == groups_users.c.group_id",
        secondaryjoin="User.id_ == groups_users.c.user_id",
        doc="组下用户",
        foreign_keys="[groups_users.c.group_id, groups_users.c.user_id]",
        active_history=True,
        lazy="joined",
        info={"marshmallow": {
            "column": ["id", "username"]
        }},
    )
    roles = db.relationship(
        "Role",
        uselist=True,
        secondary="groups_roles",
        primaryjoin="Group.id_ == groups_roles.c.group_id",
        secondaryjoin="Role.id_ == groups_roles.c.role_id",
        doc="组下默认角色",
        foreign_keys="[groups_roles.c.group_id, groups_roles.c.role_id]",
        active_history=True,
        lazy="joined",
        info={"marshmallow": {
            "column": ["id", "name"]
        }},
    )

    @classmethod
    def get_by_name(cls, name: str) -> Group:
        return cls.where(name=name).first_or_404()

    def __repr__(self) -> str:
        return self.name
Esempio n. 7
0
class Role(Model, SurrogatePK):
    """
    角色表

    :attr name: str(80) 角色名称
    :attr description: str(255) 角色描述
    :attr permissions: Permission 所有权限
    :attr user_default: bool 用户默认角色
    :attr group_default: bool 组默认角色
    """

    __tablename__ = "roles"

    name = db.Column(db.String(80), unique=True, doc="角色名称", nullable=False)
    description = db.Column(db.String(255), doc="角色描述")
    user_default = db.Column(db.Boolean, doc="用户默认角色", default=False)
    group_default = db.Column(db.Boolean, doc="组默认角色", default=False)
    permissions = db.relationship(
        "Permission",
        uselist=True,
        secondary=permission_roles,
        doc="所有权限",
        primaryjoin="foreign(permission_roles.c.role_id) == Role.id_",
        secondaryjoin=
        "foreign(permission_roles.c.permission_id) == Permission.id_",
        # backref=db.backref("roles", lazy="dynamic", doc="所有角色"),
    )

    @classmethod
    def get_by_name(cls, name: str) -> Role:
        return cls.where(name=name).first_or_404()

    @classmethod
    def get_by_user_default(cls, is_admin: bool = False) -> List[Role]:
        if is_admin:
            return cls.where(name__in=[ROLES.SuperUser, ROLES.User]).all()
        return cls.where(user_default=True).all()

    def add_permissions(self, permissions: List[Permission]) -> List[str]:
        """
        获取权限

        兼容flask-security
        """
        for permission in permissions:
            if permission not in self.permissions:
                assert isinstance(self.permissions, list)
                self.permissions.append(permission)
        return list(permission.name for permission in self.permissions)
Esempio n. 8
0
class Code(Model, SurrogatePK, BaseNestedSets):
    """
    编码

    :attr name: str(128) 编码名称
    """

    sqlalchemy_mptt_pk_name = "id_"

    __tablename__ = "codes"

    name = db.Column(db.String(length=128), nullable=False, doc="编码名称")
    type_code = db.Column(db.String(length=16), nullable=False, doc="类型码")

    def __repr__(self) -> str:
        return self.name
Esempio n. 9
0
class TokenBlackList(SurrogatePK, Model):
    """
    Token Black List Table

    :attr user_identity: str(50) 验证信息
    :attr jit: str(36) 36位jti信息
    :attr revoked: bool 是否撤销
    :attr token_type: str(10) token类型
    :attr expires: DateTime 过期时间
    """

    __tablename__ = "jwt_token_blacklist"

    user_identity = db.Column(db.String(50), nullable=False)
    jti = db.Column(db.String(36), unique=True, nullable=False)
    revoked = db.Column(db.Boolean, nullable=False)
    token_type = db.Column(db.String(10), nullable=False)
    expires = db.Column(db.DateTime(True), nullable=False)
Esempio n. 10
0
class Permission(Model, SurrogatePK):
    """
    角色表

    :attr name: str(80) 权限名称
    :attr description: str(255) 权限描述
    :attr roles: Role 所有角色
    :attr users: User 所有用户
    """

    __tablename__ = "permissions"

    name = db.Column(db.String(80), unique=True, doc="权限名称", nullable=False)
    description = db.Column(db.String(255), doc="权限描述")

    @classmethod
    def get_by_name(cls, name: str) -> Optional[Permission]:
        return cls.where(name=name).first()

    @classmethod
    def get_by_names(cls, *names: str) -> List[Permission]:
        return cls.where(name__in=names).all()
Esempio n. 11
0
class Project(Model, SurrogatePK):
    """
    项目

    Attribute:
        name (str): 项目名称,禁止非空,非值,最大长度128
    """

    __tablename__ = "projects"

    name = db.Column(db.String(length=128), nullable=False, doc="项目名称")

    def __repr__(self) -> str:
        return self.name
Esempio n. 12
0
class Menu(Model, SurrogatePK, BaseNestedSets):
    """
    菜单

    :attr name: str(128) 菜单名称
    """

    sqlalchemy_mptt_pk_name = "id_"
    __tablename__ = "menus"

    name = db.Column(db.String(length=128), nullable=False, doc="菜单名称")
    img = db.Column(db.String(512), doc="菜单图片")
    url = db.Column(db.String(512), doc="菜单URL")
    permission_id = db.Column(db.Integer)
    permission = db.relationship(
        "Permission",
        primaryjoin="Permission.id_ == Menu.permission_id",
        foreign_keys=permission_id,
        uselist=False,
    )

    def __repr__(self) -> str:
        return self.name
Esempio n. 13
0
class UserInfo(SurrogatePK, Model):
    """
    用户信息表

    :attr avator_id: int 用户头像ID
    :attr uid: int 用户ID
    :attr avator: Storages 用户头像
    :attr user: User 关联用户
    :attr sex: int 性别
    :attr age: int 年龄
    :attr first_name: str(80) 姓
    :attr second_name: str(80) 名
    """

    __tablename__ = "userinfo"

    avator_id = db.Column(
        db.Integer, doc="头像ID", info={"marshmallow": {"dump_only": True}}
    )
    uid = db.Column(db.Integer, doc="用户ID")
    sex = db.Column(db.Integer, doc="性别", default=1,)
    age = db.Column(db.Integer, doc="年龄",)
    first_name = db.Column(db.String(80), doc="姓",)
    last_name = db.Column(db.String(80), doc="名",)
    user = db.relationship(
        "User", doc="用户", primaryjoin="User.id_ == UserInfo.uid", foreign_keys=uid,
    )
    avator = db.relationship(
        Storages,
        primaryjoin="Storages.id_ == UserInfo.avator_id",
        foreign_keys=avator_id,
        doc="头像",
        lazy="joined",
    )

    def __repr__(self) -> str:
        return self.nickname

    @property
    def nickname(self) -> str:
        if self.first_name and self.last_name:
            return self.first_name + " " + self.last_name
        return self.user.username

    @property
    def sex_label(self) -> str:
        """性别标签"""
        labels = {1: "男", 2: "女"}
        try:
            return labels[self.sex]
        except KeyError:
            return "未填写"
Esempio n. 14
0
class Storages(StoragesMixin, Model, SurrogatePK):
    """
    文件管理表

    :param          name: str(256)                  文件名
    :param          filetype: str(256)              文件类型
    :param          storetype: str(256)             存储类型
    :param          saved: bool                     是否保存
    :param          path: str(2000)                 保存路径
    :param          uid: int                        用户ID
    :param          _store: FileStorage             文件
    """

    uid = db.Column(db.Integer, doc="用户ID")

    __trunk_size = 1000

    def __init__(self, **kwargs):
        self.store = kwargs.pop("store", None)
        db.Model.__init__(self, **kwargs)
Esempio n. 15
0
class Storages(Model, SurrogatePK, StoragesMixin):
    """
    文件管理表

    :attr name: str(256) 文件名
    :attr filetype: str(256) 文件类型
    :attr storetype: str(256) 存储类型
    :attr saved: bool 是否保存
    :attr path: str(2000) 保存路径
    :attr uid: int 用户ID
    :attr _store: FileStorage 文件
    """

    __tablename__ = "storages"

    uid = db.Column(db.Integer, doc="用户ID")

    def __init__(self, **kwargs: Any):
        self.store = kwargs.pop("store")
        super().__init__(**kwargs)
Esempio n. 16
0
class ResponseLog(Model, SurrogatePK):
    """
    请求日志

    :attr url: str(4096) url地址
    :attr arguments: json 请求数据
    :attr method: str(10) 请求方法
    :attr ip: str(128) IP地址
    :attr module: str(128) 模块名
    :attr status_code: int 状态码
    """

    __tablename__ = "response_logs"

    url = db.Column(db.String(4096), nullable=False, doc="请求url")
    arguments = db.Column(JSONType, doc="请求数据")
    method = db.Column(db.String(10), nullable=False, doc="请求方法")
    ip = db.Column(db.String(128), doc="IP地址")
    module = db.Column(db.String(128), doc="模块名")
    status_code = db.Column(db.Integer, doc="状态码")
Esempio n. 17
0
    smorest_sfs.modules.users.models
    ~~~~~~~~~~~~~~~~~~~~~~~~~

    用户的ORM模块
"""
from typing import List

from marshmallow.validate import OneOf, Range
from smorest_sfs.extensions.sqla import Model, SurrogatePK, db
from smorest_sfs.modules.auth.permissions import ROLES
from smorest_sfs.modules.roles.models import permission_roles
from sqlalchemy_utils.types import PasswordType

roles_users = db.Table(
    "roles_users",
    db.Column("user_id", db.Integer(), nullable=False),
    db.Column("role_id", db.Integer(), nullable=False),
)


user_permissions = db.join(
    roles_users, permission_roles, roles_users.c.role_id == permission_roles.c.role_id
)


class User(Model, SurrogatePK):
    """
    用户表

    :attr username: str(255) 用户名
    :attr email: str(255) 用户邮箱
Esempio n. 18
0
class User(Model, SurrogatePK):
    """
    用户表

    :attr username: str(255) 用户名
    :attr email: str(255) 用户邮箱
    :attr password: str(255) 用户密码
    :attr active: bool 是否启用
    :attr confirmed_at: DateTime 确认时间
    :attr roles: Role 角色
    :attr permissions: Permission 权限
    """

    __tablename__ = "users"

    username = db.Column(db.String(255), nullable=False, unique=True, doc="用户名")
    phonenum = db.Column(db.String(255), nullable=True, unique=True, doc="电话号码")
    email = db.Column(db.String(255), nullable=True, unique=True, doc="用户邮箱")
    password = db.Column(
        PasswordType(schemes=["pbkdf2_sha512"]), nullable=False, doc="用户密码"
    )
    active = db.Column(db.Boolean(), doc="启用", default=False)
    confirmed_at = db.Column(db.DateTime(), doc="确认时间")
    roles = db.relationship(
        "Role",
        secondary=roles_users,
        doc="所有角色",
        primaryjoin="foreign(roles_users.c.user_id) == User.id",
        secondaryjoin="foreign(roles_users.c.role_id) == Role.id",
        backref=db.backref("users", lazy="dynamic", doc="所有用户"),
        info={"marshmallow": {"column": ["id", "name"]}},
    )
    permissions = db.relationship(
        "Permission",
        secondary=user_permissions,
        doc="权限",
        primaryjoin="User.id == roles_users.c.user_id",
        secondaryjoin="Permission.id == permission_roles.c.permission_id",
        backref=db.backref("users", doc="用户", lazy="dynamic"),
        viewonly=True,
        info={"marshmallow": {"dump_only": True, "column": ["id", "name"]}},
    )

    @classmethod
    def get_by_keyword(cls, keyword: str) -> Model:
        """
        根据邮箱获取用户
        """
        return cls.query.filter(
            db.and_(
                cls.deleted.is_(False),
                db.or_(
                    cls.email == keyword,
                    cls.username == keyword,
                    cls.phonenum == keyword,
                ),
            )
        ).first()

    def __str__(self) -> str:  # pragma: no cover
        return self.email

    @property
    def nickname(self) -> str:
        if self.userinfo.first_name and self.userinfo.last_name:
            return self.userinfo.first_name + " " + self.userinfo.last_name
        return self.username
Esempio n. 19
0
class UserInfo(SurrogatePK, Model):
    """
    用户信息表

    :attr avator_id: int 用户头像ID
    :attr uid: int 用户ID
    :attr avator: Storages 用户头像
    :attr user: User 关联用户
    :attr sex: int 性别
    :attr age: int 年龄
    :attr first_name: str(80) 姓
    :attr second_name: str(80) 名
    """

    # from app.modules.storages.models import Storages

    __tablename__ = "userinfo"

    avator_id = db.Column(
        db.Integer, doc="头像ID", info={"marshmallow": {"dump_only": True}}
    )
    uid = db.Column(db.Integer, doc="用户ID", info={"marshmallow": {"dump_only": True}})
    avator = db.relationship(
        "Storages",
        primaryjoin="Storages.id == UserInfo.avator_id",
        foreign_keys=avator_id,
        doc="头像",
        lazy="joined",
        info={"marshmallow": {"dump_only": True}},
    )
    sex = db.Column(
        db.Integer,
        doc="性别",
        default=1,
        info={
            "marshmallow": {
                "validate": [OneOf([1, 2])],
                "allow_none": False,
                "required": True,
            }
        },
    )
    age = db.Column(
        db.Integer,
        doc="年龄",
        info={
            "marshmallow": {
                "allow_none": False,
                "validate": [Range(1, None)],
                "required": True,
            }
        },
    )
    first_name = db.Column(
        db.String(80),
        doc="姓",
        info={"marshmallow": {"allow_none": False, "required": True}},
    )
    last_name = db.Column(
        db.String(80),
        doc="名",
        info={"marshmallow": {"allow_none": False, "required": True}},
    )
    user = db.relationship(
        "User",
        doc="用户",
        primaryjoin="User.id == UserInfo.uid",
        foreign_keys=uid,
        backref=db.backref(
            "userinfo",
            uselist=False,
            lazy="joined",
            info={
                "marshmallow": {
                    "column": ["avator_id", "first_name", "last_name", "sex", "age"]
                }
            },
        ),
        info={"marshmallow": {"dump_only": True}},
    )

    def __str__(self) -> str:
        return self.user.username

    @property
    def sex_label(self) -> str:
        """性别标签"""
        labels = {1: "男", 2: "女"}
        try:
            return labels[self.sex]
        except KeyError:
            return "未填写"
Esempio n. 20
0
class User(Model, SurrogatePK):
    """
    用户表

    :attr username required: str(255) 用户名
    :attr email: str(255) 用户邮箱
    :attr password required: str(255) 用户密码
    :attr phonenum: str(255) 电话号码
    :attr active opt: bool 是否启用
    :attr confirmed_at: DateTime 确认时间
    :attr roles: Role 角色
    :attr permissions: Permission 权限
    :attr userinfo required: UserInfo 用户详情
    :attr groups: Group 用户组信息
    """

    __tablename__ = "users"

    username = db.Column(db.String(255), nullable=False, unique=True, doc="用户名")
    phonenum = db.Column(db.String(255), nullable=True, unique=True, doc="电话号码")
    email = db.Column(db.String(255), nullable=True, unique=True, doc="用户邮箱")
    password = db.Column(
        PasswordType(schemes=["pbkdf2_sha512"]), nullable=False, doc="用户密码"
    )
    active = db.Column(db.Boolean(), doc="启用", default=False)
    confirmed_at = db.Column(db.DateTime(), doc="确认时间")
    roles = db.relationship(
        "Role",
        secondary=roles_users,
        uselist=True,
        doc="所有角色",
        primaryjoin="foreign(roles_users.c.user_id) == User.id_",
        secondaryjoin="foreign(roles_users.c.role_id) == Role.id_",
        # backref=db.backref("users", lazy="dynamic", doc="所有用户"),
        order_by="Role.id_",
    )
    permissions = db.relationship(
        "Permission",
        secondary=user_permissions,
        doc="权限",
        primaryjoin="User.id_ == roles_users.c.user_id",
        secondaryjoin="Permission.id_ == permission_roles.c.permission_id",
        viewonly=True,
    )
    userinfo = db.relationship(
        "UserInfo",
        doc="用户",
        primaryjoin="User.id_ == UserInfo.uid",
        foreign_keys="UserInfo.uid",
        uselist=False,
        lazy="joined",
    )
    groups = db.relationship(
        Group,
        secondary=groups_users,
        uselist=True,
        primaryjoin="User.id_ == groups_users.c.user_id",
        secondaryjoin=Group.id_ == groups_users.c.group_id,
        doc="组下用户",
        foreign_keys=[groups_users.c.group_id, groups_users.c.user_id],
    )

    @classmethod
    def get_by_keyword(cls, keyword: str) -> User:
        """
        根据邮箱获取用户
        """
        return cls.query.filter(
            db.or_(
                cls.email == keyword, cls.username == keyword, cls.phonenum == keyword,
            ),
        ).first_or_404()

    def __repr__(self) -> str:  # pragma: no cover
        return self.nickname

    @property
    def nickname(self) -> str:
        if self.userinfo:
            return self.userinfo.nickname
        return self.username
Esempio n. 21
0
# -*- coding: utf-8 -*-
"""
    smorest_sfs.modules.roles.models
    ~~~~~~~~~~~~~~~~~~~~~~~~~

    角色权限的ORM模块
"""

from typing import List

from smorest_sfs.extensions.sqla import Model, SurrogatePK, db
from smorest_sfs.modules.auth.permissions import ROLES

permission_roles = db.Table(
    "permission_roles",
    db.Column("permission_id", db.Integer(), nullable=False),
    db.Column("role_id", db.Integer(), nullable=False),
)


class Permission(Model, SurrogatePK):
    """
    角色表

    :attr name: str(80) 权限名称
    :attr description: str(255) 权限描述
    :attr roles: Role 所有角色
    :attr users: User 所有用户
    """

    __tablename__ = "permissions"