Beispiel #1
0
class BaseModel(db.Model):
    """模型抽象基础类
    通过设置__abstract__属性,成为SQLAlchemy 抽象基类, 不再映射到数据库中
    """
    __abstract__ = True

    updated_at = db.Column(db.DateTime, default=datetime.utcnow)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

    def __repr__(self):
        try:
            identifier = self.name
        except AttributeError:
            identifier = self.id
        return "<{} {}>".format(self.__class__.__name__,
                                identifier)  # 结果形如<类名 name>

    def save(self):
        """保存到数据库中
        """
        db.session.add(self)
        db.session.commit()

    def delete(self):
        """从数据库中删除
        """
        db.session.delete(self)
        db.session.commit()
Beispiel #2
0
class Server(BaseModel):
    """Redis服务器模型
    """

    __tablename__ = 'redis_server'

    id = db.Column(db.Integer, primary_key=True)
    # unique = True 设置不能有同名的服务器
    name = db.Column(db.String(64), unique=True)
    description = db.Column(db.String(512))
    host = db.Column(db.String(15))
    port = db.Column(db.Integer, default=6379)
    password = db.Column(db.String())

    @property
    def redis(self):
        return StrictRedis(host=self.host,
                           port=self.port,
                           password=self.password)

    def ping(self):
        """检查 Redis 服务器是否可以访问
        """
        try:
            return self.redis.ping()
        except RedisError:
            raise RedisConnectError(
                400, 'redis server %s can not connected' % self.host)

    @property
    def status(self):
        """服务器当前状态
        """
        status = 'error'
        try:
            if self.ping():
                status = 'ok'
        except RedisConnectError:
            pass
        return status

    def get_metrics(self):
        """获取 Redis 服务器监控信息

        通过 Redis 服务器指令 INFO 返回监控信息, 参考 https://redis.io/commands/INFO
        """
        try:
            # TODO 新版本的 Redis 服务器支持查看某一 setion 的信息,不必返回所有信息
            return self.redis.info()
        except RedisError:
            raise RedisConnectError(
                400, 'redis server %s can not connected' % self.host)
Beispiel #3
0
class Server(BaseModel):
    """Redis服务器模型
    """

    __tablename__ = 'redis_server'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    description = db.Column(db.String(512))
    host = db.Column(db.String(15))
    port = db.Column(db.Integer, default=6379)
    password = db.Column(db.String())

    def __repr__(self):
        return '<Server(name=%s)>' % self.name

    @property
    def redis(self):
        return StrictRedis(host=self.host,
                           port=self.port,
                           password=self.password)

    def ping(self):
        """检查Redis服务器是否可以访问
        """
        try:
            return self.redis.ping()  # 这里调用的是StrictRedis对象的ping方法
        except RedisError:
            raise RestException(
                400, 'redis server %s can not connected' % self.host)

    def get_metrics(self):
        """获取Redis服务器监控信息

        通过Redis服务器指令INFO返回监控信息
        """
        try:
            return self.redis.info()  # 这里调用的是StrictRedis对象的info方法
        except RedisError:
            raise RestException(
                400, 'redis server %s can not connected' % self.host)
Beispiel #4
0
class User(BaseModel):
    """用户模型
    """
    __tablename__ = 'user'

    id = db.Column(db.Integer, primary_key=True)
    wx_id = db.Column(db.String(32), unique=True)
    name = db.Column(db.String(64), unique=True)
    email = db.Column(db.String(64), unique=True)
    _password = db.Column(db.String(128))
    is_admin = db.Column(db.Boolean, default=False)
    login_at = db.Column(db.DateTime)

    @property
    def password(self):
        return self._password

    @password.setter
    def password(self, passwd):
        """设置密码
        """
        self._password = generate_password_hash(passwd)

    def verify_password(self, password):
        """检查密码
        """
        return check_password_hash(self.password, password)

    @classmethod
    def authenticate(cls, identifier, password):
        """认证用户

        Args:
                identifier(str): 用户名或邮箱
                password(str): 用户密码

        Returns:
                object: 用户对象

        Raise:
                AuthenticationError
        """
        user = cls.query.filter(
            db.or_(cls.name == identifier, cls.email == identifier)).first()
        if user is None or not user.verify_password(password):
            raise AuthenticationError(403, 'authentication failed')
        return user

    def generate_token(self):
        """生成json web token
        生成token, 有效期为1天,过期后十分钟内可以使用老token刷新获取新的token
        """
        # token过期时间,默认在一天后过期
        exp = datatime.utcnow() + timedelta(days=1)

        # token过期后十分钟内,还可以使用老token进行刷新token
        refresh_exp = timegm((exp + timedelta(seconds=60 * 10)).utctimetuple())

        payload = {
            'uid': self.id,
            'is_admin': self.is_admin,
            'exp': exp,
            'refresh_exp': refresh_exp
        }

        return jwt.encode(payload, current_app.secret_key,
                          algorithm='HS512').decode('utf-8')

    @classmethod
    def verify_token(cls, token, verify_exp=True):
        """检查验证json web token

        Args:
                token(str): json web token
                verify_exp(bool): 是否验证token的过期时间

        Return:
                object: 返回用户对象

        Raise:
                InvalidTokenError
        """
        now = datetime.utcnow()

        if verify_exp:
            options = None
        else:
            options = {'verify_exp': False}

        try:
            payload = jwt.decode(token,
                                 current_app.secret_key,
                                 verify=True,
                                 algorithm=['HS512'],
                                 options=options,
                                 require_exp=True)
        except jwt.InvalidTokenError as e:
            raise InvalidTokenError(403, str(e))

        # 验证token是否正确
        if any(('is_admin' not in payload, 'refresh_exp' not in payload, 'uid'
                not in payload)):
            raise InvalidTokenError(403, 'invalid token')

        # 如果刷新时间过期,则认为token无效
        if payload['refresh_exp'] < timegm(now.utctimetuple()):
            raise InvalidTokenError(403, 'invalid token')

        u = User.query.get(payload.get('uid'))
        if u is None:
            raise InvalidTokenError(403, 'user not exist')
        return u

    @classmethod
    def create_administrator(cls):
        """创建管理员账户

        Return:
                name(str): 管理员账户名称
                password(str): 管理员账户密码
        """
        name = 'admin'
        # 管理员账户名称默认为admin
        admin = cls.query.filter_by(name=name).first()
        if admin:
            return admin.name, ''
        password = '******'
        admin = User(name=name, email='*****@*****.**', is_admin=True)
        admin.password = password
        admin.save()
        return name, password

    @classmethod
    def wx_id_user(cls, wx_id):
        """根据 wx_id获取用户
        """
        return cls.query.filter_by(wx_id=wx_id).first()