2018-05-04 13:44:17 +00:00
|
|
|
import jwt
|
|
|
|
import datetime
|
2018-09-20 20:05:03 +00:00
|
|
|
from app.core import db, app
|
2018-05-08 14:45:09 +00:00
|
|
|
from calendar import timegm
|
2018-05-03 07:48:24 +00:00
|
|
|
|
|
|
|
|
2018-05-03 13:28:57 +00:00
|
|
|
class Account(db.Model):
|
2018-05-03 07:48:24 +00:00
|
|
|
__tablename__ = 'accounts'
|
|
|
|
|
2018-05-03 14:58:44 +00:00
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
|
|
username = db.Column(db.String, index=True, unique=True)
|
|
|
|
password = db.Column(db.String)
|
|
|
|
email = db.Column(db.String, index=True, unique=True)
|
|
|
|
role_id = db.Column(db.Integer, db.ForeignKey("roles.id"))
|
2018-05-03 14:40:30 +00:00
|
|
|
role = db.relationship("Role", foreign_keys=[role_id])
|
2018-10-08 21:09:55 +00:00
|
|
|
confirmed = db.Column(db.Boolean, default=False)
|
|
|
|
confirmed_at = db.Column(db.DateTime, nullable=True)
|
2018-05-08 08:52:49 +00:00
|
|
|
created_at = db.Column(db.DateTime,
|
|
|
|
nullable=False,
|
|
|
|
default=db.func.current_timestamp())
|
|
|
|
modified_at = db.Column(db.DateTime,
|
|
|
|
nullable=False,
|
|
|
|
default=db.func.current_timestamp(),
|
|
|
|
onupdate=db.func.current_timestamp())
|
2018-05-03 07:48:24 +00:00
|
|
|
|
2018-05-04 13:44:17 +00:00
|
|
|
def __init__(self, username, password, email, role=2):
|
2018-05-03 07:48:24 +00:00
|
|
|
self.username = str(username)
|
|
|
|
self.password = str(password)
|
2018-05-03 14:58:44 +00:00
|
|
|
self.email = str(email)
|
2018-05-03 07:48:24 +00:00
|
|
|
if isinstance(role, Role):
|
|
|
|
self.role_id = role.id
|
|
|
|
else:
|
|
|
|
self.role_id = int(role)
|
|
|
|
|
2018-05-03 14:58:44 +00:00
|
|
|
def save(self):
|
2018-05-04 13:44:17 +00:00
|
|
|
"""
|
2018-05-06 19:42:21 +00:00
|
|
|
Stores this user to database
|
2018-05-04 13:44:17 +00:00
|
|
|
This may raise errors
|
|
|
|
"""
|
2018-05-03 14:58:44 +00:00
|
|
|
db.session.add(self)
|
|
|
|
db.session.commit()
|
|
|
|
|
2018-05-04 13:44:17 +00:00
|
|
|
@staticmethod
|
|
|
|
def exists_with_any_of(**kwargs):
|
|
|
|
"""
|
|
|
|
Checks if user with any of the given arguments exists
|
|
|
|
"""
|
|
|
|
for key, value in kwargs.items():
|
|
|
|
args = {key: value}
|
|
|
|
if Account.query.filter_by(**args).first():
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def exists(**kwargs):
|
|
|
|
"""
|
|
|
|
Checks if user with all of the given arguments exists
|
|
|
|
"""
|
|
|
|
if Account.query.filter_by(**kwargs).first():
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
2018-05-03 14:58:44 +00:00
|
|
|
@staticmethod
|
|
|
|
def get_all():
|
2018-05-06 19:42:21 +00:00
|
|
|
"""
|
|
|
|
Get all stored accounts
|
|
|
|
"""
|
2018-05-03 14:58:44 +00:00
|
|
|
return Account.query.all()
|
|
|
|
|
|
|
|
@staticmethod
|
2018-05-04 13:44:17 +00:00
|
|
|
def get(**kwargs):
|
2018-05-06 19:42:21 +00:00
|
|
|
"""
|
2018-05-08 10:58:14 +00:00
|
|
|
Get account with given filters
|
2018-05-06 19:42:21 +00:00
|
|
|
|
|
|
|
Available filters:
|
|
|
|
* username
|
|
|
|
* email
|
|
|
|
* role_id
|
|
|
|
* id
|
|
|
|
* password (useless, but not forbidden)
|
|
|
|
|
|
|
|
"""
|
2018-05-04 13:44:17 +00:00
|
|
|
return Account.query.filter_by(**kwargs).first()
|
|
|
|
|
|
|
|
def create_auth_token(self):
|
|
|
|
"""
|
|
|
|
Generates the Auth Token
|
|
|
|
:return: string
|
|
|
|
"""
|
2018-05-07 15:17:19 +00:00
|
|
|
current_time = datetime.datetime.utcnow()
|
|
|
|
payload = {
|
|
|
|
'exp': current_time + datetime.timedelta(days=0, hours=1),
|
|
|
|
'iat': current_time,
|
|
|
|
'sub': self.id
|
|
|
|
}
|
|
|
|
return jwt.encode(
|
|
|
|
payload,
|
|
|
|
app.config.get('SECRET_KEY'),
|
|
|
|
algorithm='HS256'
|
|
|
|
).decode('utf-8')
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def validate_token(token):
|
|
|
|
"""
|
|
|
|
Validates given Auth token
|
|
|
|
:rtype: Account
|
|
|
|
:return: Account associated with token
|
|
|
|
"""
|
|
|
|
payload = jwt.decode(
|
|
|
|
token,
|
|
|
|
app.config.get('SECRET_KEY'),
|
|
|
|
algorithms=['HS256']
|
|
|
|
)
|
2018-05-08 14:45:09 +00:00
|
|
|
current_time = timegm(datetime.datetime.utcnow().utctimetuple())
|
|
|
|
if current_time > payload['exp']:
|
|
|
|
raise ValueError("Expired token")
|
2018-05-07 15:17:19 +00:00
|
|
|
return Account.get(id=payload['sub'])
|
2018-05-03 14:58:44 +00:00
|
|
|
|
2018-05-03 07:48:24 +00:00
|
|
|
def __repr__(self):
|
2018-05-08 14:45:09 +00:00
|
|
|
return '<Account (name=%s, role=%s)>' % (self.username, self.role)
|
2018-05-03 07:48:24 +00:00
|
|
|
|
|
|
|
|
2018-05-03 13:28:57 +00:00
|
|
|
class Role(db.Model):
|
2018-05-03 07:48:24 +00:00
|
|
|
__tablename__ = 'roles'
|
|
|
|
|
2018-05-03 14:58:44 +00:00
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
2018-09-22 23:22:19 +00:00
|
|
|
display_name = db.Column(db.String, unique=True)
|
|
|
|
permissions = db.Column(db.ARRAY(db.String))
|
2018-05-03 07:48:24 +00:00
|
|
|
|
2018-09-22 23:22:19 +00:00
|
|
|
def __init__(self, name, permissions):
|
2018-05-03 07:48:24 +00:00
|
|
|
self.display_name = str(name)
|
2018-09-22 23:22:19 +00:00
|
|
|
self.permissions = permissions
|
2018-05-03 07:48:24 +00:00
|
|
|
|
2018-05-03 14:58:44 +00:00
|
|
|
def save(self):
|
2018-05-06 19:42:21 +00:00
|
|
|
"""
|
|
|
|
Stores this role to database
|
|
|
|
This may raise errors
|
|
|
|
"""
|
2018-05-03 14:58:44 +00:00
|
|
|
db.session.add(self)
|
|
|
|
db.session.commit()
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_all():
|
2018-05-06 19:42:21 +00:00
|
|
|
"""
|
|
|
|
Get all stored roles
|
|
|
|
"""
|
2018-05-03 14:58:44 +00:00
|
|
|
return Role.query.all()
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get(roleId):
|
2018-05-06 19:42:21 +00:00
|
|
|
"""
|
|
|
|
Get role with id = roleId
|
|
|
|
"""
|
2018-09-22 23:22:19 +00:00
|
|
|
return Role.query.filter_by(id=roleId).first_or_404()
|
2018-05-03 14:58:44 +00:00
|
|
|
|
2018-05-03 07:48:24 +00:00
|
|
|
def __repr__(self):
|
2018-09-22 23:22:19 +00:00
|
|
|
return '<Role %s (%s)>' % self.display_name, self.permissions
|