Beispiel #1
0
class Notification(db.Model, BaseModel):
    """Model for Notification"""

    __tablename__ = 'notifications'

    # columns
    user_id = db.Column('user_id',
                        db.Integer,
                        db.ForeignKey('users.id'),
                        nullable=True)
    channel = db.Column('channel', db.Integer, nullable=False)
    template = db.Column('template', db.String(60), nullable=True)
    service = db.Column('service', db.String(60), nullable=True)
    notification_id = db.Column('notification_id',
                                db.String(60),
                                nullable=True)
    accepted = db.Column('accepted', db.Integer, nullable=False)
    rejected = db.Column('rejected', db.Integer, nullable=False)
    sent_at = db.Column('sent_at',
                        db.TIMESTAMP(timezone=True),
                        server_default=db.func.current_timestamp(),
                        nullable=False)

    # relationships
    user = db.relationship('User', back_populates='notifications')
Beispiel #2
0
class AdministratorPasswordHistory(db.Model):
    """Model for AdministratorPasswordHistory"""

    __tablename__ = 'administrator_password_history'

    # columns
    id = db.Column('id', db.BigInteger, primary_key=True)
    administrator_id = db.Column('administrator_id',
                                 db.Integer,
                                 db.ForeignKey('administrators.id'),
                                 nullable=True)
    password = db.Column('password', db.String(60), nullable=False)
    set_date = db.Column('set_date',
                         db.TIMESTAMP(timezone=True),
                         server_default=db.func.current_timestamp(),
                         nullable=False)

    # timestamps
    created_at = db.Column('created_at',
                           db.TIMESTAMP(timezone=True),
                           server_default=db.func.current_timestamp(),
                           nullable=False)
    updated_at = db.Column('updated_at',
                           db.TIMESTAMP(timezone=True),
                           server_default=db.func.current_timestamp(),
                           onupdate=db.func.current_timestamp(),
                           nullable=False)

    # relationships
    administrator = db.relationship('Administrator',
                                    back_populates='password_history')
Beispiel #3
0
class UserProfile(db.Model, BaseModel):
    """Model for UserProfile"""

    __tablename__ = 'user_profiles'

    CRYPT_SYM_SECRET_KEY = Config.CRYPT_SYM_SECRET_KEY

    # columns
    user_id = db.Column('user_id',
                        db.Integer,
                        db.ForeignKey('users.id'),
                        nullable=False)
    first_name = db.Column('first_name',
                           PGPString(CRYPT_SYM_SECRET_KEY, length=200),
                           nullable=False)
    last_name = db.Column('last_name',
                          PGPString(CRYPT_SYM_SECRET_KEY, length=200),
                          nullable=False)
    joined_at = db.Column('joined_at',
                          db.TIMESTAMP(timezone=True),
                          index=True,
                          server_default=db.func.current_timestamp(),
                          nullable=False)

    # relationships
    user = db.relationship('User', back_populates='profile')
Beispiel #4
0
class Country(db.Model, BaseModel):
    """Model for Country"""

    __tablename__ = 'countries'

    # columns
    name = db.Column('name', db.String(60), unique=True, nullable=False)
    code_2 = db.Column('code_2', db.String(2), unique=True, nullable=False)
    code_3 = db.Column('code_3', db.String(3), unique=True, nullable=False)

    # relationships
    regions = db.relationship("Region", back_populates="country")
Beispiel #5
0
class UserTermsOfService(db.Model):
    """Model for UserTermsOfService"""

    __tablename__ = 'user_terms_of_services'

    CRYPT_SYM_SECRET_KEY = Config.CRYPT_SYM_SECRET_KEY

    # columns
    user_id = db.Column('user_id',
                        db.Integer,
                        db.ForeignKey('users.id'),
                        primary_key=True)
    terms_of_service_id = db.Column('terms_of_service_id',
                                    db.Integer,
                                    db.ForeignKey('terms_of_services.id'),
                                    primary_key=True)
    accept_date = db.Column('accept_date',
                            db.TIMESTAMP(timezone=True),
                            server_default=db.func.current_timestamp(),
                            nullable=False)
    ip_address = db.Column('ip_address',
                           PGPString(CRYPT_SYM_SECRET_KEY, length=200),
                           nullable=False)

    # relationships
    user = db.relationship('User', uselist=False)
    terms_of_service = db.relationship('TermsOfService', uselist=False)

    # timestamps
    created_at = db.Column('created_at',
                           db.TIMESTAMP(timezone=True),
                           server_default=db.func.current_timestamp(),
                           nullable=False)
    updated_at = db.Column('updated_at',
                           db.TIMESTAMP(timezone=True),
                           server_default=db.func.current_timestamp(),
                           onupdate=db.func.current_timestamp(),
                           nullable=False)
Beispiel #6
0
class Region(db.Model, BaseModel):
    """Model for Region"""

    __tablename__ = 'regions'

    # columns
    name = db.Column('name', db.String(60), nullable=False)
    code_2 = db.Column('code_2', db.String(2))
    country_id = db.Column('country_id',
                           db.Integer,
                           db.ForeignKey('countries.id'),
                           nullable=False)

    # relationships
    country = db.relationship('Country', back_populates="regions")
