# Path: mass_flask_core/utils/time_functions.py
# class TimeFunctions:
#     @staticmethod
#     def get_timestamp():
#         # We remove the microsecond part of the timestamp here since mongoengine can not handle it correctly and test cases fail due to the lost precision
#         return datetime.now(utc).replace(microsecond=0)
# 
# Path: mass_flask_config/app.py
# BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# SECRET_FILE = os.path.join(BASE_DIR, 'secret.txt')
# def setup_session_auth(user_loader):
# def setup_key_based_auth(key_loader):
# def unauthorized_callback():
# 
# Path: mass_flask_core/models/analysis_system_instance.py
# class AnalysisSystemInstance(db.Document, AbstractAuthEntity):
#     @property
#     def is_authenticated(self):
#         return True
# 
#     def get_roles(self):
#         return ['analysis_system_instance']
# 
#     @property
#     def max_tlp_level(self):
#         return TLPLevelField.TLP_LEVEL_WHITE
# 
#     analysis_system = ReferenceField(AnalysisSystem, required=True)
#     uuid = StringField(max_length=36, required=True, unique=True, default=_gen_uuid)
#     last_seen = DateTimeField()
# 
#     meta = {
#         'ordering': ['analysis_system', 'uuid'],
#         'indexes': [('analysis_system', 'uuid')]
#     }
# 
#     def __repr__(self):
#         return '[AnalysisSystemInstance] {} {}'.format(self.analysis_system.identifier_name, self.uuid)
# 
#     def __str__(self):
#         return self.__repr__()
# 
#     def update_last_seen(self):
#         self.last_seen = TimeFunctions.get_timestamp()
#         self.save()
# 
#     @property
#     def is_online(self):
#         if self.last_seen is None:
#             return False
# 
#         difference = TimeFunctions.get_timestamp() - self.last_seen
#         return difference < datetime.timedelta(minutes=10)
# 
# Path: mass_flask_core/models/user.py
# class User(db.Document, UserMixin):
#     def is_authenticated(self):
#         return True
# 
#     username = StringField(min_length=3, max_length=50, unique=True, required=True)
#     password_hash = StringField(min_length=5, max_length=200)
#     user_level = UserLevelField(default=UserLevel.USER_LEVEL_USER, required=True)
# 
#     def set_password(self, password):
#         self.password_hash = generate_password_hash(password)
# 
#     def check_password(self, password):
#         return check_password_hash(self.password_hash, password)
# 
#     def get_id(self):
#         return str(self.id)
# 
#     @staticmethod
#     def user_loader(**kwargs):
#         if 'username' in kwargs and 'password' in kwargs:
#             user = User.objects(username=kwargs['username']).first()
#             if user and user.check_password(kwargs['password']):
#                 return user
#             else:
#                 return None
#         elif 'id' in kwargs and kwargs['id']:
#             return User.objects(id=ObjectId(kwargs['id'])).first()
#         else:
#             raise RuntimeError('This access method is not supported by the user loader.')


from mongoengine import DateTimeField, ListField, StringField, ReferenceField
from itsdangerous import URLSafeSerializer as Serializer, BadSignature
from mass_flask_core.utils.time_functions import TimeFunctions
from mass_flask_config.app import db, app, setup_key_based_auth
from mass_flask_core.models import User, AnalysisSystemInstance

API_SCOPES = [
    'view_sample',
    'submit_sample',
]


class APIKey(db.Document):
    expiry_date = DateTimeField()
    scopes = ListField(StringField(choices=API_SCOPES))

    meta = {
        'allow_inheritance': True,
    }

    def is_expired(self):
        if self.expiry_date is not None and TimeFunctions.get_timestamp() >= self.expiry_date:
            return True
        else:
            return False

    def generate_auth_token(self):
        if self.id:

# Path: mass_flask_core/utils/time_functions.py
# class TimeFunctions:
#     @staticmethod
#     def get_timestamp():
#         # We remove the microsecond part of the timestamp here since mongoengine can not handle it correctly and test cases fail due to the lost precision
#         return datetime.now(utc).replace(microsecond=0)
# 
# Path: mass_flask_config/app.py
# BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# SECRET_FILE = os.path.join(BASE_DIR, 'secret.txt')
# def setup_session_auth(user_loader):
# def setup_key_based_auth(key_loader):
# def unauthorized_callback():
# 
# Path: mass_flask_core/models/analysis_system_instance.py
# class AnalysisSystemInstance(db.Document, AbstractAuthEntity):
#     @property
#     def is_authenticated(self):
#         return True
# 
#     def get_roles(self):
#         return ['analysis_system_instance']
# 
#     @property
#     def max_tlp_level(self):
#         return TLPLevelField.TLP_LEVEL_WHITE
# 
#     analysis_system = ReferenceField(AnalysisSystem, required=True)
#     uuid = StringField(max_length=36, required=True, unique=True, default=_gen_uuid)
#     last_seen = DateTimeField()
# 
#     meta = {
#         'ordering': ['analysis_system', 'uuid'],
#         'indexes': [('analysis_system', 'uuid')]
#     }
# 
#     def __repr__(self):
#         return '[AnalysisSystemInstance] {} {}'.format(self.analysis_system.identifier_name, self.uuid)
# 
#     def __str__(self):
#         return self.__repr__()
# 
#     def update_last_seen(self):
#         self.last_seen = TimeFunctions.get_timestamp()
#         self.save()
# 
#     @property
#     def is_online(self):
#         if self.last_seen is None:
#             return False
# 
#         difference = TimeFunctions.get_timestamp() - self.last_seen
#         return difference < datetime.timedelta(minutes=10)
# 
# Path: mass_flask_core/models/user.py
# class User(db.Document, UserMixin):
#     def is_authenticated(self):
#         return True
# 
#     username = StringField(min_length=3, max_length=50, unique=True, required=True)
#     password_hash = StringField(min_length=5, max_length=200)
#     user_level = UserLevelField(default=UserLevel.USER_LEVEL_USER, required=True)
# 
#     def set_password(self, password):
#         self.password_hash = generate_password_hash(password)
# 
#     def check_password(self, password):
#         return check_password_hash(self.password_hash, password)
# 
#     def get_id(self):
#         return str(self.id)
# 
#     @staticmethod
#     def user_loader(**kwargs):
#         if 'username' in kwargs and 'password' in kwargs:
#             user = User.objects(username=kwargs['username']).first()
#             if user and user.check_password(kwargs['password']):
#                 return user
#             else:
#                 return None
#         elif 'id' in kwargs and kwargs['id']:
#             return User.objects(id=ObjectId(kwargs['id'])).first()
#         else:
#             raise RuntimeError('This access method is not supported by the user loader.')


# Path: mass_flask_core/models/api_key.py
from mongoengine import DateTimeField, ListField, StringField, ReferenceField
from itsdangerous import URLSafeSerializer as Serializer, BadSignature
from mass_flask_core.utils.time_functions import TimeFunctions
from mass_flask_config.app import db, app, setup_key_based_auth
from mass_flask_core.models import User, AnalysisSystemInstance


API_SCOPES = [
    'view_sample',
    'submit_sample',
]


class APIKey(db.Document):
    expiry_date = DateTimeField()
    scopes = ListField(StringField(choices=API_SCOPES))

    meta = {
        'allow_inheritance': True,
    }

    def is_expired(self):
        if self.expiry_date is not None and TimeFunctions.get_timestamp() >= self.expiry_date:
            return True
        else:
            return False

    def generate_auth_token(self):
        if self.id:

            s = Serializer(app.secret_key)