class Issue(db.Model): """Issues table in the database.""" __tablename__ = 'issues' id = db.Column(db.Integer, primary_key=True) title = db.Column(db.Text) user_id = db.Column(db.ForeignKey(u'users.id'), index=True) category_id = db.Column(db.ForeignKey(u'category.id'), nullable=False, index=True) location_lat = db.Column(db.Float) location_lon = db.Column(db.Float) status = db.Column(db.Text) description = db.Column(db.Text) open_date = db.Column(db.TIMESTAMP(timezone=True)) close_date = db.Column(db.TIMESTAMP(timezone=True)) delete_date = db.Column(db.TIMESTAMP(timezone=True)) category = db.relationship(u'Category') user = db.relationship(u'User') def delete(self): """Setting deleting date for issue""" if not self.delete_date: self.delete_date = func.current_timestamp() return True return False def restore(self): """Restoring issue from deletion""" if self.delete_date: self.delete_date = None return True return False
class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(255), unique=True, nullable=False) email = db.Column(db.String(255), unique=True, nullable=False) password = db.Column(PasswordType(schemes=[ 'sha256_crypt', ])) created_at = db.Column(db.DateTime, default=datetime.utcnow) updated_at = db.Column(db.DateTime, default=datetime.utcnow) password_changed_at = db.Column(db.DateTime) identities = db.relationship('Identity', backref='user', lazy='dynamic') sessions = db.relationship('Session', backref='user', lazy='dynamic') @classmethod def find_by_email_or_username(cls, username): return (User.query.filter((User.email == username) | (User.username == username)).first()) def change_password(self, password): self.password = password self.password_changed_at = datetime.utcnow()
class SqlQuery(db.Model): id = db.Column(db.Integer, primary_key=True) label = db.Column(db.String(64), index=True, unique=True) raw_sql = db.Column(db.Text) creator_user_id = db.Column(db.Integer, db.ForeignKey('user.id'), index=True, nullable=False) charts = db.relationship('Chart', backref='sql_query', lazy='dynamic') usergroups = db.relationship("Usergroup", secondary=query_perms, backref="queries") @validates('label') def validate_label(self, key, label): if not label: raise AssertionError('No label provided') if Usergroup.query.filter( func.lower(Usergroup.label) == func.lower(label)).first(): raise AssertionError('Provided label is already in use') return label @validates('raw_sql') def validate_raw_sql(self, key, raw_sql): if not raw_sql: raise AssertionError('No raw_sql provided') if not isinstance(raw_sql, str): raise AssertionError('raw_sql must be a string') return raw_sql @validates('usergroups') def validate_usergroups(self, key, usergroups): if not isinstance(usergroups, Usergroup): raise AssertionError('Provided usergroup is not recognized') return usergroups def get_dict(self): dict_format = { 'query_id': self.id, 'label': self.label, 'raw_sql': self.raw_sql, 'creator': self.creator.get_dict(), } return dict_format def get_usergroups(self): usergroups = helpers.get_dicts_from_usergroups(self.usergroups) return usergroups def get_authorized_users(self): users = dict(users=helpers.get_users_from_usergroups(self.usergroups)) return users def __repr__(self): return '<SqlQuery {}:{}'.format(self.id, self.label)
class IssueHistory(db.Model): """IssueHistory table in the database.""" __tablename__ = 'issue_History' id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.ForeignKey(u'users.id')) issue_id = db.Column(db.ForeignKey(u'issues.id'), index=True) status_id = db.Column(db.ForeignKey(u'statuses.id'), index=True) transaction_date = db.Column(db.TIMESTAMP(timezone=True)) issue = db.relationship(u'Issue') status = db.relationship(u'Status') user = db.relationship(u'User')
class Label(db.Model): __tablename__ = 'labels' label_id = db.Column(db.String(32), primary_key=True) user_id = db.Column(db.String(32), db.ForeignKey('users.user_id')) songs = db.relationship('Song', backref='label') label_name = db.Column(db.String(50), nullable=False)
class Activity(BaseModel, db.Model): """Model for Activity table""" __tablename__ = "Activities" id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(128), nullable=False) type_ = db.Column(db.String(128), nullable=False) start_time = db.Column(db.DateTime, nullable=False) finished_time = db.Column(db.DateTime, nullable=True) state = db.Column(db.String, nullable=False) result = db.Column(db.String, nullable=True) logs = db.relationship('Log', back_populates='activity', lazy=True, cascade="all, delete", passive_deletes=False) def __init__(self, name, type_, start_time, finished_time, state, result): super().__init__() self.name = name self.type_ = type_ self.start_time = start_time self.finished_time = finished_time self.state = state self.result = result
class Attachment(db.Model): """Attachment table in the database.""" __tablename__ = 'attachments' id = db.Column(db.Integer, primary_key=True) issue_id = db.Column(db.ForeignKey(u'issues.id'), index=True) image_url = db.Column(db.Text) issue = db.relationship(u'Issue') def get_thumbnail_url(self): head, tail = os.path.split(self.image_url) thumb_name = "thumb-{}".format(tail) return "{}/{}".format(head, thumb_name) def delete(self): db.session.delete(self) db.session.commit() delete_file(self.image_url) delete_file(self.get_thumbnail_url()) directory_path = os.path.abspath( os.path.join(current_app.config['MEDIA_FOLDER'], self.image_url, os.pardir)) if os.path.exists(directory_path) and not os.listdir(directory_path): os.rmdir(directory_path) def get_full_thumbnail_url(self): url = self.get_thumbnail_url() if current_app.config.get('MEDIA_URL'): return current_app.config['MEDIA_URL'] + url return '/media/' + url
class User(UserMixin, db.Model): __tablename__ = 'user' # attributes id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(50), nullable=False) phoneNumber = db.Column(db.String(10), nullable=False, unique=True) # Relationships tkt = db.relationship('Ticket', backref=db.backref('tickets', lazy=True))
class User(db.Model): __tablename__ = 'users' user_id = db.Column(db.String(32), primary_key=True) email = db.Column(db.String(80), unique=True, nullable=False) name = db.Column(db.String(50), nullable=False) password = db.Column(db.String(80), nullable=False) created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) labels = db.relationship('Label', backref='owner')
class MovieShow(db.Model): __tablename__ = 'movieShow' # attributes timing = db.Column(db.DateTime, primary_key=True, unique=True, nullable=False) number_of_tickets = db.Column(db.Integer, default=20) # Relationships time = db.relationship('Ticket', cascade="save-update", backref=db.backref('time', lazy=True))
class Comments(db.Model): """ Issues table in the database. """ __tablename__ = 'comments' id = db.Column(db.Integer, primary_key=True) comment = db.Column(db.Text) date_public = db.Column(db.TIMESTAMP(timezone=True)) user_id = db.Column(db.ForeignKey(u'users.id')) issue_id = db.Column(db.ForeignKey(u'issues.id'), index=True) status = db.Column(db.Text) pre_deletion_status = db.Column(db.Text) issue = db.relationship(u'Issue') user = db.relationship(u'User') class Meta: """...""" app_label = 'city_issues' managed = False db_table = 'comments'
class Log(BaseModel, db.Model): """Model for Log table""" __tablename__ = "Logs" id = db.Column(db.Integer, primary_key=True, autoincrement=True) timestamp = db.Column(db.String, nullable="False") log_message = db.Column(db.String, nullable="False") type_ = db.Column(db.String(20), nullable="False") activity_id = db.Column(db.Integer, db.ForeignKey('Activities.id', ondelete="CASCADE"), nullable=False) activity = db.relationship("Activity", back_populates="logs") def __init__(self, timestamp, log_message, type_, activity_id): super().__init__() self.timestamp = timestamp self.log_message = log_message self.type_ = type_ self.activity_id = activity_id
class User(db.Model): """User table in the database""" ROLE_ADMIN = 1 ROLE_MODERATOR = 2 ROLE_USER = 3 __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.Text) alias = db.Column(db.Text) email = db.Column(db.Text) hashed_password = db.Column(db.Text) role_id = db.Column(db.ForeignKey(u'roles.id'), index=True) avatar = db.Column(db.Text) delete_date = db.Column(db.TIMESTAMP) last_login = db.Column(db.TIMESTAMP) role = db.relationship(u'Role') @hybrid_property def password(self): """Getting the password.""" return self.hashed_password @password.setter def password(self, raw_password): """Hashing password before being stored.""" self.hashed_password = django_bcrypt.hash(raw_password) def check_password(self, raw_password): """Checking the password form database.""" return django_bcrypt.verify(raw_password, self.hashed_password) # pylint: disable=no-self-use # This needs to be checked because no self is used in function def is_last_admin(self): """Looking for the last admin""" count = User.query.filter_by(role_id=User.ROLE_ADMIN, delete_date=None).count() if count > 1: return False return True def delete(self): """Setting deleting date for user""" if self.role_id == User.ROLE_ADMIN: if not self.is_last_admin(): self.delete_date = func.current_timestamp() return True else: self.delete_date = func.current_timestamp() return True return False def restore(self): """Restoring user from deletion""" if self.delete_date: self.delete_date = None return True return False
class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), index=True, unique=True, nullable=False) email = db.Column(db.String(120), index=True, nullable=False) password_hash = db.Column(db.String(128)) role = db.Column(db.Enum('viewer', 'writer', 'admin', 'superuser', name='user_roles'), default='viewer') is_active = db.Column(db.Boolean, default=True, nullable=False) connections = db.relationship('Connection', backref='creator', lazy='dynamic') queries = db.relationship('SqlQuery', backref='creator', lazy='dynamic') charts = db.relationship('Chart', backref='creator', lazy='dynamic') reports = db.relationship('Report', backref='creator', lazy='dynamic') publications = db.relationship('Publication', backref='creator', lazy='dynamic') contacts = db.relationship('Contact', backref='creator', lazy='dynamic') usergroups = db.relationship("Usergroup", secondary=user_perms, backref="members", cascade="save-update, merge") @validates('username') def validate_username(self, key, username): if not username: raise AssertionError('No username provided') is_string = isinstance(username, str) is_unique = not User.query.filter(User.username == username).first() is_only_numbers_and_letters = re.match("^[a-zA-Z0-9_]+$", username) is_more_than_5_characters = len(username) >= 5 is_less_than_40_characters = len(username) <= 40 if not is_string: raise AssertionError('Provided username is invalid') if not is_unique: raise AssertionError('Provided username is already in use') if not is_only_numbers_and_letters: raise AssertionError( 'Usernames may only contain letters, numbers, and underscores') if not is_more_than_5_characters: raise AssertionError('Username must be 5 or more characters') if not is_less_than_40_characters: raise AssertionError('Usernames may only be 40 characters or less') return username @validates('email') def validate_email(self, key, email): if not email: raise AssertionError('No email provided') if not re.match("[^@]+@[^@]+\.[^@]+", email): raise AssertionError('Provided email is not an email address') return email @validates('role') def validate_role(self, key, role): if role not in ('viewer', 'writer', 'admin'): AssertionError('Provided role is not recognized') return role @validates('usergroups') def validate_usergroups(self, key, usergroups): if not isinstance(usergroups, Usergroup): raise AssertionError('Provided usergroup is not recognized') return usergroups def get_dict(self): dict_format = { "user_id": self.id, "username": self.username, "email": self.email, "role": self.role, "usergroups": self.get_dicts_from_usergroups() } return dict_format def set_password(self, password): if not password: raise AssertionError('Password not provided') if not re.match('\d.*[A-Z]|[A-Z].*\d', password): raise AssertionError( 'Password must contain 1 capital letter and 1 number') if len(password) < 8 or len(password) > 50: raise AssertionError( 'Password must be between 8 and 50 characters') self.password_hash = generate_password_hash(password) def check_password(self, password): return check_password_hash(self.password_hash, password) # returns list of usergroup ids def get_usergroup_ids(self): ug_tuple_list = db.session.query(user_perms).filter( user_perms.c.user_id == self.id).all() return list(map(lambda tup: tup[1], ug_tuple_list)) # takes table, returns list of ids def get_authorized_ids(self, table): usergroup_ids = self.get_usergroup_ids() conn_tuple_list = db.session.query(table).filter( table.c.usergroup_id.in_(usergroup_ids)).all() return list(set(map(lambda tup: tup[1], conn_tuple_list))) # returns list of usergroup dictionaries def get_dicts_from_usergroups(self): usergroup_ids = self.get_usergroup_ids() usergroup_objects_list = Usergroup.query.filter( Usergroup.id.in_(usergroup_ids)).all() return list( map(lambda obj: { 'id': obj.id, 'label': obj.label, }, usergroup_objects_list)) # returns list of connection dictionaries def get_connections(self): connection_ids = self.get_authorized_ids(connection_perms) connection_objects_list = Connection.query.filter( Connection.id.in_(connection_ids)).all() return list(map(lambda obj: obj.get_dict(), connection_objects_list)) # returns list of query dictionaries def get_queries(self): query_ids = self.get_authorized_ids(query_perms) query_objects_list = SqlQuery.query.filter( SqlQuery.id.in_(query_ids)).all() return list(map(lambda obj: obj.get_dict(), query_objects_list)) # returns list of chart dictionaries def get_charts(self): chart_ids = self.get_authorized_ids(chart_perms) chart_objects_list = db.session.query(Chart).filter( Chart.id.in_(chart_ids)).all() return list(map(lambda obj: obj.get_dict(), chart_objects_list)) # returns list of report dictionaries def get_reports(self): report_ids = self.get_authorized_ids(report_perms) report_objects_list = Report.query.filter( Report.id.in_(report_ids)).all() return list(map(lambda obj: obj.get_dict(), report_objects_list)) # returns list of contact dictionaries def get_contacts(self): public_contacts = Contact.query.filter(Contact.public).all() created_contacts = Contact.query.filter( Contact.creator_user_id == self.id).all() return list( map(lambda obj: obj.get_dict(), public_contacts + created_contacts)) def __repr__(self): return '<User {}>'.format(self.username) # returns personal usergroup def get_personal_usergroup(self): usergroup = Usergroup.query.filter( Usergroup.label == self.username).first() return usergroup
class Connection(db.Model): id = db.Column(db.Integer, primary_key=True) label = db.Column(db.String(64), index=True, unique=True, nullable=False) db_type = db.Column(db.String(64)) host = db.Column(db.String(256)) port = db.Column(db.Integer) username = db.Column(db.String(128)) password = db.Column(db.String(128)) database_name = db.Column(db.String(256)) charts = db.relationship('Chart', backref='chart_connection', lazy='dynamic') creator_user_id = db.Column(db.Integer, db.ForeignKey('user.id'), index=True, nullable=False) usergroups = db.relationship("Usergroup", secondary=connection_perms, backref="connections") @validates('label') def validate_label(self, key, label): if not label: raise AssertionError('No label provided') if not isinstance(label, str): raise AssertionError('Label must be string') if Usergroup.query.filter( func.lower(Usergroup.label) == func.lower(label)).first(): raise AssertionError('Provided label is already in use') return label.lower() @validates('db_type') def validate_db_type(self, key, db_type): if not db_type: raise AssertionError('No db_type provided') if not isinstance(db_type, str): raise AssertionError('Provided db_type not valid') return db_type @validates('host') def validate_host(self, key, host): if not host: raise AssertionError('No host provided') if not isinstance(host, str): raise AssertionError('Provided host not valid') return host @validates('port') def validate_host(self, key, port): if not port: raise AssertionError('No port provided') if not isinstance(port, (str, int)): raise AssertionError('Provided port not valid') return port @validates('username') def validate_username(self, key, username): if not username: raise AssertionError('No username provided') if not isinstance(username, str): raise AssertionError('Provided username not valid') return username @validates('password') def validate_password(self, key, password): if not password: raise AssertionError('No password provided') if not isinstance(password, str): raise AssertionError('Provided password not valid') return encrypt_with_aws(password) @validates('database_name') def validate_database_name(self, key, database_name): if not database_name: raise AssertionError('No database_name provided') if not isinstance(database_name, str): raise AssertionError('Provided database name not valid') return database_name @validates('creator') def validate_creator(self, key, creator): if not isinstance(creator, User): raise AssertionError('Provided creator is not recognized') return creator @validates('usergroups') def validate_usergroups(self, key, usergroups): if not isinstance(usergroups, Usergroup): raise AssertionError('Provided usergroup is not recognized') return usergroups def get_dict(self): dict_format = { 'connection_id': self.id, 'label': self.label, 'db_type': self.db_type, 'host': self.host, 'port': self.port, 'username': self.username, 'password': decrypt_with_aws(self.password) if self.password else self.password, 'db_name': self.database_name, 'creator': self.creator.get_dict(), } return dict_format def get_usergroups(self): usergroups = helpers.get_dicts_from_usergroups(self.usergroups) return usergroups def get_authorized_users(self): users = helpers.get_users_from_usergroups(self.usergroups) return users def __repr__(self): return '<Connection label: {}>'.format(self.label)
class Chart(db.Model): id = db.Column(db.Integer, primary_key=True) label = db.Column(db.String(64), index=True, unique=True) type = db.Column(db.String(128)) parameters = db.Column(db.Text) creator_user_id = db.Column(db.Integer, db.ForeignKey('user.id'), index=True) sql_query_id = db.Column(db.Integer, db.ForeignKey('sql_query.id')) connection_id = db.Column(db.Integer, db.ForeignKey('connection.id')) usergroups = db.relationship("Usergroup", secondary=chart_perms, backref="charts") @validates('label') def validate_label(self, key, label): if not label: raise AssertionError('No label provided') if Usergroup.query.filter( func.lower(Usergroup.label) == func.lower(label)).first(): raise AssertionError('Provided label is already in use') return label @validates('type') def validate_type(self, key, type): if not type: raise AssertionError('No chart type provided') if not isinstance(type, str): raise AssertionError('chart type must be a string') return type @validates('parameters') def validate_parameters(self, key, parameters): if not parameters: raise AssertionError('No parameters provided') if not isinstance(parameters, str): raise AssertionError('Provided parameters is wrong data type') return parameters @validates('sql_query_id') def validate_sql_query_id(self, key, sql_query_id): if not sql_query_id: raise AssertionError('sql_query_id not provided') if not helpers.get_record_from_id(SqlQuery, sql_query_id): raise AssertionError('sql_query_id not recognized') return sql_query_id @validates('connection_id') def validate_connection_id(self, key, connection_id): if not connection_id: raise AssertionError('connection_id not provided') if not helpers.get_record_from_id(Connection, connection_id): raise AssertionError('connection_id not recognized') return connection_id @validates('usergroups') def validate_usergroups(self, key, usergroups): if not isinstance(usergroups, Usergroup): raise AssertionError('Provided usergroup is not recognized') return usergroups def get_dict(self): dict_format = { 'chart_id': self.id, 'label': self.label, 'creator': self.creator.get_dict(), 'type': self.type, 'parameters': self.parameters, 'sql_query': self.sql_query.get_dict(), 'connection': self.chart_connection.get_dict(), } return dict_format def get_usergroups(self): usergroups = helpers.get_dicts_from_usergroups(self.usergroups) return usergroups def get_authorized_users(self): users = dict(users=helpers.get_users_from_usergroups(self.usergroups)) return users def __repr__(self): return '<Chart label: {}>'.format(self.label)
class Report(db.Model): id = db.Column(db.Integer, primary_key=True) label = db.Column(db.String(64), index=True, unique=True) creator_user_id = db.Column(db.Integer, db.ForeignKey('user.id'), index=True) created_on = db.Column(db.DateTime, default=datetime.utcnow) last_published = db.Column(db.DateTime) parameters = db.Column(db.Text) publications = db.relationship('Publication', backref='publication_report', lazy='dynamic') usergroups = db.relationship("Usergroup", secondary=report_perms, backref="reports") @validates('label') def validate_label(self, key, label): if not label: raise AssertionError('No label provided') if Usergroup.query.filter( func.lower(Usergroup.label) == func.lower(label)).first(): raise AssertionError('Provided label is already in use') return label @validates('parameters') def validate_parameters(self, key, parameters): if not parameters: raise AssertionError('No parameters provided') if not isinstance(parameters, str): raise AssertionError('Provided parameters is wrong data type') return parameters @validates('usergroups') def validate_usergroups(self, key, usergroups): if not isinstance(usergroups, Usergroup): raise AssertionError('Provided usergroup is not recognized') return usergroups def get_dict(self): dict_format = { 'report_id': self.id, 'label': self.label, 'creator': self.creator.get_dict(), 'created_on': self.created_on, 'last_published': self.last_published, 'parameters': self.parameters, 'publications': self.get_publications(), } return dict_format def get_usergroups(self): usergroups = helpers.get_dicts_from_usergroups(self.usergroups) return usergroups def get_authorized_users(self): users = dict(users=helpers.get_users_from_usergroups(self.usergroups)) return users def get_publications(self): return list(map(lambda obj: obj.get_dict(), self.publications)) def __repr__(self): return '<Report {}>'.format(self.label)
class Contact(db.Model): id = db.Column(db.Integer, primary_key=True) first_name = db.Column(db.String(64)) last_name = db.Column(db.String(64)) email = db.Column(db.String(128)) public = db.Column(db.Boolean) creator_user_id = db.Column(db.Integer, db.ForeignKey('user.id'), index=True) publication_ids = db.relationship("Publication", secondary=publication_recipients, backref="recipients") @validates('first_name') def validate_first_name(self, key, first_name): if not first_name: return None if not isinstance(first_name, str): raise AssertionError('First name must be string') if len(first_name) > 50: raise AssertionError('First names must be less than 50 characters') return first_name @validates('last_name') def validate_last_name(self, key, last_name): if not last_name: return None if not isinstance(last_name, str): raise AssertionError('Last name must be string') if len(last_name) > 50: raise AssertionError('Last names must be less than 50 characters') return last_name @validates('email') def validate_email(self, key, email): if not email: raise AssertionError('No email provided') if not isinstance(email, str): raise AssertionError('Email must be string') if not re.match("[^@]+@[^@]+\.[^@]+", email): raise AssertionError('Provided email is not an email address') return email.lower() @validates('public') def validates_public(self, key, public): if not public: return None if isinstance(public, bool): return public if isinstance(public, str): if public.lower() == 'true': return True if public.lower() == 'false': return False else: raise AssertionError('Public flag must be boolean value') @validates('publications') def validate_publications(self, key, publication): if not publication: raise AssertionError('No publication provided') if not isinstance(publication, Publication): raise AssertionError('Publication not recognized') return publication def get_dict(self): dict_format = { 'contact_id': self.id, 'first_name': self.first_name, 'last_name': self.last_name, 'email': self.email, 'public': self.public, 'creator': self.creator.get_dict(), } return dict_format def __repr__(self): return '<Recipient {}, {}>'.format(self.last_name, self.first_name)