Beispiel #7
0
class PasswordReset(db.Model, BaseModel):
    """Model for PasswordReset"""

    __tablename__ = 'password_resets'

    # columns
    user_id = db.Column('user_id',
                        db.Integer,
                        db.ForeignKey('users.id'),
                        nullable=False)
    code = db.Column('code', db.String(40), nullable=False)
    is_used = db.Column('is_used', db.Boolean, nullable=False)
    requested_at = db.Column('requested_at',
                             db.TIMESTAMP(timezone=True),
                             server_default=db.func.current_timestamp(),
                             nullable=False)
    ip_address = db.Column('ip_address', db.String(50), index=True)

    # relationships
    user = db.relationship('User', back_populates='password_resets')
Beispiel #8
0
class Administrator(db.Model, BaseModel):
    """Model for Administrator"""

    __tablename__ = 'administrators'

    HASH_ROUNDS = Config.AUTH_HASH_ROUNDS
    AUTH_SECRET_KEY = Config.AUTH_SECRET_KEY
    CRYPT_SYM_SECRET_KEY = Config.CRYPT_SYM_SECRET_KEY
    CRYPT_DIGEST_SALT = Config.CRYPT_DIGEST_SALT

    # columns
    username = db.Column('username',
                         db.String(40),
                         index=True,
                         unique=True,
                         nullable=False)
    _email = db.Column('email',
                       PGPString(CRYPT_SYM_SECRET_KEY, length=500),
                       nullable=False)
    email_digest = db.Column('email_digest',
                             db.String(64),
                             unique=True,
                             nullable=False)
    first_name = db.Column('first_name',
                           PGPString(CRYPT_SYM_SECRET_KEY, length=200),
                           nullable=False)
    last_name = db.Column('last_name',
                          PGPString(CRYPT_SYM_SECRET_KEY, length=200),
                          nullable=False)
    _password = db.Column('password', db.String(60), nullable=False)
    password_changed_at = db.Column('password_changed_at',
                                    db.TIMESTAMP(timezone=True),
                                    server_default=db.func.current_timestamp(),
                                    nullable=False)
    joined_at = db.Column('joined_at',
                          db.TIMESTAMP(timezone=True),
                          server_default=db.func.current_timestamp(),
                          nullable=False)

    # relationships
    roles = db.relationship('Role',
                            secondary=roles,
                            lazy='subquery',
                            order_by="Role.priority",
                            backref=db.backref('administrators', lazy=True))
    password_history = db.relationship(
        'AdministratorPasswordHistory',
        cascade="all,delete-orphan",
        back_populates='administrator',
        order_by=AdministratorPasswordHistory.set_date.desc())

    @hybrid_property
    def password(self):
        """Gets `password` property (hashed).

        :return: User's hashed password value
        :rtype: string
        """

        return self._password

    @password.setter
    def password(self, password):
        """Sets `password` property.

        Applies Bcrypt hashing function to `password` before storing it. The
        number of hashing rounds are configurable in the main application
        config settings.

        :param password: User's plaintext password
        :type password: str
        """

        self._password = str(
            bcrypt.hashpw(bytes(password, 'utf-8'),
                          bcrypt.gensalt(self.HASH_ROUNDS)), 'utf8')
        self.password_changed_at = datetime.now()

    @hybrid_property
    def email(self):
        """Gets `email` property.

        :return: User's plaintext email address
        :rtype: str
        """

        return self._email

    @email.setter
    def email(self, email):
        """Sets `email` property.

        Applies a lowercase transformation to `email` before storing it. Also
        sets the `email_digest` property to its SHA-256 hash value - this is
        useful if the email is stored encrypted, to allow lookups and
        comparisons (e.g.: duplicates) if an exact match is supplied.

        :param email: User's plaintext email address
        :type email: str
        """

        self._email = email.lower()
        hash_object = hashlib.sha256(
            (self.CRYPT_DIGEST_SALT + email).encode('utf-8'))
        self.email_digest = hash_object.hexdigest()

    def check_password(self, password):
        """Checks supplied password against saved value.

        :param password: User's plaintext password
        :type password: str
        :return: True if password matches what's on file, False otherwise
        :rtype: bool
        """

        return bcrypt.checkpw(password.encode('utf-8'),
                              self._password.encode('utf-8'))

    def generate_auth_token(self, expiration=1800):
        """Creates a new authentication token.

        :param expiration: Length of time in seconds that token is valid
        :type expiration: int
        :return: Authentication token
        :rtype: str
        """

        ser = Serializer(self.AUTH_SECRET_KEY, expires_in=expiration)
        return ser.dumps({'id': self.id, 'type': 'administrator'})

    @staticmethod
    def verify_auth_token(token):
        """Verifies authentication token is valid and current.

        :param token: Authentication token
        :type token: str
        :return: The user associated with token if valid, None otherwise
        :rtype: User | None
        """

        ser = Serializer(Administrator.AUTH_SECRET_KEY)
        try:
            data = ser.loads(token)
        except SignatureExpired:
            return None  # valid token, but expired
        except BadSignature:
            return None  # invalid token
        if 'type' in data and data['type'] == 'administrator':
            admin = Administrator.query.get(data['id'])
            return admin
        return None