Example #1
0
class Category(db.Model, Base, EntityBase):
    __tablename__ = 'category'
    id = db.Column(guid(), primary_key=True)

    # Relationship with parent Category
    parent_id = db.Column(guid(),
                          db.ForeignKey('category.id',
                                        name='fk_category_id_category',
                                        onupdate='CASCADE',
                                        ondelete='CASCADE'),
                          index=True)
    parent = db.relationship(lambda: Category,
                             remote_side=id,
                             backref='sub_products')

    name = db.Column(db.String(255), nullable=False, unique=True)
    description = db.Column(db.Text, nullable=False)
    photo = db.Column(db.String(255))

    @property
    def entity_type(self):
        return EntityBase.TYPE_CATEGORY

    @property
    def resource_type(self):
        from models.acl import AclResource
        return AclResource.CATEGORY
Example #2
0
class Product(db.Model, Base, EntityBase):
    __tablename__ = 'product'
    id = db.Column(guid(), primary_key=True)

    # Relationships with Category
    category_id = db.Column(guid(),
                            db.ForeignKey('category.id',
                                          name='fk_product_id_category',
                                          onupdate='CASCADE',
                                          ondelete='CASCADE'),
                            index=True)
    category = db.relationship('Category')

    name = db.Column(db.String(255), nullable=False)
    photo = db.Column(db.String(255))
    code = db.Column(db.String(255), nullable=False)
    price = db.Column(db.Numeric(10, 2), nullable=False)
    quantity = db.Column(db.Integer, nullable=False, default=0)
    description = db.Column(db.Text)

    @property
    def entity_type(self):
        return EntityBase.TYPE_PRODUCT

    @property
    def resource_type(self):
        from models.acl import AclResource
        return AclResource.PRODUCT
Example #3
0
class AclUserResource(db.Model):
    __tablename__ = 'acl_user_resource'

    user_id = db.Column(guid(),
                        db.ForeignKey('user.id',
                                      name='fk_acl_user_resource_id_user',
                                      onupdate='CASCADE',
                                      ondelete='CASCADE'),
                        primary_key=True,
                        nullable=False)
    user = db.relationship('User')

    resource_id = db.Column(guid(), primary_key=True, nullable=False)
    resource_type = db.Column(db.Integer,
                              primary_key=True,
                              nullable=False,
                              autoincrement=False)
    _privilege = db.Column(db.Integer,
                           name='privilege',
                           primary_key=True,
                           autoincrement=False,
                           nullable=False)
    _permission = db.Column(db.Integer,
                            name='permission',
                            primary_key=True,
                            autoincrement=False,
                            nullable=False)

    @property
    def privilege(self):
        from libraries.bitwise import Bitwise
        return Bitwise(self._privilege)

    @privilege.setter
    def privilege(self, bit):
        self._privilege = bit

    @property
    def permission(self):
        from libraries.bitwise import Bitwise
        return Bitwise(self._permission)

    @permission.setter
    def permission(self, bit):
        self._permission = bit

    @staticmethod
    def get_permission_for_user(user_id, resource_id, resource_type,
                                privilege):
        from sqlalchemy import and_, or_
        return AclUserResource.query.filter(
            and_(
                AclUserResource.user_id == user_id,
                AclUserResource.resource_id == resource_id,
                or_(resource_type is None,
                    AclUserResource.resource_type == resource_type),
                AclUserResource._privilege.op('&')(privilege) > 0,
            )).all()
Example #4
0
class EntityMeta(db.Model, Base):
    __tablename__ = 'sys_entity_meta'
    entity_id = db.Column(guid(), nullable=False, autoincrement=False, primary_key=True)
    entity_type = db.Column(db.Integer, nullable=False, autoincrement=False, primary_key=True)
    meta_id = db.Column(guid(), db.ForeignKey(
        'sys_meta_value.id',
        onupdate='CASCADE',
        ondelete='CASCADE'
    ), nullable=False, autoincrement=False, primary_key=True)
