<reponame>Mateus-Brito/flask-start
import sys
from datetime import datetime
from flask_login import AnonymousUserMixin, UserMixin
from flask import session
from sqlalchemy import Column, ForeignKey, Boolean, DateTime, String, Integer, Text
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from sqlalchemy.orm import relationship

from werkzeug.security import check_password_hash, generate_password_hash

from sqlalchemy.exc import IntegrityError

from models.base import Model
from dynaconf import settings

def dump_datetime(value):
    """Deserialize datetime object into string form for JSON processing."""
    if value is None:
        return None
    return [value.strftime("%Y-%m-%d"), value.strftime("%H:%M:%S")]

class TimestampMixin(object):
    date_created = Column(DateTime, nullable=False, default=datetime.utcnow)
    date_updated = Column(DateTime, onupdate=datetime.utcnow)

class Role(Model):
    __tablename__ = "role"

    id = Column('id', Integer, primary_key=True)
    name = Column('name', String(256))

    @staticmethod
    def insert_default(db):
        roles = {'User','Administrator'}
        for role in roles:
            if Role.query.filter_by(name=role).first() is None:
                Role(name=role).save(db)

    def save(self, db):
        try:
            db.session.add(self)
            db.session.commit()
        except IntegrityError:
            db.session.rollback()
            return False
        return True
        
class User(UserMixin, Model,TimestampMixin):
    __tablename__ = "user"

    id = Column('id', Integer, primary_key=True)
    first_name = Column('first_name', String(50))
    last_name = Column('last_name', String(50))
    email = Column('email', String(254))
    confirmed = Column('confirmed', Boolean, default=False)
    password_hash = Column(String(256), nullable=False)
    status = Column('status', Boolean, default=True) #0 for unconfirmed , 1 for confirmed and -1 for inactive
    user_role = Column(Integer, ForeignKey('role.id'))
    role = relationship('Role', backref='role', lazy=True)

    def __init__(self, **kwargs):
        super(User, self).__init__(**kwargs)

    @property
    def password(self):
        raise AttributeError('`password` is not a readable attribute')

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)

    def full_name(self):
        return "{0} {1}".format(self.first_name, self.last_name)

    def verify_password(self, password):
        return check_password_hash(self.password_hash, password)

    def generate_confirmation_token(self, expiration=604800):
        """Generate a confirmation token to email a new user."""

        s = Serializer(settings.SECRET_KEY, expiration)
        return s.dumps({'confirm': self.id})

    def generate_password_reset_token(self, expiration=3600):
        s = Serializer(settings.SECRET_KEY, expiration)
        return s.dumps({'reset': self.id})

    def confirm_account(self, token):
        """Verify that the provided token is for this user's id."""
        s = Serializer(settings.SECRET_KEY)
        try:
            data = s.loads(token)
        except (BadSignature, SignatureExpired):
            return False
        if data.get('confirm') != self.id:
            return False
        self.confirmed = True
        return True

    def is_admin(self):
        return self.role is not None and self.role.name.upper() == 'Administrator'.upper(); #default Admin

    @staticmethod
    def insert_default(db):
        role_admin = Role.query.filter_by(name='Administrator').first().id
        users = [
            {'first_name':'Admin',
            'last_name':'',
            'email':'<EMAIL>',
            'password':'<PASSWORD>',
            'status':1,
            'user_role':role_admin}
            ]
        for user in users:
            if User.query.filter_by(email=user['email']).first() is None:
                User(**user).save(db)

    def save(self, db):
        try:
            db.session.add(self)
            db.session.commit()
        except IntegrityError:
            db.session.rollback()
            return False
        return True

class AnonymousUser(AnonymousUserMixin):
    def can(self, _):
        return False

    def is_admin(self):
        return False
import sys
from datetime import datetime
from flask_login import AnonymousUserMixin, UserMixin
from flask import session
from sqlalchemy import Column, ForeignKey, Boolean, DateTime, String, Integer, Text
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from sqlalchemy.orm import relationship

from werkzeug.security import check_password_hash, generate_password_hash

from sqlalchemy.exc import IntegrityError

from models.base import Model
from dynaconf import settings

def dump_datetime(value):
    """Deserialize datetime object into string form for JSON processing."""
    if value is None:
        return None
    return [value.strftime("%Y-%m-%d"), value.strftime("%H:%M:%S")]

class TimestampMixin(object):
    date_created = Column(DateTime, nullable=False, default=datetime.utcnow)
    date_updated = Column(DateTime, onupdate=datetime.utcnow)

class Role(Model):
    __tablename__ = "role"

    id = Column('id', Integer, primary_key=True)
    name = Column('name', String(256))

    @staticmethod
    def insert_default(db):
        roles = {'User','Administrator'}
        for role in roles:
            if Role.query.filter_by(name=role).first() is None:
                Role(name=role).save(db)

    def save(self, db):
        try:
            db.session.add(self)
            db.session.commit()
        except IntegrityError:
            db.session.rollback()
            return False
        return True
        
class User(UserMixin, Model,TimestampMixin):
    __tablename__ = "user"

    id = Column('id', Integer, primary_key=True)
    first_name = Column('first_name', String(50))
    last_name = Column('last_name', String(50))
    email = Column('email', String(254))
    confirmed = Column('confirmed', Boolean, default=False)
    password_hash = Column(String(256), nullable=False)
    status = Column('status', Boolean, default=True) #0 for unconfirmed , 1 for confirmed and -1 for inactive
    user_role = Column(Integer, ForeignKey('role.id'))
    role = relationship('Role', backref='role', lazy=True)

    def __init__(self, **kwargs):
        super(User, self).__init__(**kwargs)

    @property
    def password(self):
        raise AttributeError('`password` is not a readable attribute')

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)

    def full_name(self):
        return "{0} {1}".format(self.first_name, self.last_name)

    def verify_password(self, password):
        return check_password_hash(self.password_hash, password)

    def generate_confirmation_token(self, expiration=604800):
        """Generate a confirmation token to email a new user."""

        s = Serializer(settings.SECRET_KEY, expiration)
        return s.dumps({'confirm': self.id})

    def generate_password_reset_token(self, expiration=3600):
        s = Serializer(settings.SECRET_KEY, expiration)
        return s.dumps({'reset': self.id})

    def confirm_account(self, token):
        """Verify that the provided token is for this user's id."""
        s = Serializer(settings.SECRET_KEY)
        try:
            data = s.loads(token)
        except (BadSignature, SignatureExpired):
            return False
        if data.get('confirm') != self.id:
            return False
        self.confirmed = True
        return True

    def is_admin(self):
        return self.role is not None and self.role.name.upper() == 'Administrator'.upper(); #default Admin

    @staticmethod
    def insert_default(db):
        role_admin = Role.query.filter_by(name='Administrator').first().id
        users = [
            {'first_name':'Admin',
            'last_name':'',
            'email':'<EMAIL>',
            'password':'<PASSWORD>',
            'status':1,
            'user_role':role_admin}
            ]
        for user in users:
            if User.query.filter_by(email=user['email']).first() is None:
                User(**user).save(db)

    def save(self, db):
        try:
            db.session.add(self)
            db.session.commit()
        except IntegrityError:
            db.session.rollback()
            return False
        return True

class AnonymousUser(AnonymousUserMixin):
    def can(self, _):
        return False

    def is_admin(self):
        return False
Deserialize datetime object into string form for JSON processing. #0 for unconfirmed , 1 for confirmed and -1 for inactive Generate a confirmation token to email a new user. Verify that the provided token is for this user's id. #default Admin