# Path: m2core/data_schemes/db_system_scheme.py
# class CreatedMixin:
# class SortMixin:
# class M2PermissionCheckMixin:
# class M2Permission(BaseModel):
# class M2Role(BaseModel):
# class M2RolePermission(BaseModel):
# class M2UserMixin:
# class M2UserRole(BaseModel):
#     def can(self, permission_rule: Permission) -> bool:
#     def enum_member(self):
#     def from_enum_member(cls, member: Permission):
#     def get_role_permissions(self) -> List[str]:
#     def dump_role_permissions(self):
#     def set_permissions(self, permissions: list):
#     def add_permission(self, permission_system_name: str):


from sqlalchemy import Column, BigInteger, Integer, String, func
from m2core.data_schemes.db_system_scheme import M2UserRole, M2Role, M2Error, BaseModel, CreatedMixin
import bcrypt
    name = Column(String(255), info={'custom_param_for_json_scheme_1': '11111', 'custom_param_for_json_scheme_2': True})
    gender = Column(Integer, nullable=False)

    @classmethod
    def authorize(cls, _email: str, _password: str) -> dict or None:
        """
        Authorize user and save his access token to Redis
        :param _email: user email
        :param _password: user password
        """
        user_obj = cls.q.filter(
            func.lower(cls.email) == _email.lower(),
            # cls.password == func.crypt(_password, cls.password)  <- this could be used for check in DB
        ).first()
        if not user_obj:
            return None

        # check authorization via python bcrypt, not postgres bcrypt
        if not bcrypt.checkpw(str.encode(_password), str.encode(user_obj.get('password'))):
            return None

        access_token = cls.sh.generate_token(user_obj.get('id'))
        access_token['user_info'] = user_obj.data('password')
        return access_token

    def add_role(self, _role_name: str):
        """
        Adds new role for user. User can have unlimited number of roles. If he already has this role - do nothing
        :param _role_name: role name
        """

# Path: m2core/data_schemes/db_system_scheme.py
# class CreatedMixin:
# class SortMixin:
# class M2PermissionCheckMixin:
# class M2Permission(BaseModel):
# class M2Role(BaseModel):
# class M2RolePermission(BaseModel):
# class M2UserMixin:
# class M2UserRole(BaseModel):
#     def can(self, permission_rule: Permission) -> bool:
#     def enum_member(self):
#     def from_enum_member(cls, member: Permission):
#     def get_role_permissions(self) -> List[str]:
#     def dump_role_permissions(self):
#     def set_permissions(self, permissions: list):
#     def add_permission(self, permission_system_name: str):


# Path: example/models/users.py
from sqlalchemy import Column, BigInteger, Integer, String, func
from m2core.data_schemes.db_system_scheme import M2UserRole, M2Role, M2Error, BaseModel, CreatedMixin
import bcrypt

    name = Column(String(255), info={'custom_param_for_json_scheme_1': '11111', 'custom_param_for_json_scheme_2': True})
    gender = Column(Integer, nullable=False)

    @classmethod
    def authorize(cls, _email: str, _password: str) -> dict or None:
        """
        Authorize user and save his access token to Redis
        :param _email: user email
        :param _password: user password
        """
        user_obj = cls.q.filter(
            func.lower(cls.email) == _email.lower(),
            # cls.password == func.crypt(_password, cls.password)  <- this could be used for check in DB
        ).first()
        if not user_obj:
            return None

        # check authorization via python bcrypt, not postgres bcrypt
        if not bcrypt.checkpw(str.encode(_password), str.encode(user_obj.get('password'))):
            return None

        access_token = cls.sh.generate_token(user_obj.get('id'))
        access_token['user_info'] = user_obj.data('password')
        return access_token

    def add_role(self, _role_name: str):
        """
        Adds new role for user. User can have unlimited number of roles. If he already has this role - do nothing
        :param _role_name: role name
        """

        role = M2Role.load_by_params(name=_role_name)