Example #5
0
class AclRole(db.Model):
    __tablename__ = 'acl_role'
    id = db.Column(guid(), primary_key=True)
    name = db.Column(db.String(255), unique=True, nullable=False)

    parent_id = db.Column(guid(),
                          db.ForeignKey('acl_role.id',
                                        name='fk_acl_role_id_acl_role',
                                        ondelete='CASCADE',
                                        onupdate='CASCADE'),
                          index=True)
    parent = db.relationship('AclRole')

    def get_parents(self):
        """

        :return: array of role.id
        """
        if not self.parent_id:
            return []

        results = [self.parent_id]

        # Include parent's parent
        parent = self.query.filter_by(id=self.parent_id).first()
        results.extend(parent.get_parents())

        return results

    @staticmethod
    def get_default_role():
        from flask import current_app as app
        result = AclRole.query.filter_by(
            name=app.config.get('DEFAULT_USER_ROLE')).first()
        if not result:
            from sqlalchemy.exc import DataError
            raise DataError('System is missing DEFAULT_ROLE')
        return result

    @staticmethod
    def get_owner_role():
        from flask import current_app as app

        result = AclRole.query.filter_by(
            name=app.config.get('OWNER_USER_ROLE')).first()
        if not result:
            from sqlalchemy.exc import DataError
            raise DataError('System is missing OWNER_ROLE')

        return result
Example #6
0
class AclUserRole(db.Model):
    __tablename__ = 'acl_user_role'
    user_id = db.Column(guid(),
                        db.ForeignKey('user.id',
                                      name='fk_acl_user_role_id_user',
                                      onupdate='CASCADE',
                                      ondelete='CASCADE'),
                        primary_key=True,
                        nullable=False)
    user = db.relationship('User')

    role_id = db.Column(guid(),
                        db.ForeignKey('acl_role.id',
                                      name='fk_acl_user_role_id_acl_role',
                                      onupdate='CASCADE',
                                      ondelete='CASCADE'),
                        primary_key=True,
                        nullable=False)
    role = db.relationship('AclRole')

    @staticmethod
    def get_roles_for(user_id, is_owner):
        """

        :param user_id:
        :return: arrays of role.id
        """
        default_role = AclRole.get_default_role()
        results = [default_role.id]

        if is_owner:
            owner_role = AclRole.get_owner_role()
            results.append(owner_role.id)

        roles = AclUserRole.query.filter_by(user_id=user_id).all()

        for r in roles:
            # Add role.id
            results.append(r.role_id)
            if not r.role.parent_id:
                continue

            # Find parent recursive
            results.extend(r.role.get_parents())

        return filter(None, set(results))
Example #7
0
class AclRoleResource(db.Model):
    __tablename__ = 'acl_role_resource'

    role_id = db.Column(guid(),
                        db.ForeignKey('acl_role.id',
                                      name='fk_acl_role_resource_id_acl_role',
                                      ondelete='CASCADE',
                                      onupdate='CASCADE'),
                        primary_key=True,
                        nullable=False)
    role = db.relationship('AclRole')
    resource_name = db.Column(db.String(255), primary_key=True, nullable=False)
    _privilege = db.Column(db.Integer,
                           name='privilege',
                           primary_key=True,
                           autoincrement=False,
                           nullable=False)
    _permission = db.Column(db.Integer,
                            name='permission',
                            primary_key=True,
                            autoincrement=False,
                            nullable=False)

    @property
    def privilege(self):
        from libraries.bitwise import Bitwise
        return Bitwise(self._privilege)

    @privilege.setter
    def privilege(self, bit):
        self._privilege = bit

    @property
    def permission(self):
        from libraries.bitwise import Bitwise
        return Bitwise(self._permission)

    @permission.setter
    def permission(self, bit):
        self._permission = bit

    @staticmethod
    def get_permission_for_user(user_id, resource_name, privilege, is_owner):
        from sqlalchemy import and_, or_
        from sqlalchemy.sql.operators import in_op

        roles = AclUserRole.get_roles_for(user_id=user_id, is_owner=is_owner)

        return AclRoleResource.query.filter(
            and_(
                or_(
                    AclRoleResource.resource_name == '*',
                    AclRoleResource.resource_name == resource_name,
                ),
                AclRoleResource._privilege.op('&')(privilege) > 0,
                in_op(AclRoleResource.role_id, roles))).all()
