class BucketList(Base): ''' This is the one stop data place for a single bucketlist. ''' created_by = db.Column(db.Integer, db.ForeignKey('user.id')) name = db.Column(db.String(256)) items = db.relationship('BucketListItem', backref=db.backref('bucket_list', lazy='joined'), cascade='all, delete-orphan', lazy='dynamic') def __init__(self, bucketlistname, created_by): self.name = bucketlistname self.created_by = created_by def as_dict(self): # render the bucketlists items = [item.as_dict() for item in self.items.all()] return OrderedDict([('id', str(self.id)), ('name', str(self.name)), ('items', items), ('date_created', str(self.date_created)), ('date_modified', str(self.date_modified)), ('created_by', str(self.created_by))]) def __repr__(self): return '<BucketList {}>'.format(self.name)
class BaseModel(db.Model): """The base model for implementing features common to all the models. Inherits: db.Model Attributes: id: [int] id single model in the database date_created: [datetime] date function was created """ __abstract__ = True id = db.Column(db.Integer, primary_key=True) date_created = db.Column(db.DateTime, default=db.func.now()) def update(self, commit=True, **kwargs): """Update specific fields of a record.""" # Prevent changing ID of object kwargs.pop('id', None) for attr, value in kwargs.items(): if value is not None: setattr(self, attr, value) return commit and self.save() or self def save(self, commit=True): """Save the record.""" db.session.add(self) if commit: db.session.commit() return self def delete(self, commit=True): """Remove the record from the database.""" db.session.delete(self) return commit and db.session.commit()
class BucketListItem(BucketListModel): """Provides the database Model for the items on the BucketList Items. Inherits: BucketListModel Attributes: bucketlist_id: [int] it of the bucketlist it belongs to done: [Boolean] """ __tablename__ = 'items' done = db.Column(db.Boolean, default=False) bucketlist_id = db.Column(db.Integer, db.ForeignKey('bucketlist.id'))
class Base(db.Model): ''' Base class for the models. Contains common data to The User, Bucketlist and Bucketlist Item id: primary key date created: date object was created sample format "2017-04-14 10:10:58" date modified: date object was modified sample format "2017-04-14 11:10:58" ''' __abstract__ = True id = db.Column(db.Integer, primary_key=True) date_created = db.Column(db.DateTime(timezone=True), default=db.func.current_timestamp()) date_modified = db.Column(db.DateTime(timezone=True), default=db.func.current_timestamp(), onupdate=db.func.current_timestamp())
class User(Base): ''' This model holds data for a single User. The user ID, Username and Password_Hash used for verification. ''' username = db.Column(db.String(256), nullable=False, unique=True) password_hash = db.Column(db.String(256), nullable=False) bucketlists = db.relationship('BucketList', backref=db.backref('user', lazy='joined'), cascade='all, delete-orphan', lazy='dynamic') def __init__(self, username, password): self.username = username self.password = password def hash_password(self): # generate a hash for the password self.password_hash = pwd_context.encrypt(self.password) return self.password_hash def verify_password(self, password): # check password hash matches password. return pwd_context.verify(password, self.password_hash) def generate_auth_token(self, expiration=86400): # generate an auth token that lasts for a day. s = Serializer(app.config['SECRET_KEY'], expires_in=expiration) return s.dumps({'id': self.id}) @staticmethod def verify_auth_token(token): # check token to ascertain validity s = Serializer(app.config['SECRET_KEY']) try: data = s.loads(token) except BadSignature: raise ValueError # invalid token except SignatureExpired: return None return User.query.get(data['id']) def as_dict(self): return "Hello your username is {} ".format(self.username) def __repr__(self): return {"username": self.username}
class BucketListModel(BaseModel): """Base class for bucketlist item. Inherits: BaseModel Attributes: name: [string] the title of the Item date_modified: [datetime] The last modified date """ __abstract__ = True name = db.Column(db.String(50), nullable=False) date_modified = db.Column(db.DateTime, default=db.func.now()) def save(self, commit=True): self.date_modified = db.func.now() super(BucketListModel, self).save()
class BucketList(BucketListModel): """Provides the database Model for the BucketList. Attributes: is_public: [Boolean] Is availability to the user user_id: [int] the foreign key user id item: [Model Fk] The bucketlist-item relationship Inherits: BucketListModel """ __tablename__ = 'bucketlist' is_public = db.Column(db.Boolean, default=False) user_id = db.Column(db.Integer, db.ForeignKey('users.id')) items = db.relationship('BucketListItem', backref='bucketlist', cascade="all, delete", lazy='dynamic')
class BucketListItem(Base): ''' This is the data center for a single item in the bucket list ''' done = db.Column(db.Boolean, default=False) name = db.Column(db.String(256)) bucketlist_id = db.Column(db.Integer, db.ForeignKey('bucket_list.id')) def __init__(self, item_name, bucketlist_id): self.name = item_name self.bucketlist_id = bucketlist_id def as_dict(self): return { col.name: str(getattr(self, col.name)) for col in self.__table__.columns if col.name != 'bucketlist_id' } def __repr__(self): return '<BucketListItem {}>'.format(self.name)
class User(BaseModel): """Provides the database Model for Users. Inherits: BaseModel Attributes: username: [String] username of the user password_hash: [String] Hashed version of the user password bucketlists: [Model Fk] ForeignKey relationship between User and BucketList """ __tablename__ = 'users' username = db.Column(db.String(50), nullable=False) password_hash = db.Column(db.String(70)) bucketlists = db.relationship('BucketList', backref='user', cascade="all, delete", lazy='dynamic') def __init__(self, username, password, **kwargs): super(User, self).__init__(username=username, **kwargs) self.set_password(password) def set_password(self, password): """Encrypt the User password. Arguments: password: [String] string Representing the User password """ self.password_hash = pwd_context.encrypt(password) def verify_password(self, password): """Verify input password with the Hashed password. Arguments: password: [String] string Representing the User password Return: Boolean. Representing the status of the password check """ return pwd_context.verify(password, self.password_hash) def generate_auth_token(self, expiration=20000): """Generate Authentication Token. Arguments: expiration: [Int] The token expiry time in second Return: Token: [String] The generated token """ s = Serializer(app.config['SECRET_KEY'], expires_in=expiration) return s.dumps({'id': self.id}) @staticmethod def verify_token(token): """Verify the State of the Token. Check if the token is valid and hasn't exipred Arguments: token: [String] Return: user [Model] User Model containing the user information """ s = Serializer(app.config['SECRET_KEY']) try: data = s.loads(token) except SignatureExpired: return None except BadSignature: return None user = User.query.get(data['id']) return user @staticmethod def get_user(username, password): """Get the user with specified username. Arguments: username: [string] username of the user to get_user password: [string] a valid password of that user Return: user [Model] User Model containing the user information """ user = User.query.filter_by(username=username).first() if user is None or not user.verify_password(password): return None return user @staticmethod def user_exist(username): """Verify if a user already exist in the Database. Arguments: token: [string] Return: [Boolean] Representing the status of the user existence """ if User.query.filter_by(username=username).first(): return True return False