class BlacklistedToken(db.Model): __tablename__ = "token_blacklist" # Property Declaration id = db.Column(db.Integer, primary_key=True, autoincrement=True) token = db.Column(db.String(500), unique=True, nullable=False) blacklisted_on = db.Column(db.DateTime, default=db.func.now()) # Initialize Token def __init__(self, token): """ Constructor for BlackListedToken Model Class. """ self.token = token def __repr__(self): """ Official way of representing BlackListedToken Instance. """ return f"<BlacklistToken token={self.token} >" @classmethod def check_blacklist(cls, token): """ Returns True if token already exists in blacklisted_token. """ exists = cls.query.filter_by(token=token).first() return True if exists else False
class Case(UserMixin, db.Model): __tablename__ = "case" # Propertry Declaration id = db.Column(db.Integer, primary_key=True) case_name = db.Column(db.String(100), unique=True) data_size = db.Column(db.String(100), default="none") extracted_on = db.Column(db.DateTime, default=db.func.now()) extractor_id = db.Column(db.Integer, db.ForeignKey("extractor.id")) data_path = db.Column(db.String(100)) device_id = db.Column(db.String(100)) # Initalize Properties def __init__(self, case_name, device_id, data_path, extractor): self.case_name = case_name self.device_id = device_id self.extractor = extractor self.data_path = data_path def __repr__(self): """ Official way of representing Case Object. """ return f"<Case case_name={self.case_name} extractor={self.extractor.email}>"
class Admin(BaseUser): __tablename__="admin" # Properties Declaration id = db.Column(db.Integer, unique=True, primary_key=True) role = db.Column(db.String(255), default="admin") extractor_members = db.relationship("Extractor", backref="admin", cascade="all, delete, delete-orphan", lazy=True) management_members = db.relationship("Management", backref="admin", cascade="all, delete, delete-orphan", lazy=True) assigned_tasks = db.relationship("Task", backref="admin", cascade="all, delete, delete-orphan", lazy=True) def __init__(self, name, email, password): """ Constructor for admin uesr model. """ super().__init__(name, email,password) def __repr__(self): """ Official way of representing admin user in db. """ return ( f"<Admin email={self.email}, public_id={self.public_id}>" )
class Management(BaseUser): __tablename__ = "management" # Property Declaration id = db.Column(db.Integer, unique=True, primary_key=True) role = db.Column(db.String(255), default="management") admin_id = db.Column(db.Integer, db.ForeignKey("admin.id")) assigned_tasks = db.relationship("Task", backref="management", lazy=True) def __init__(self, name, email, password, admin, role="management"): """ Constructor for management user model. """ super().__init__(name, email, password) self.admin = admin self.role = role def __repr__(self): """ Official way of representing management user in db. """ return ( f"<Management email={self.email}, public_id={self.public_id}, admin_email={self.admin.email}>" )
class Task(db.Model): __tablename__="task" # Property Declaration id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(255), nullable=False) description = db.Column(db.Text, nullable=False) assinged_on = db.Column(db.DateTime, nullable=False, default=db.func.now()) due_on = db.Column(db.DateTime, nullable=True) admin_id = db.Column(db.Integer, db.ForeignKey("admin.id"), nullable=False) is_completed = db.Column(db.Boolean, default=False) extractor_id = db.Column(db.Integer, db.ForeignKey("extractor.id"), nullable=True) management_id = db.Column(db.Integer, db.ForeignKey("management.id"), nullable=True) def __init__(self, title, admin, extractor=None, management=None,description=None, due_on=None): """ Initializing columns. """ self.title = title self.admin = admin self.due_on = due_on if due_on != None else (dt.date.today() + dt.timedelta(days=7)) self.description = description if description != None else "Not Given" if extractor and management: raise AttributeError("Can't assign one task to extractor and management member.") elif extractor: self.extractor = extractor elif management: self.management = management else: raise AttributeError("Please select one member.") def __repr__(self): """ Official way of representing task object. """ return f"<Task title={self.title}, admin={self.admin.email}>"
class BaseUser(db.Model): """ Class definition for Base User Model.""" __abstract__ = True # Properties Declaration name = db.Column(db.String(255), nullable=False, unique=False) email = db.Column(db.String(255), nullable=False, unique=True) password_hash = db.Column(db.String(255), nullable=False) verified = db.Column(db.Boolean, default=False) created_on = db.Column(db.DateTime, default=db.func.now()) updated_on = db.Column(db.DateTime, default=db.func.now(), onupdate=db.func.now()) public_id = db.Column(db.String(255), nullable=False, default=lambda: str(uuid4())) def __init__(self, name, email, password): """ Constructor for base user model. """ self.name = name self.email = email self.password = password @property def password(self): """ Write only password field. """ raise AttributeError("Password: write only access.") @password.setter def password(self, password): """ Storing password as password_hash. """ log_rounds = current_app.config.get("BCRYPT_LOG_ROUNDS") hash_bytes = bcrypt.generate_password_hash(password, log_rounds) self.password_hash = hash_bytes.decode("utf-8") def check_password(self, password): """ Comparing pasword with password_hash. """ return bcrypt.check_password_hash(self.password_hash, password) def __repr__(self): """ Official way of representing user in db. """ return (f"<User email={self.email}, public_id={self.public_id}") # Class Method for searching in Admin Class @classmethod def find_by_email(cls, email): return cls.query.filter_by(email=email).first() @classmethod def find_by_id(cls, id): return cls.query.get(id) @classmethod def find_by_pubic_id(cls, public_id): return cls.query.filter_by(public_id=public_id) # Methods for encoding and Decoding def encode_access_token(self): """ Generating jwt access tokens. """ # Token Properties now = datetime.now(timezone.utc) token_age_h = current_app.config.get("TOKEN_EXPIRE_HOURS") token_age_min = current_app.config.get("TOKEN_EXPIRE_MINUTES") expires = now + timedelta(hours=token_age_h, minutes=token_age_min) # Check for TESTING environment if current_app.config.get("TESIING"): expires = now + timedelta(seconds=5) # Create Payload payload = dict(exp=expires, iat=now, sub=self.public_id, role=self.role) # Get secret key key = current_app.config.get("SECRET_KEY") # Return encoded user return jwt.encode(payload, key, algorithm="HS256") @staticmethod def decode_access_token(access_token): """ Decodes the access token. """ # Check for token type if isinstance(access_token, bytes): access_token = access_token.decode("ascii") # Check for Bearer if access_token.startswith("Bearer"): split = access_token.split("Bearer") access_token = split[1].strip() try: key = current_app.config.get("SECRET_KEY") payload = jwt.decode(access_token, key, algorithms="HS256") # Handle Errors except jwt.ExpiredSignatureError: error = "Access token expired, Please login again." return Result.Fail(error_message=error) except jwt.InvalidTokenError: error = "Invalid token. Please log in again." return Result.Fail(error_message=error) if BlacklistedToken.check_blacklist(access_token): error = "Token blacklisted. Please try to log in again." return Result.Fail(error_message=error) # Following keys would be accessible # to decorated functinos user_dict = dict( public_id=payload["sub"], role=payload["role"], token=access_token, expires_at=payload["exp"], ) return Result.Ok(value=user_dict)