Example #8
0
class Client(db.Model):
    __tablename__ = 'client'
    # human readable name, not required
    name = db.Column(db.String(40))

    # human readable description, not required
    description = db.Column(db.String(400))

    # creator of the client, not required

    user_id = db.Column(
        guid(), db.ForeignKey('user.id',
                              onupdate='CASCADE',
                              ondelete='CASCADE'))
    user = db.relationship('User')

    client_id = db.Column(db.String(40), primary_key=True)
    client_secret = db.Column(db.String(55),
                              unique=True,
                              index=True,
                              nullable=False)

    # public or confidential
    is_confidential = db.Column(db.Boolean)

    _redirect_uris = db.Column(db.Text)
    _default_scopes = db.Column(db.Text)

    @property
    def client_type(self):
        if self.is_confidential:
            return 'confidential'
        return 'public'

    @property
    def redirect_uris(self):
        if self._redirect_uris:
            return self._redirect_uris.split()
        return []

    @property
    def default_redirect_uri(self):
        return self.redirect_uris[0]

    @property
    def default_scopes(self):
        return ['email']
Example #9
0
class Grant(db.Model):
    __tablename__ = 'grant'
    id = db.Column(db.String(40), primary_key=True)

    user_id = db.Column(
        guid(), db.ForeignKey('user.id',
                              onupdate='CASCADE',
                              ondelete='CASCADE'))
    user = db.relationship('User')

    client_id = db.Column(
        db.String(40),
        db.ForeignKey('client.client_id',
                      onupdate='CASCADE',
                      ondelete='CASCADE'),
        nullable=False,
    )
    client = db.relationship('Client')

    code = db.Column(db.String(255), index=True, nullable=False)

    redirect_uri = db.Column(db.String(255))
    expires = db.Column(db.DateTime)

    _scopes = db.Column(db.Text)

    def delete(self):
        from flask import current_app as app
        session = app.db.session
        session.delete(self)
        session.commit()
        return self

    @property
    def scopes(self):
        if self._scopes:
            return self._scopes.split()
        return []

    def validate_redirect_uri(self, redirect_uri):
        return True
Example #10
0
class Token(db.Model):
    __tablename__ = 'token'
    id = db.Column(db.Integer, primary_key=True)

    client_id = db.Column(
        db.String(40),
        db.ForeignKey('client.client_id',
                      onupdate='CASCADE',
                      ondelete='CASCADE'),
        nullable=False,
    )

    client = db.relationship('Client')

    user_id = db.Column(
        guid(), db.ForeignKey('user.id',
                              onupdate='CASCADE',
                              ondelete='CASCADE'))
    user = db.relationship('User')

    # currently only bearer is supported
    token_type = db.Column(db.String(40))

    access_token = db.Column(db.String(255), unique=True)
    refresh_token = db.Column(db.String(255), unique=True)
    expires = db.Column(db.DateTime)
    _scopes = db.Column(db.Text)

    def delete(self):
        from flask import current_app as app
        session = app.db.session
        session.delete(self)
        session.commit()
        return self

    @property
    def scopes(self):
        if self._scopes:
            return self._scopes.split()
        return []
