2018-04-27 17:16:43 +00:00
|
|
|
from uuid import uuid4
|
|
|
|
|
2018-08-03 16:15:08 +00:00
|
|
|
from flask import current_app as app
|
2021-12-28 08:39:12 +00:00
|
|
|
from flask_login import UserMixin
|
2022-04-06 10:35:08 +00:00
|
|
|
from sqlalchemy import BigInteger, Boolean, Column, Sequence
|
2018-04-27 17:16:43 +00:00
|
|
|
from sqlalchemy.dialects.postgresql import UUID
|
2018-08-03 16:15:08 +00:00
|
|
|
from sqlalchemy_utils import EmailType, PasswordType
|
2021-04-13 16:33:15 +00:00
|
|
|
from teal.db import IntEnum
|
2018-04-27 17:16:43 +00:00
|
|
|
|
2019-01-21 15:08:55 +00:00
|
|
|
from ereuse_devicehub.db import db
|
2022-04-06 10:35:08 +00:00
|
|
|
from ereuse_devicehub.resources.enums import SessionType
|
2019-01-21 15:08:55 +00:00
|
|
|
from ereuse_devicehub.resources.inventory.model import Inventory
|
2018-08-03 16:15:08 +00:00
|
|
|
from ereuse_devicehub.resources.models import STR_SIZE, Thing
|
2018-04-27 17:16:43 +00:00
|
|
|
|
|
|
|
|
2021-12-28 08:39:12 +00:00
|
|
|
class User(UserMixin, Thing):
|
2018-04-27 17:16:43 +00:00
|
|
|
__table_args__ = {'schema': 'common'}
|
|
|
|
id = Column(UUID(as_uuid=True), default=uuid4, primary_key=True)
|
|
|
|
email = Column(EmailType, nullable=False, unique=True)
|
2022-04-06 10:35:08 +00:00
|
|
|
password = Column(
|
|
|
|
PasswordType(
|
|
|
|
max_length=STR_SIZE,
|
|
|
|
onload=lambda **kwargs: dict(
|
|
|
|
schemes=app.config['PASSWORD_SCHEMES'], **kwargs
|
|
|
|
),
|
|
|
|
)
|
|
|
|
)
|
2019-01-23 15:55:04 +00:00
|
|
|
token = Column(UUID(as_uuid=True), default=uuid4, unique=True, nullable=False)
|
2021-04-08 17:13:28 +00:00
|
|
|
active = Column(Boolean, default=True, nullable=False)
|
|
|
|
phantom = Column(Boolean, default=False, nullable=False)
|
2022-04-06 10:35:08 +00:00
|
|
|
inventories = db.relationship(
|
|
|
|
Inventory,
|
|
|
|
backref=db.backref('users', lazy=True, collection_class=set),
|
|
|
|
secondary=lambda: UserInventory.__table__,
|
|
|
|
collection_class=set,
|
|
|
|
)
|
2019-02-18 11:43:50 +00:00
|
|
|
|
2019-01-23 15:55:04 +00:00
|
|
|
# todo set restriction that user has, at least, one active db
|
|
|
|
|
2022-04-06 10:35:08 +00:00
|
|
|
def __init__(
|
|
|
|
self, email, password=None, inventories=None, active=True, phantom=False
|
|
|
|
) -> None:
|
2019-06-19 11:35:26 +00:00
|
|
|
"""Creates an user.
|
2019-01-23 15:55:04 +00:00
|
|
|
:param email:
|
|
|
|
:param password:
|
|
|
|
:param inventories: A set of Inventory where the user has
|
|
|
|
access to. If none, the user is granted access to the current
|
|
|
|
inventory.
|
2021-04-08 17:13:28 +00:00
|
|
|
:param active: allow active and deactive one account without delete the account
|
|
|
|
:param phantom: it's util for identify the phantom accounts
|
|
|
|
create during the trade actions
|
2019-01-23 15:55:04 +00:00
|
|
|
"""
|
|
|
|
inventories = inventories or {Inventory.current}
|
2022-04-06 10:35:08 +00:00
|
|
|
super().__init__(
|
|
|
|
email=email,
|
|
|
|
password=password,
|
|
|
|
inventories=inventories,
|
|
|
|
active=active,
|
|
|
|
phantom=phantom,
|
|
|
|
)
|
2018-05-13 13:13:12 +00:00
|
|
|
|
|
|
|
def __repr__(self) -> str:
|
2018-08-03 16:15:08 +00:00
|
|
|
return '<User {0.email}>'.format(self)
|
2018-05-30 10:49:40 +00:00
|
|
|
|
2019-02-18 11:43:50 +00:00
|
|
|
@property
|
|
|
|
def type(self) -> str:
|
|
|
|
return self.__class__.__name__
|
|
|
|
|
2018-08-03 16:15:08 +00:00
|
|
|
@property
|
|
|
|
def individual(self):
|
|
|
|
"""The individual associated for this database, or None."""
|
|
|
|
return next(iter(self.individuals), None)
|
2019-01-21 15:08:55 +00:00
|
|
|
|
2021-07-01 10:08:18 +00:00
|
|
|
@property
|
|
|
|
def code(self):
|
|
|
|
"""Code of phantoms accounts"""
|
|
|
|
if not self.phantom:
|
|
|
|
return
|
|
|
|
return self.email.split('@')[0].split('_')[1]
|
|
|
|
|
2021-12-28 08:39:12 +00:00
|
|
|
@property
|
|
|
|
def is_active(self):
|
|
|
|
"""Alias because flask-login expects `is_active` attribute"""
|
|
|
|
return self.active
|
|
|
|
|
2021-12-28 12:26:56 +00:00
|
|
|
@property
|
|
|
|
def get_full_name(self):
|
2022-04-12 14:59:45 +00:00
|
|
|
if self.individuals:
|
2022-04-06 10:35:08 +00:00
|
|
|
return self.individual.get_full_name
|
|
|
|
|
2021-12-28 12:26:56 +00:00
|
|
|
return self.email
|
|
|
|
|
2021-12-28 08:39:12 +00:00
|
|
|
def check_password(self, password):
|
|
|
|
# take advantage of SQL Alchemy PasswordType to verify password
|
|
|
|
return self.password == password
|
|
|
|
|
2019-01-21 15:08:55 +00:00
|
|
|
|
|
|
|
class UserInventory(db.Model):
|
|
|
|
"""Relationship between users and their inventories."""
|
2022-04-06 10:35:08 +00:00
|
|
|
|
2019-01-21 15:08:55 +00:00
|
|
|
__table_args__ = {'schema': 'common'}
|
|
|
|
user_id = db.Column(db.UUID(as_uuid=True), db.ForeignKey(User.id), primary_key=True)
|
2022-04-06 10:35:08 +00:00
|
|
|
inventory_id = db.Column(
|
|
|
|
db.Unicode(), db.ForeignKey(Inventory.id), primary_key=True
|
|
|
|
)
|
2021-04-13 16:33:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
class Session(Thing):
|
2021-05-24 11:00:03 +00:00
|
|
|
__table_args__ = {'schema': 'common'}
|
2021-04-13 16:33:15 +00:00
|
|
|
id = Column(BigInteger, Sequence('device_seq'), primary_key=True)
|
|
|
|
expired = Column(BigInteger, default=0)
|
|
|
|
token = Column(UUID(as_uuid=True), default=uuid4, unique=True, nullable=False)
|
|
|
|
type = Column(IntEnum(SessionType), default=SessionType.Internal, nullable=False)
|
|
|
|
user_id = db.Column(db.UUID(as_uuid=True), db.ForeignKey(User.id))
|
2022-04-06 10:35:08 +00:00
|
|
|
user = db.relationship(
|
|
|
|
User,
|
|
|
|
backref=db.backref('sessions', lazy=True, collection_class=set),
|
|
|
|
collection_class=set,
|
|
|
|
)
|
2021-04-15 19:18:15 +00:00
|
|
|
|
|
|
|
def __str__(self) -> str:
|
|
|
|
return '{0.token}'.format(self)
|