You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

61 lines
2.0 KiB

  1. from werkzeug.security import generate_password_hash, check_password_hash
  2. from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
  3. from itsdangerous import BadSignature
  4. from flask import current_app
  5. from flask_login import UserMixin
  6. from . import db, login_manager
  7. class Role(db.Model):
  8. __tablename__ = 'roles'
  9. id = db.Column(db.Integer, primary_key=True)
  10. name = db.Column(db.String(64), unique=True)
  11. users = db.relationship('User', backref='role', lazy='dynamic')
  12. def __repr__(self):
  13. return '<Role %r>' % self.name
  14. class User(UserMixin, db.Model):
  15. __tablename__ = 'users'
  16. id = db.Column(db.Integer, primary_key=True)
  17. email = db.Column(db.String(64), unique=True, index=True)
  18. username = db.Column(db.String(64), unique=True, index=True)
  19. role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
  20. password_hash = db.Column(db.String(128))
  21. confirmed = db.Column(db.Boolean, default=False)
  22. @property
  23. def password(self):
  24. raise AttributeError('Password is not a readable attribute')
  25. @password.setter
  26. def password(self, password):
  27. self.password_hash = generate_password_hash(password)
  28. def verify_password(self, password):
  29. return check_password_hash(self.password_hash, password)
  30. def generate_confirmation_token(self, expiration=3600):
  31. s = Serializer(current_app.config['SECRET_KEY'], expiration)
  32. return s.dumps({'confirm': self.id}).decode('utf-8')
  33. def confirm(self, token):
  34. s = Serializer(current_app.config['SECRET_KEY'])
  35. try:
  36. data = s.loads(token.encode('utf-8'))
  37. except BadSignature:
  38. return False
  39. if data.get('confirm') != self.id:
  40. return False
  41. self.confirmed = True
  42. db.session.add(self)
  43. return True
  44. def __repr__(self):
  45. return '<User %r>' % self.username
  46. @login_manager.user_loader
  47. def load_user(user_id):
  48. return User.query.get(int(user_id))