Example #11
0
class User(db.Model, Base, EntityBase):
    __tablename__ = 'user'
    id = db.Column(guid(), primary_key=True)
    username = db.Column(db.String(255), unique=True, nullable=False)
    facebook = db.Column(db.String(255))
    skype = db.Column(db.String(255))
    first_name = db.Column(db.String(255))
    last_name = db.Column(db.String(255))
    dob = db.Column(db.Integer())
    email = db.Column(db.String(255), unique=True, nullable=False)
    photo = db.Column(db.String(255))
    _password = db.Column(db.String(4000), name='password')
    about = db.Column(db.String(4000))

    @property
    def entity_type(self):
        return EntityBase.TYPE_USER

    @property
    def resource_type(self):
        from models.acl import AclResource
        return AclResource.USER

    @property
    def password(self):
        # No one should be able to find user's password
        return None

    @password.setter
    def password(self, password):
        from werkzeug.security import generate_password_hash
        self._password = generate_password_hash(password)

    def check_password(self, password):
        from werkzeug.security import check_password_hash
        return check_password_hash(self._password, password)

    def is_allowed(self, resource, privilege):
        from models.acl import acl_manager
        return acl_manager.is_allowed(self, resource, privilege)
Example #12
0
class MetaGroup(db.Model, Base):
    __tablename__ = 'sys_meta_group'
    id = db.Column(guid(), primary_key=True)

    name = db.Column(db.String(255), nullable=False, unique=True)
    description = db.Column(db.Text, nullable=False)
def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    # Insert roles
    from flask import current_app as app
    role_table = table('acl_role',
                       column('id', guid()),
                       column('name', String(255)),
                       column('parent_id', guid()))

    user_role_uuid = str(uuid.uuid4())
    owner_role_uuid = str(uuid.uuid4())
    super_user_role_uuid = str(uuid.uuid4())

    op.bulk_insert(role_table,
                   [
                       {
                           'id': user_role_uuid,
                           'name': app.config.get('DEFAULT_USER_ROLE')
                       }
                   ])

    op.bulk_insert(role_table,
                   [
                       {
                           'id': super_user_role_uuid,
                           'name': app.config.get('SUPER_USER_ROLE'),
                           'parent_id': user_role_uuid
                       },
                       {
                           'id': owner_role_uuid,
                           'name': app.config.get('OWNER_USER_ROLE'),
                           'parent_id': user_role_uuid
                       }
                   ])


    # Create users
    user_uuid = str(uuid.uuid4())
    super_user_uuid = str(uuid.uuid4())

    from werkzeug.security import generate_password_hash
    import string, random

    user_table = table('user',
                       column('id', guid()),
                       column('username', String(255)),
                       column('email', String(255)),
                       column('password', String(255))
                       )

    import os
    from colorama import Fore
    bold = '\033[1m'
    end_bold = '\033[0m'

    superuser_name = 'superuser'
    superuser_password = ''.join(random.choice(string.ascii_uppercase) for i in range(10))
    superuser_email = os.getenv('SUPERUSER_EMAIL', '*****@*****.**')

    user_name = 'normal_user'
    user_password = ''.join(random.choice(string.ascii_uppercase) for i in range(10))
    user_email = os.getenv('NORMAL_USER_EMAIL', '*****@*****.**')

    print '* Generating {2}{0}SUPER_USER{1}{3}...'.format(
        bold,  # {0}
        end_bold,  # {1}
        Fore.YELLOW,  # {2}
        Fore.RESET  # {3}
    )
    print ' - {6}Username{7}: {5}{3}{0}{4}{7}\n - {6}Password{7}: {5}{3}{1}{4}{7}\n - {6}Email{7}: {5}{3}{2}{4}{7}'.format(
        superuser_name,
        superuser_password,
        superuser_email,
        bold,  # {3}
        end_bold,  # {4}
        Fore.GREEN,  # {5}
        Fore.YELLOW,  # {6}
        Fore.RESET  # {7}
    )

    print '* Generating {2}{0}NORMAL_USER{1}{3}...'.format(
        bold,  # {0}
        end_bold,  # {1}
        Fore.YELLOW,  # {2}
        Fore.RESET  # {3}
    )

    print ' - {6}Username{7}: {5}{3}{0}{4}{7}\n - {6}Password{7}: {5}{3}{1}{4}{7}\n - {6}Email{7}: {5}{3}{2}{4}{7}'.format(
        user_name,
        user_password,
        user_email,
        bold,  # {3}
        end_bold,  # {4}
        Fore.GREEN,  # {5}
        Fore.YELLOW,  # {6}
        Fore.RESET  # {7}
    )

    op.bulk_insert(user_table,
                   [
                       {
                           'id': super_user_uuid,
                           'username': superuser_name,
                           'email': superuser_email,
                           'password': generate_password_hash(superuser_password)
                       },
                       {
                           'id': user_uuid,
                           'username': user_name,
                           'email': user_email,
                           'password': generate_password_hash(user_password)
                       }
                   ])

    # Create user_roles
    user_roles_table = table('acl_user_role',
                             column('user_id', guid()),
                             column('role_id', guid()))

    op.bulk_insert(user_roles_table,
                   [
                       {
                           'user_id': super_user_uuid,
                           'role_id': super_user_role_uuid
                       }
                   ])

    # Create roles_resources
    role_resource_table = table('acl_role_resource',
                                column('role_id', guid()),
                                column('resource_name', String(255)),
                                column('privilege', Integer),
                                column('permission', Integer))

    from models.acl import Privilege, AclResource
    from libraries.acl import Permission

    op.bulk_insert(role_resource_table,
                   [
                       {
                           'role_id': super_user_role_uuid,
                           'resource_name': '*',
                           'privilege': Privilege.ADD | Privilege.VIEW | Privilege.DELETE | Privilege.UPDATE,
                           'permission': Permission.ALLOW
                       },
                       {
                           'role_id': owner_role_uuid,
                           'resource_name': '*',
                           'privilege': Privilege.ADD | Privilege.VIEW | Privilege.DELETE | Privilege.UPDATE,
                           'permission': Permission.ALLOW
                       },
                       {
                           'role_id': user_role_uuid,
                           'resource_name': AclResource.PRODUCT,
                           'privilege': Privilege.VIEW,
                           'permission': Permission.ALLOW
                       },
                       {
                           'role_id': user_role_uuid,
                           'resource_name': AclResource.CATEGORY,
                           'privilege': Privilege.VIEW,
                           'permission': Permission.ALLOW
                       },
                       {
                           'role_id': user_role_uuid,
                           'resource_name': AclResource.USER,
                           'privilege': Privilege.VIEW,
                           'permission': Permission.ALLOW
                       }
                   ])

    pass
def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    # Insert roles
    from flask import current_app as app
    role_table = table('acl_role', column('id', guid()),
                       column('name', String(255)),
                       column('parent_id', guid()))

    user_role_uuid = str(uuid.uuid4())
    owner_role_uuid = str(uuid.uuid4())
    super_user_role_uuid = str(uuid.uuid4())

    op.bulk_insert(role_table, [{
        'id': user_role_uuid,
        'name': app.config.get('DEFAULT_USER_ROLE')
    }])

    op.bulk_insert(role_table, [{
        'id': super_user_role_uuid,
        'name': app.config.get('SUPER_USER_ROLE'),
        'parent_id': user_role_uuid
    }, {
        'id': owner_role_uuid,
        'name': app.config.get('OWNER_USER_ROLE'),
        'parent_id': user_role_uuid
    }])

    # Create users
    user_uuid = str(uuid.uuid4())
    super_user_uuid = str(uuid.uuid4())

    from werkzeug.security import generate_password_hash
    import string, random

    user_table = table('user', column('id', guid()),
                       column('username', String(255)),
                       column('email', String(255)),
                       column('password', String(255)))

    import os
    from colorama import Fore
    bold = '\033[1m'
    end_bold = '\033[0m'

    superuser_name = 'superuser'
    superuser_password = ''.join(
        random.choice(string.ascii_uppercase) for i in range(10))
    superuser_email = os.getenv('SUPERUSER_EMAIL', '*****@*****.**')

    user_name = 'normal_user'
    user_password = ''.join(
        random.choice(string.ascii_uppercase) for i in range(10))
    user_email = os.getenv('NORMAL_USER_EMAIL', '*****@*****.**')

    print '* Generating {2}{0}SUPER_USER{1}{3}...'.format(
        bold,  # {0}
        end_bold,  # {1}
        Fore.YELLOW,  # {2}
        Fore.RESET  # {3}
    )
    print ' - {6}Username{7}: {5}{3}{0}{4}{7}\n - {6}Password{7}: {5}{3}{1}{4}{7}\n - {6}Email{7}: {5}{3}{2}{4}{7}'.format(
        superuser_name,
        superuser_password,
        superuser_email,
        bold,  # {3}
        end_bold,  # {4}
        Fore.GREEN,  # {5}
        Fore.YELLOW,  # {6}
        Fore.RESET  # {7}
    )

    print '* Generating {2}{0}NORMAL_USER{1}{3}...'.format(
        bold,  # {0}
        end_bold,  # {1}
        Fore.YELLOW,  # {2}
        Fore.RESET  # {3}
    )

    print ' - {6}Username{7}: {5}{3}{0}{4}{7}\n - {6}Password{7}: {5}{3}{1}{4}{7}\n - {6}Email{7}: {5}{3}{2}{4}{7}'.format(
        user_name,
        user_password,
        user_email,
        bold,  # {3}
        end_bold,  # {4}
        Fore.GREEN,  # {5}
        Fore.YELLOW,  # {6}
        Fore.RESET  # {7}
    )

    op.bulk_insert(user_table,
                   [{
                       'id': super_user_uuid,
                       'username': superuser_name,
                       'email': superuser_email,
                       'password': generate_password_hash(superuser_password)
                   }, {
                       'id': user_uuid,
                       'username': user_name,
                       'email': user_email,
                       'password': generate_password_hash(user_password)
                   }])

    # Create user_roles
    user_roles_table = table('acl_user_role', column('user_id', guid()),
                             column('role_id', guid()))

    op.bulk_insert(user_roles_table, [{
        'user_id': super_user_uuid,
        'role_id': super_user_role_uuid
    }])

    # Create roles_resources
    role_resource_table = table('acl_role_resource', column('role_id', guid()),
                                column('resource_name', String(255)),
                                column('privilege', Integer),
                                column('permission', Integer))

    from models.acl import Privilege, AclResource
    from libraries.acl import Permission

    op.bulk_insert(role_resource_table, [{
        'role_id':
        super_user_role_uuid,
        'resource_name':
        '*',
        'privilege':
        Privilege.ADD | Privilege.VIEW | Privilege.DELETE | Privilege.UPDATE,
        'permission':
        Permission.ALLOW
    }, {
        'role_id':
        owner_role_uuid,
        'resource_name':
        '*',
        'privilege':
        Privilege.ADD | Privilege.VIEW | Privilege.DELETE | Privilege.UPDATE,
        'permission':
        Permission.ALLOW
    }, {
        'role_id': user_role_uuid,
        'resource_name': AclResource.PRODUCT,
        'privilege': Privilege.VIEW,
        'permission': Permission.ALLOW
    }, {
        'role_id': user_role_uuid,
        'resource_name': AclResource.CATEGORY,
        'privilege': Privilege.VIEW,
        'permission': Permission.ALLOW
    }, {
        'role_id': user_role_uuid,
        'resource_name': AclResource.USER,
        'privilege': Privilege.VIEW,
        'permission': Permission.ALLOW
    }])

    pass