class Offer(TimestampMixin, AuthorMixin, db.Model): __tablename__ = 'offers' id = db.Column(db.Integer, primary_key=True) summary = db.Column(db.String(100), info={'label': lazy_gettext('What are you selling?')}) category = db.Column(ChoiceType(RECYCLING_CHOICE_CATEGORY), info={'label': lazy_gettext('Category')}, nullable=False) condition = db.Column(ChoiceType(RECYCLING_CHOICE_CONDITION), info={'label': lazy_gettext('Condition')}, nullable=False) quantity = db.Column(db.String(100), info={'label': lazy_gettext('Quantity')}) unit = db.Column(ChoiceType(RECYCLING_CHOICE_UNIT), info={'label': lazy_gettext('Unit')}, nullable=False) unit_price = db.Column(db.String(100), info={'label': lazy_gettext('Price per Unit')}) pricing_terms = db.Column(ChoiceType(RECYCLING_CHOICE_PRICING_TERMS), info={'label': lazy_gettext('Pricing Terms')}, nullable=False) place_of_delivery = db.Column(db.String(100), info={'label': lazy_gettext('Location')}) payment_method = db.Column(ChoiceType(RECYCLING_CHOICE_PAYMENT), info={'label': lazy_gettext('Payment')}, nullable=False) target_market = db.Column(ChoiceType(COUNTRIES), info={'label': lazy_gettext('Target Market')}, nullable=False) description = db.Column(db.String(100), info={ 'label': lazy_gettext('Description'), 'widget': TextArea() }) published = db.Column(db.Boolean(), info={ 'label': lazy_gettext('Published'), 'widget': RadioInput() }) images = db.relationship('OfferImage', backref='offer', lazy=True) @staticmethod def generate_fake(count=100, **kwargs): """Generate a number of fake offers for testing.""" from sqlalchemy.exc import IntegrityError from random import seed, choice from faker import Faker from random import randint import lorem fake = Faker() users = User.query.all() seed() for i in range(count): u = Offer( summary=lorem.sentence(), category=randint(1, 18), condition=randint(1, 17), quantity=randint(0, 100), unit=randint(1, 3), # unit=choice(RECYCLING_CHOICE_UNIT)[0], unit_price=randint(0, 1000), pricing_terms=randint(1, 11), place_of_delivery=fake.address(), payment_method=randint(1, 3), target_market=choice(COUNTRIES)[0], description=lorem.sentence(), published=True, author_id=randint(1, 20), created=fake.date_of_birth(tzinfo=None, minimum_age=0, maximum_age=1), **kwargs) db.session.add(u) try: db.session.commit() except IntegrityError: db.session.rollback()
class User(db.Model, UserMixin): __tablename__ = 'user' id = db.Column(db.Integer, primary_key=True) uuid = db.Column(db.String(36), unique=True) first_name = db.Column(db.String(255)) last_name = db.Column(db.String(255)) email = db.Column(db.String(255), unique=True) username = db.Column(db.String(255), unique=True) password = db.Column(db.String(255)) active = db.Column(db.Boolean()) confirmed_at = db.Column(db.DateTime()) registered_on = db.Column(db.DateTime()) roles = db.relationship('Role', secondary=roles_users, backref=db.backref('users', lazy='dynamic')) entities_created = db.relationship( 'Entity', backref='created_by', lazy='dynamic', primaryjoin='User.id==Entity.created_by_id') entities_updated = db.relationship( 'Entity', backref='updated_by', lazy='dynamic', primaryjoin='User.id==Entity.updated_by_id') edges_created = db.relationship('Edge', backref='created_by', lazy='dynamic', primaryjoin='User.id==Edge.created_by_id') edges_updated = db.relationship('Edge', backref='updated_by', lazy='dynamic', primaryjoin='User.id==Edge.updated_by_id') verified_email = db.relationship("VerifiedEmail", uselist=False, backref="user") def set_password(self, password): self.password = hash_password(password) def __init__(self, email=None, password=None, first_name=None, last_name=None, active=None, confirmed_at=None, registered_on=None, username=None, roles=['user']): self.email = email self.password = hash_password(password) self.registered_on = datetime.datetime.now() self.first_name = first_name self.last_name = last_name self.active = active self.username = username self.roles = [r for r in Role.query.all() if r.name in roles] self.uuid = uuid.uuid4().__str__() def __str__(self): return self.email def __repr__(self): return '<User {} at {}>'.format(self.email, id(self)) def encode_auth_token(self, user_uuid): """ Generates the Auth Token :return: string """ try: payload = { 'exp': datetime.datetime.utcnow() + datetime.timedelta(days=1, seconds=1), 'iat': datetime.datetime.utcnow(), 'sub': user_uuid } return jwt.encode(payload, app.config.get('SECRET_KEY'), algorithm='HS256') except Exception as e: return e @staticmethod def decode_auth_token(auth_token): """ Validates the auth token :param auth_token: :return: integer|string """ try: payload = jwt.decode(auth_token, app.config.get('SECRET_KEY')) is_blacklisted_token = BlacklistToken.check_blacklist(auth_token) if is_blacklisted_token: response = jwt_fail_responses['blacklisted'] return response else: response = {'status': "success", 'message': payload['sub']} return response except jwt.ExpiredSignatureError: response = jwt_fail_responses['expired'] return response except jwt.InvalidTokenError: response = jwt_fail_responses['invalid'] return response
class Task(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(250), index=True) task = db.Column(db.String(5000), index=True) completed = db.Column(db.Boolean()) owner = db.Column(db.String(500))
class User(db.Model, UserMixin): id = db.Column(db.Integer(), primary_key=True) email = db.Column(db.String(100), unique=True) password = db.Column(db.String(255)) active = db.Column(db.Boolean()) roles = db.relationship('Role', secondary=roles_users, backref=db.backref('user', lazy='dynamic'))
class User(db.Model, UserMixin): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(255), unique=True) #用户名 email = db.Column(db.String(255), unique=True) password = db.Column(db.String(255), nullable=False) active = db.Column(db.Boolean(), default=True) # 是否已经激活 role = db.Column(db.String(20), default='User') # 用户或者管理员 gender = db.Column(db.Enum('male', 'female', 'unknown'), default='unknown') identity = db.Column(db.Enum('Teacher', 'Student')) # 学生或者教师 register_time = db.Column(db.DateTime(), default=datetime.utcnow) confirmed_at = db.Column(db.DateTime()) last_login_time = db.Column(db.DateTime()) #TODO:login unread_notification_count = db.Column(db.Integer, default=0) homepage = db.Column(db.String(200)) # 用户博客、主页等 description = db.Column(db.Text) _avatar = db.Column(db.String(100)) following_count = db.Column(db.Integer, default=0) follower_count = db.Column(db.Integer, default=0) courses_following = db.relationship('Course', secondary=follow_course, backref='followers') courses_upvoted = db.relationship('Course', secondary=upvote_course, backref='upvote_users') courses_downvoted = db.relationship('Course', secondary=downvote_course, backref='downvote_users') _student_info = db.relationship('Student', backref='user', uselist=False) _teacher_info = db.relationship('Teacher', backref='user', uselist=False) reviewed_course = db.relationship('Course', secondary=review_course, backref='review_users') users_following = db.relationship( 'User', secondary=follow_user, primaryjoin=(follow_user.c.follower_id == id), secondaryjoin=(follow_user.c.followed_id == id), backref=db.backref('followers')) # followers: backref to User # notifications: backref to Notification def __init__(self, username, email, password): self.username = username self.email = email self.set_password(password) def __repr__(self): return '<User {} ({})>'.format(self.email, self.password) @property def url(self): return url_for('user.view_profile', user_id=self.id) @property def link(self): return Markup('<a href="' + self.url + '">') + Markup.escape( self.username) + Markup('</a>') @property def latest_notifications_text(self): text = latest_notifications_cache.get(self.id) if text is None: text = [] for notice in self.notifications[0:5]: text.append(notice.display_text) latest_notifications_cache.set(self.id, text) return text @property def reviews_count(self): return len(self.reviews) @property def courses_following_count(self): return len(self.courses_following) @property def courses_upvoted_count(self): return len(self.courses_upvoted) @property def courses_downvoted_count(self): return len(self.courses_downvoted) @property def courses_joined_count(self): return len(self.courses_joined) @property def courses_joined(self): if self.is_student and self.info: return self.info.courses_joined else: return [] @property def classes_joined_count(self): return len(self.classes_joined) @property def classes_joined(self): if self.is_student and self.info: return self.info.classes_joined else: return [] @property def avatar(self): if self._avatar: return '/uploads/images/' + self._avatar return '/static/image/user.png' def set_avatar(self, avatar): self._avatar = avatar @property def confirmed(self): if self.confirmed_at: return True return False @property def info(self): if self.identity == 'Student': return self._student_info elif self.identity == 'Teacher': return self._teacher_info else: return None @property def is_student(self): return self.identity == 'Student' @property def is_teacher(self): return self.identity == 'Teacher' @property def is_authenticated(self): return True @property def is_admin(self): return self.role == 'Admin' def is_active(self): if self.active: return True return False def confirm(self): self.confirmed_at = datetime.utcnow() self.save() def set_password(self, password): self.password = generate_password_hash(password) self.save() def check_password(self, password): """Check passwords.Returns ture if matchs""" if self.password is None: return False return check_password_hash(self.password, password) @classmethod def authenticate(cls, login, password): """A classmethod for authenticating users It returns true if the user exists and has entered a correct password :param login: This can be either a username or a email address. :param password: The password that is connected to username and email. """ user = cls.query.filter( db.or_(User.username == login, User.email == login)).first() if user and user.confirmed: authenticated = user.check_password(password) else: authenticated = False return user, authenticated, user.confirmed if user else False def bind_student(self, sno): if self.identity == 'Student': student = Student.query.get(sno) if student: self._student_info = student return True, _('成功绑定!') else: return False, _('找不到这个学号:%(sno)s!', sno=sno) else: return False, _('无法绑定学号。') def bind_teacher(self, email): if self.identity == 'Teacher': teacher = Teacher.query.filter_by(email=email).first() if teacher: self._teacher_info = teacher self.description = teacher.description self.homepage = teacher.homepage return True, _('绑定成功!') else: return False, _('找不到教师邮箱:%(email)s!', email=email) else: return False, _('无法绑定教师身份。') def save(self): db.session.add(self) db.session.commit() def notify(self, operation, ref_obj, from_user=current_user, ref_display_class=None): # my operations should not be notified to myself if from_user == self: return False notification = Notification(self, from_user, operation, ref_obj, ref_display_class) notification.save() self.unread_notification_count += 1 db.session.commit() # clear cache latest_notifications_cache.set(self.id, None) return True def follow(self, followed): if followed in self.users_following: return False self.users_following.append(followed) self.following_count += 1 followed.follower_count += 1 db.session.commit() return True def unfollow(self, followed): if followed not in self.users_following: return False self.users_following.remove(followed) self.following_count -= 1 followed.follower_count -= 1 db.session.commit() return True def followed_by(self, user=current_user): return user in self.followers def following(self, user=current_user): return user in self.users_following
class Event(Base): __tablename__ = "event" __table_args__ = {'extend_existing': True} id = db.Column(db.Integer(), primary_key=True) start_date = db.Column(db.DateTime(), nullable=False) end_date = db.Column(db.DateTime(), nullable=False) key = db.Column(db.String(255), nullable=False, unique=True) organisation_id = db.Column(db.Integer(), db.ForeignKey('organisation.id'), nullable=False) email_from = db.Column(db.String(255), nullable=False) url = db.Column(db.String(255), nullable=False) application_open = db.Column(db.DateTime(), nullable=False) application_close = db.Column(db.DateTime(), nullable=False) review_open = db.Column(db.DateTime(), nullable=False) review_close = db.Column(db.DateTime(), nullable=False) selection_open = db.Column(db.DateTime(), nullable=False) selection_close = db.Column(db.DateTime(), nullable=False) offer_open = db.Column(db.DateTime(), nullable=False) offer_close = db.Column(db.DateTime(), nullable=False) registration_open = db.Column(db.DateTime(), nullable=False) registration_close = db.Column(db.DateTime(), nullable=False) event_type = db.Column(db.Enum(EventType), nullable=False) travel_grant = db.Column(db.Boolean(), nullable=False) miniconf_url = db.Column(db.String(100), nullable=True) event_translations = db.relationship('EventTranslation', lazy='dynamic') def __init__( self, names, descriptions, start_date, end_date, key, organisation_id, email_from, url, application_open, application_close, review_open, review_close, selection_open, selection_close, offer_open, offer_close, registration_open, registration_close, event_type, travel_grant, miniconf_url=None ): self.start_date = start_date self.end_date = end_date self.key = key self.organisation_id = organisation_id self.email_from = email_from self.url = url self.application_open = application_open self.application_close = application_close self.review_open = review_open self.review_close = review_close self.selection_open = selection_open self.selection_close = selection_close self.offer_open = offer_open self.offer_close = offer_close self.registration_open = registration_open self.registration_close = registration_close self.event_roles = [] self.event_type = event_type self.travel_grant = travel_grant self.miniconf_url = miniconf_url self.add_event_translations(names, descriptions) def add_event_translations(self, names, descriptions): for language in names: name = names[language] description = descriptions[language] event_translation = EventTranslation(name, description, language) self.event_translations.append(event_translation)
class BadgeTemplate(TimestampMixin, Model): __tablename__ = 'badge_template' id = db.Column(db.BigInteger(), primary_key=True) name = db.Column(db.UnicodeText(), nullable=False) description = db.Column(db.UnicodeText()) extends_id = db.Column( db.BigInteger(), db.ForeignKey('badge_template.id', onupdate='CASCADE', ondelete='RESTRICT')) extends = db.relationship('BadgeTemplate', remote_side=[id], backref='extended_by') min_age = db.Column(db.Integer()) max_age = db.Column(db.Integer()) no_match = db.Column(db.Boolean(), nullable=False, default=False, server_default='0') image = db.Column(db.UnicodeText()) badge_name_top = db.Column(db.Float()) badge_name_left = db.Column(db.Float()) badge_name_width = db.Column(db.Float()) badge_name_height = db.Column(db.Float()) badge_number_top = db.Column(db.Float()) badge_number_left = db.Column(db.Float()) badge_number_width = db.Column(db.Float()) badge_number_height = db.Column(db.Float()) level_top = db.Column(db.Float()) level_left = db.Column(db.Float()) level_width = db.Column(db.Float()) level_height = db.Column(db.Float()) timestamp_format = db.Column(db.UnicodeText()) timestamp_append_to_level = db.Column(db.Boolean(), nullable=False, default=False) timestamp_top = db.Column(db.Float()) timestamp_left = db.Column(db.Float()) timestamp_width = db.Column(db.Float()) timestamp_height = db.Column(db.Float()) arbitrary_text = db.Column(db.UnicodeText()) arbitrary_text_override_level = db.Column(db.Boolean(), nullable=False, default=False) arbitrary_text_top = db.Column(db.Float()) arbitrary_text_left = db.Column(db.Float()) arbitrary_text_width = db.Column(db.Float()) arbitrary_text_height = db.Column(db.Float()) css = db.Column(db.UnicodeText()) flags = db.relationship('Flag', secondary=BadgeTemplateToFlag.__table__, backref='badge_templates') levels = db.relationship('Level', secondary=BadgeTemplateToLevel.__table__, backref='badge_templates') def __str__(self): return self.name @property def image_url(self): if self.image: return url_for('index.upload', filename=self.image) @property def is_leaf(self): if getattr(self, '_is_leaf', None) is None: self._is_leaf = BadgeTemplate.query.filter( BadgeTemplate.extends == self).count() == 0 return self._is_leaf @property def inheritance_chain(self): b = self while b: yield b b = b.extends @property def cascaded_props(self): out = { 'id': self.id, 'name': self.name, 'description': self.description, 'extends_id': self.extends_id, 'extends': self.extends, 'min_age': self.min_age, 'max_age': self.max_age, 'no_match': self.no_match, # Cascaded via CSS 'badge_name_top': self.badge_name_top, 'badge_name_left': self.badge_name_left, 'badge_name_width': self.badge_name_width, 'badge_name_height': self.badge_name_height, 'badge_number_top': self.badge_number_top, 'badge_number_left': self.badge_number_left, 'badge_number_width': self.badge_number_width, 'badge_number_height': self.badge_number_height, 'level_top': self.level_top, 'level_left': self.level_left, 'level_width': self.level_width, 'level_height': self.level_height, 'timestamp_top': self.timestamp_top, 'timestamp_left': self.timestamp_left, 'timestamp_width': self.timestamp_width, 'timestamp_height': self.timestamp_height, 'arbitrary_text_top': self.arbitrary_text_top, 'arbitrary_text_left': self.arbitrary_text_left, 'arbitrary_text_width': self.arbitrary_text_width, 'arbitrary_text_height': self.arbitrary_text_height, # TODO: these should allow for an empty value to be properly overridden 'timestamp_append_to_level': self.timestamp_append_to_level, 'arbitrary_text_override_level': self.arbitrary_text_override_level, # Real overrides 'timestamp_format': None, 'arbitrary_text': None, 'image': None, # Fake properties 'level': None, 'timestamp': None, 'level_append': None, 'classes': '', } for tpl in self.inheritance_chain: out['classes'] += ' tplid_' + str(tpl.id) if tpl.timestamp_append_to_level: out['timestamp_append_to_level'] = tpl.timestamp_append_to_level if tpl.arbitrary_text_override_level: out['arbitrary_text_override_level'] = tpl.arbitrary_text_override_level if tpl.timestamp_format and not out['timestamp_format']: out['timestamp_format'] = tpl.timestamp_format if tpl.arbitrary_text and not out['arbitrary_text']: out['arbitrary_text'] = tpl.arbitrary_text if tpl.image and not out['image']: out['image'] = tpl.image_url if out['timestamp_format']: out['timestamp'] = arrow.now().format(out['timestamp_format']) if out['arbitrary_text'] and out['arbitrary_text_override_level']: out['level'] = out['arbitrary_text'] out['arbitrary_text'] = None if out['timestamp'] and out['timestamp_append_to_level']: out['level_append'] = ' ' + out['timestamp'] out['timestamp'] = None return out def matches(self, badge): """\ Determine whether this template matches a particular badge. The return value is the specificity of the match. Matches are: - Badge age is within the range configured (1 match) - Badge and template share a flag (1 match per shared flag) - Badge level is assigned to the template (1 match) - Badge is a leaf node (no children), but only if there are other matches (2 matches) """ if self.no_match: return 0 matches = [] age_weight = 3 min_age = self.min_age max_age = self.max_age if min_age is None: min_age = 0 age_weight -= 1 if max_age is None: max_age = 999 age_weight -= 1 # Note that min/max ages are both inclusive if badge.age >= min_age and badge.age <= max_age: matches.append(('age', age_weight)) else: # If the badge age isn't in the range, no match is possible matches.append(('age', -1)) if not self.flags: # No flags is a single match matches.append(('flags', 0.5)) else: matching_flags = 0 for t_flag in self.flags: for b_flag in badge.flags: if t_flag == b_flag: matching_flags += 1 if not matching_flags: # If the template has flags but the badge doesn't match any, no match is possible matches.append(('flags', -1)) else: matches.append(('flags', matching_flags)) if not self.levels: # No levels is a single match matches.append(('level', 0.5)) else: if badge.level not in self.levels: # If the template has levels but the badge doesn't have one of them, no match is possible matches.append(('level', -1)) else: matches.append(('level', 1)) if matches: if self.is_leaf: matches.append(('leaf', 2)) # logger.debug("Match badge %s against template %s, matches: %s", badge.name, self.name, matches) if len([v for v in matches if v[1] < 0]): return 0 return sum((v[1] for v in matches))
class User(db.Model, UserMixin): id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(9999), unique=True, nullable=False) password = db.Column(db.String(9999), nullable=False) otp_secret = db.Column(db.String(9999), nullable=True) activated = db.Column(db.Boolean(), nullable=False, default=False) master_key = db.Column(db.String(9999), nullable=False) managed_passwords = db.relationship('Password', backref='user', lazy='dynamic') managed_secure_notes = db.relationship('SecureNote', backref='user', lazy='dynamic') managed_credit_cards = db.relationship('CreditCard', backref='user', lazy='dynamic') def get_activation_token(self): s = Serializer(current_app.config['SECRET_KEY']) return s.dumps({ 'user_id': self.id, 'email': self.email }).decode('utf-8') @staticmethod def verify_activation_token(token): s = Serializer(current_app.config['SECRET_KEY']) try: user_id = s.loads(token)['user_id'] except: return None email = s.loads(token)['email'] return User.query.get(user_id), email def get_reset_token(self, expires_seconds=1800): s = TimedSerializer(current_app.config['SECRET_KEY'], expires_seconds) return s.dumps({'user_id': self.id}).decode('utf-8') @staticmethod def verify_reset_token(token): s = TimedSerializer(current_app.config['SECRET_KEY']) try: user_id = s.loads(token)['user_id'] except: return None return User.query.get(user_id) def get_api_token(self, expires_seconds=1800): s = TimedSerializer(current_app.config['SECRET_KEY'], expires_seconds) return s.dumps({'user_id': self.id}).decode('utf-8') @staticmethod def verify_api_token(token): s = TimedSerializer(current_app.config['SECRET_KEY']) try: user_id = s.loads(token)['user_id'] except SignatureExpired: return 'expired' except: return None return User.query.get(user_id) def verify_totp(self, token): return onetimepass.valid_totp(token, self.otp_secret) def __repr__(self): return f"User('{self.id}', '{self.email}')"
class Page(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(200), nullable=False) slug = db.Column(db.String(200), nullable=True) dir_path = db.Column(db.String(500), nullable=True) path = db.Column(db.String(500), nullable=True) parent_id = db.Column(db.Integer(), db.ForeignKey('page.id'), nullable=True) parent = db.relationship('Page', remote_side=[id], backref='children') template = db.Column(db.String(100)) banner = db.Column(db.String(500), nullable=True) body = db.Column(db.String(10000000)) notes = db.Column(db.Text(5000000)) tags = db.relationship('Tag', secondary=tags, lazy='subquery', backref=db.backref('pages', order_by='Page.path', lazy=True)) summary = db.Column(db.String(300), nullable=True) sidebar = db.Column(db.String(5000), nullable=True) user_id = db.Column('User', db.ForeignKey('user.id'), nullable=False) sort = db.Column(db.Integer(), nullable=False, default=75) pub_date = db.Column(db.DateTime(), nullable=True) published = db.Column(db.Boolean(), default=False) edit_date = db.Column(db.DateTime(), index=True, default=datetime.utcnow) versions = db.relationship('PageVersion', backref='current', primaryjoin=id == PageVersion.original_id) TEMPLATE_CHOICES = [ ('page', 'Page'), ('post', 'Post'), ('story', 'Story'), ('book', 'Book'), ('chapter', 'Chapter'), ('blog', 'Blog'), ] #def parent(self): # return Page.query.filter_by(id=self.parent_id).first() def set_path(self): if self.parent_id: print(f"PARENT ID: {self.parent_id}") parent = Page.query.filter_by(id=self.parent_id).first() print(f"PARENT: {parent}") try: parent_path = parent.path except AttributeError: parent.set_path() self.path = f"{parent.path}/{self.slug}" self.dir_path = parent.path else: self.path = f"/{self.slug}" self.dir_path = "/" def html(self, field): if field == 'body': data = self.body if field == 'notes': data = self.notes data = markdown( data.replace('---', '<center>🌱</center>').replace( '--', '—')) data = Product.replace_product_markup(data) return data def html_body(self): body = markdown( self.body.replace('---', '<center>🌱</center>').replace( '--', '—')) body = Product.replace_product_markup(body) return body def text_body(self): pattern = re.compile(r'<.*?>') return pattern.sub('', self.html_body()) def html_sidebar(self): sidebar = self.sidebar if self.template == 'chapter' or self.template == 'post': if self.parent_id: sidebar = self.parent.sidebar sidebar = markdown(sidebar) sidebar = Product.replace_product_markup(sidebar) return sidebar def description(self, length=247): if self.summary: return self.summary return self.text_body()[0:length] + '...' def view_code(self): #return str(datetime.now().year) + str(datetime.now().isocalendar()[1]) + self.slug return str(datetime.now().year) + str(datetime.now( ).month) + self.path + current_app.config['SECRET_KEY'] def gen_view_code(self): if not self.published: return '?code=' + generate_password_hash(self.view_code()) return '' def check_view_code(self, code): if code: return check_password_hash(code, self.view_code()) return False def banner_path(self, always_return_img=False): banner = self.banner if not self.banner and (self.template == 'chapter' or self.template == 'post'): if self.parent_id: banner = self.parent.banner if banner: if 'http' in banner[0:5]: return banner else: return str(current_app.config['BASE_URL']) + banner if not always_return_img: return False else: return str(current_app.config['DEFAULT_BANNER_PATH']) def meta_img(self): if self.banner_path(): return self.banner_path() return str(current_app.config['DEFAULT_FAVICON']) def section_name(self): if self.template == 'chapter' or self.template == 'post': if self.parent_id: return self.parent.title return self.title def pub_children(self, published_only=True, chapter_post_only=False): if published_only: if chapter_post_only: return Page.query.filter(Page.template.in_([ 'chapter', 'post' ])).filter_by(parent_id=self.id, published=True).order_by('sort', 'pub_date', 'title').all() return Page.query.filter_by(parent_id=self.id, published=True).order_by( 'sort', 'pub_date', 'title').all() if chapter_post_only: return Page.query.filter(Page.template.in_( ['chapter', 'post'])).filter_by(parent_id=self.id, ).order_by( 'sort', 'pub_date', 'title').all() return Page.query.filter_by(parent_id=self.id, ).order_by( 'sort', 'pub_date', 'title').all() def latest(self): if self.template == 'chapter' or self.template == 'post': return self.pub_siblings(chapter_post_only=True)[::-1][0] return self.pub_children(chapter_post_only=True)[::-1][0] def pub_siblings(self, published_only=True, chapter_post_only=False): if published_only: if chapter_post_only: return Page.query.filter(Page.template.in_([ 'chapter', 'post' ])).filter_by(parent_id=self.parent_id, published=True).order_by('sort', 'pub_date', 'title').all() return Page.query.filter_by(parent_id=self.parent_id, published=True).order_by( 'sort', 'pub_date', 'title').all() if chapter_post_only: return Page.query.filter(Page.template.in_( ['chapter', 'post'])).filter_by(parent_id=self.parent_id).order_by( 'sort', 'title', 'pub_date').all() return Page.query.filter_by(parent_id=self.parent_id).order_by( 'sort', 'title', 'pub_date').all() def child_count(self, include_unpublished=False): if include_unpublished: return len( self.pub_children(published_only=False, chapter_post_only=True)) return len(self.pub_children(chapter_post_only=True)) def next_pub_sibling(self, published_only=True, chapter_post_only=True): try: if not published_only: raise Exception return self.next_sibling except Exception: siblings = self.pub_siblings(published_only, chapter_post_only=True) print(siblings) current = False for sibling in siblings: if current: if sibling.id != self.id: self.next_sibling = sibling return self.next_sibling if sibling.id == self.id: current = True self.next_sibling = None return None def prev_pub_sibling(self, published_only=True, chapter_post_only=True): try: if not published_only: raise Exception return self.prev_sibling except Exception: siblings = self.pub_siblings(published_only, chapter_post_only=chapter_post_only) print(siblings) prev = None for sibling in siblings: if sibling.id == self.id: if prev and prev.id != self.id: self.prev_sibling = prev return self.prev_sibling prev = sibling self.prev_sibling = None return None def ancestors(self): ancestors = [] parent = Page.query.filter_by(id=self.parent_id).first() if parent: ancestors.append(parent) for p in parent.ancestors(): ancestors.append(p) return ancestors def descendents(self): descendents = [] children = Page.query.filter_by(parent_id=self.id).all() for child in children: descendents.append(child) for c in child.all_children(): descendents.append(c) return descendents def word_count(self): try: return self.words except: words = len(re.findall("[a-zA-Z']+-?[a-zA-Z']*", self.body)) read_time = str(round(words / 200)) + " - " + str( round(words / 150)) + " mins." self.words = words return self.words def read_time(self): words = self.word_count() if words / 200 < 120: return str(round(words / 200)) + " - " + str(round( words / 150)) + " mins." return str(round(words / 200 / 60)) + " - " + str( round(words / 150 / 60)) + " hrs." def child_word_count(self, published_only=True): #try: # return self.child_words #except: words = 0 children = self.pub_children(published_only=published_only, chapter_post_only=True) for child in children: words += child.word_count() self.child_words = words return self.child_words def page_count(self, published_only=True): words_per_page = 275 if self.template in ['blog', 'story']: return round( self.child_word_count(published_only) / words_per_page) return round(self.word_count() / words_per_page) def avg_child_word_count(self, published_only=True): total = 0 children = self.pub_children(published_only=published_only, chapter_post_only=True) for child in children: total += child.word_count() return int(total / len(children)) if len(children) else total def child_read_time(self, published_only=True): words = self.child_word_count(published_only) if words / 200 < 120: return str(round(words / 200)) + " - " + str(round( words / 150)) + " mins." return str(round(words / 200 / 60)) + " - " + str( round(words / 150 / 60)) + " hrs." def child_write_time(self, published_only=True): hourly_words = 350 words = self.child_word_count(published_only) print(words) print(published_only) if words / hourly_words < 2: return str(round(words / hourly_words * 60)) + " mins." if words / hourly_words > 48: return str(round(words / hourly_words / 24)) + " days" return str(round(words / hourly_words)) + " hrs." def local_pub_date(self, tz): if self.pub_date: utc = pytz.timezone('utc') local_tz = pytz.timezone(tz) pub_date = datetime.strptime(str(self.pub_date), '%Y-%m-%d %H:%M:%S') utcdate = pytz.UTC.localize(self.pub_date) return utcdate.astimezone(tz=local_tz) return None def set_local_pub_date(self, date, tz): pub_date = datetime.strptime(str(date), '%Y-%m-%d %H:%M:%S') local_tz = pytz.timezone(tz) pub_date = local_tz.localize(pub_date) self.pub_date = pub_date.astimezone(pytz.utc) def notify_subscribers(self, group): sender = current_app.config['MAIL_DEFAULT_SENDER'] parent_title = self.parent.title + ' - ' if self.parent else '' parent_title = '🌱' + parent_title if parent_title == 'Sprig - ' else parent_title subject = f"[New {self.template.title()}] {parent_title}{self.title}" body = f"Stories by Houston Hare\nNew Post: {parent_title}{self.title}\n{self.description()}\nRead more: {current_app.config['BASE_URL']}{self.path}" if group == "all": subs = Subscriber.query.all() else: subs = Subscriber.query.filter( Subscriber.subscription.contains(f",{group},")).all() if subs: for recipient in subs: send_email( subject, sender, [recipient.email], body, render_template('email/subscriber-notification.html', page=self, recipient=recipient), ) def nav_list(self): nav = [] return nav def set_nav(): nav = [] top_pages = Page.query.filter_by(published=True, parent_id=None).order_by( 'sort', 'pub_date', 'title').all() for top_page in top_pages: page = { 'id': top_page.id, 'title': top_page.title, 'path': top_page.path, 'children': [], } for child in top_page.pub_children(): kid = { 'id': child.id, 'title': child.title, 'path': child.path, 'children': [], } for grandchild in child.pub_children(): kid['children'].append({ 'id': grandchild.id, 'title': grandchild.title, 'path': grandchild.path, 'children': [], }) page['children'].append(kid) nav.append(page) session['nav'] = nav def __str__(self): return f"{self.title} ({self.path})" def __repr__(self): return f"<Page({self.id}, {self.title}, {self.path})>"
class User(db.Model, UserMixin): __tablename__ = 'user' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), index=True, unique=True) fullname = db.Column(db.String(150), index=True) active = db.Column('is_active', db.Boolean(), nullable=False, server_default='1') email = db.Column(db.String(120), index=True, nullable=True, unique=True) bio = db.Column(db.Text, index=True) socialId = db.Column(db.String(120), unique=True) password_hash = db.Column(db.String(128), nullable=True) sign_date = db.Column(db.DateTime, default=datetime.now()) avatar_ = db.Column(db.String(300)) isCompany = db.Column(db.Boolean(), nullable=False, server_default='0') subType = db.Column(db.String(20)) listOfModules = db.Column(db.String(100)) agreementId = db.Column(db.String(50)) my_researches = db.relationship('UserResearchPermission', back_populates="users", cascade='all, delete-orphan', single_parent=True, uselist=True) owners = db.relationship('Research', backref='User', cascade='all, delete-orphan', lazy='dynamic') followed = db.relationship('User', secondary=followers, primaryjoin=(followers.c.follower_id == id), secondaryjoin=(followers.c.followed_id == id), backref=db.backref('followers', lazy='dynamic'), lazy='dynamic') subscribed = db.relationship("Research", secondary=subscriptions, back_populates="subscribers", lazy='dynamic') liked = db.relationship("Research", secondary=likes, back_populates="user_liked", lazy='dynamic') def __repr__(self): return '@{}'.format(self.username) 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 follow(self, user): if not self.is_following( user) and user.isCompany is False and self.isCompany is True: self.followed.append(user) return True return False def unfollow(self, user): if self.is_following(user): self.followed.remove(user) return True return False def is_following(self, user): return self.followed.filter( followers.c.followed_id == user.id).count() > 0 def subscribe(self, research): if not self.is_subscribed(research): self.subscribed.append(research) return True return False def unsubscribe(self, research): if self.is_subscribed(research): self.subscribed.remove(research) return True return False def is_subscribed(self, research): return self.subscribed.filter( subscriptions.c.research_id == research.id).count() > 0 def like(self, research): if not self.is_liked(research): self.liked.append(research) return True return False def unlike(self, research): if self.is_liked(research): self.liked.remove(research) return True return False def is_liked(self, research): return self.liked.filter( likes.c.research_id == research.id).count() > 0 def save_to_db(self): db.session.add(self) db.session.commit() def del_from_db(self): self.owners.clear() self.subscribed.clear() self.my_researches.clear() self.followed.clear() db.session.delete(self) db.session.commit() def return_followed(self): def to_json(x): return { 'id': x.id, 'username': x.username, 'fullname': x.fullname, 'biography': x.bio, 'isCompany': x.isCompany } return {'users': list(map(lambda x: to_json(x), list(self.followed)))} def return_subscribed(self): def to_json(x): return { 'id': x.id, 'topic': x.topic, 'description': x.description, 'creation': x.creationDate.strftime('%d.%m.%Y'), 'views': x.views, 'likes': len( db.session.query(likes).filter( likes.c.research_id == x.id).all()) } return { 'subscriptions': list(map(lambda x: to_json(x), list(self.subscribed))) } def return_liked(self): def to_json(x): return { 'id': x.id, 'topic': x.topic, 'description': x.description, 'creation': x.creationDate.strftime('%d.%m/%Y'), 'views': x.views, 'likes': len( db.session.query(likes).filter( likes.c.research_id == x.id).all()) } return {'liked': list(map(lambda x: to_json(x), list(self.liked)))} @classmethod def find_by_username(cls, username): return cls.query.filter_by(username=username).first() @classmethod def find_by_id(cls, user_id): return cls.query.filter_by(id=user_id).first() @classmethod def find_by_email(cls, user_email): return cls.query.filter_by(email=user_email).first() @classmethod def return_all(cls): def to_json(x): return { 'id': x.id, 'username': x.username, 'fullname': x.fullname, 'biography': x.bio, 'isCompany': x.isCompany } return {'users': list(map(lambda x: to_json(x), User.query.all()))} @classmethod def delete_all(cls): try: num_rows_deleted = db.session.query(cls).delete() db.session.commit() return {'message': '{} row(s) deleted'.format(num_rows_deleted)} except: return {'message': 'Something went wrong'}
from app import db, marshmallow tags = db.Table('tags', db.Column('tag_id', db.Integer, db.ForeignKey('tag.id'), primary_key=True), db.Column('tune_id', db.Integer, db.ForeignKey('tune.id'), primary_key=True) ) class Tune(db.Model): __table_args__ = {'extend_existing': True} id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(100)) time_signature = db.Column(db.String(10), default='4/4') default_note_length = db.Column(db.String(10), default='1/8') tune_type = db.Column(db.String(50)) key_signature = db.Column(db.String(50)) additional_info = db.Column(db.Text, nullable=True) poster = ForeignKeyField(User, related_name='tune_set') fork = relationship'Tune', backref=backref('tune_dad', remote_side=[id]), nullable=True) tags = db.relationship('Tag', secondary=tags, lazy='subquery', backref=db.backref('tunes', lazy=True), nullable=True) is_public = db.Column(db.Boolean(), default=False) class Tag(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(100), unique=True)
class User(db.Model): """This class represents the users.""" __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True, autoincrement=True) username = db.Column(db.String(255), unique=True, nullable=False) email = db.Column(db.String(255), unique=True, nullable=False) first_name = db.Column(db.String(255), nullable=False) last_name = db.Column(db.String(255), nullable=False) password = db.Column(db.String(255), nullable=False) registered_on = db.Column(db.DateTime, nullable=False) role = db.Column(db.String(255), nullable=False) location = db.Column(db.String(255), nullable=False) available = db.Column(db.Boolean(), nullable=False) fdc = db.relationship('FoodDistributionCenter', uselist=False, backref='admin', lazy=True) pickups = db.relationship('Pickup', backref='donor', lazy=True) def __init__(self, username, email, password, first_name, last_name, role, location): self.username = username self.email = email self.first_name = first_name self.last_name = last_name self.role = role self.password = bcrypt.generate_password_hash( password, app.config.get('BCRYPT_LOG_ROUNDS') ).decode() self.available = False self.registered_on = datetime.datetime.now() self.location = location def save(self): db.session.add(self) db.session.commit() def delete(self): db.session.delete(self) db.session.commit() def encode_auth_token(self, user_id): try: payload = { 'exp': datetime.datetime.utcnow() + datetime.timedelta(days=2, seconds=0), 'iat': datetime.datetime.utcnow(), 'sub': user_id } return jwt.encode( payload, app.config.get('SECRET_KEY'), algorithm='HS256' ) except Exception as e: return e @staticmethod def decode_auth_token(auth_token): try: payload = jwt.decode(auth_token, app.config.get('SECRET_KEY'), algorithms='HS256') is_blacklisted_token = BlacklistToken.check_blacklist(auth_token) if is_blacklisted_token: return 'Token blacklisted. Please log in again.' else: return payload['sub'] except jwt.ExpiredSignatureError: return 'Signature expired. Please log in again.' except jwt.InvalidTokenError: return 'Invalid token. Please log in again.'
class Post(SearchableMixin, db.Model): __searchable__ = ['body', 'title'] def _default_user(self): if current_user: return current_user.id else: return None id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(140), default='Untitled story') body = db.Column(db.Text()) timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), default=_default_user) published = db.Column(db.Boolean(), default=False) clap_count = db.Column(db.Integer, default=0) read_count = db.Column(db.Integer, default=0) def add_to_index(self): if self.published: add_to_index(self.__tablename__, self) def remove_from_index(self): if self.published: remove_from_index(self.__tablename__, self) def action_publish(self): self.published = True self.add_to_index() author = User.query.get(self.user_id) for f in author.followers.all(): msg = Message(mtype='Stories', sender_id=author.id, recipient_id=f.id, body="%s posted %s." % (author.username, self.title)) db.session.add(msg) def action_draft(self): self.published = False self.remove_from_index() def __repr__(self): return '<Post {}>'.format(self.title) def is_following(self): if current_user: is_following = current_user.is_following(self.author) return is_following else: return False def to_dict(self): data = { 'id': self.hash_id, 'title': self.title, 'body': self.body, 'is_following': self.is_following(), 'author': self.author and self.author.to_dict(), 'timestamp': self.timestamp.isoformat() + 'Z', 'clap_users_count': self.clap_users.count(), 'published': self.published, 'clap_count': self.clap_count or 0, 'tags': [tag.to_dict() for tag in self.tags], } return data def clap(self, uid): self.clap_count = (self.clap_count or 0) + 1 user = User.query.get(uid) if user not in self.clap_users: self.clap_users.append(user) db.session.add(self) return self.clap_count
class User(db.Model, UserMixin): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) # User authentication information (required for Flask-User) email = db.Column(db.Unicode(255), nullable=False, server_default=u'', unique=True) email_confirmed_at = db.Column(db.DateTime()) password = db.Column(db.String(255), nullable=False, server_default='') username = db.Column(db.String(50), nullable=False, unique=True) # reset_password_token = db.Column(db.String(100), nullable=False, server_default='') active = db.Column(db.Boolean(), nullable=False, server_default='0') # User information active = db.Column('is_active', db.Boolean(), nullable=False, server_default='0') first_name = db.Column(db.Unicode(50), nullable=False, server_default=u'') last_name = db.Column(db.Unicode(50), nullable=False, server_default=u'') bio = db.Column(db.Unicode(500), nullable=True, server_default=u'') interests = db.Column(db.Unicode(500), nullable=False, server_default='#Education #Technology #GT #OMSCS') # Relationships roles = db.relationship('Role', secondary='users_roles', backref=db.backref('users', lazy='dynamic')) projects = db.relationship('Project', backref=db.backref('creator', lazy=True)) liked = db.relationship('ProjectLike', foreign_keys='ProjectLike.user_id', backref='user', lazy='dynamic') # following = db.relationship('Network', foreign_keys='Network.user_id',backref='user', lazy='dynamic') # followers = db.relationship('Network', backref='user', lazy='dynamic') followed = db.relationship('User', secondary=network, primaryjoin=(network.c.follower_id == id), secondaryjoin=(network.c.followed_id == id), backref=db.backref('network', lazy='dynamic'), lazy='dynamic') def like_project(self, project): if not self.has_liked_project(project): like = ProjectLike(user_id=self.id, project_id=project.id) db.session.add(like) def unlike_project(self, project): if self.has_liked_project(project): ProjectLike.query.filter_by(user_id=self.id, project_id=project.id).delete() def has_liked_project(self, project): return ProjectLike.query.filter(ProjectLike.user_id == self.id, ProjectLike.project_id == project.id).count() > 0 def follow_user(self, user): if not self.has_followed_user(user): self.followed.append(user) def unfollow_user(self, user): if self.has_followed_user(user): self.followed.remove(user) def has_followed_user(self, user): has_followed = False following = self.followed.all() following_user_ids = [] for f in following: following_user_ids.append(f.id) has_followed = user.id in following_user_ids return has_followed def followed_projects(self): return Project.query.join( network, (network.c.followed_id == Project.creator_id)).filter( network.c.follower_id == self.id).order_by( Project.date_added.desc()).all()
class User(db.Model, UserMixin): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) # User authentication information (required for Flask-User) email = db.Column(db.Unicode(255), nullable=False, server_default=u'', unique=True) confirmed_at = db.Column(db.DateTime()) password = db.Column(db.String(255), nullable=False, server_default='') # reset_password_token = db.Column(db.String(100), nullable=False, server_default='') active = db.Column(db.Boolean(), nullable=False, server_default='0') # User information active = db.Column('is_active', db.Boolean(), nullable=False, server_default='0') first_name = db.Column(db.Unicode(50), nullable=False, server_default=u'') last_name = db.Column(db.Unicode(50), nullable=False, server_default=u'') institution = db.Column(db.Unicode(300), server_default=u'') administrator= db.Column(db.Boolean,default=False,nullable=False) def object_is_shared(self,genome,type,object_id): p = db.session.query(SharedObject.owner).filter_by(shared_with=self.id,type=type,genome=genome,object_id= object_id).first() if p: return p.owner return False def has_permission(self,permission,value=None): if self.administrator: return True if not value: p = db.session.query(Permission).filter_by(user_id=self.id,permission=permission).first() if p: return p.value return None else: p = db.session.query(Permission).filter_by(user_id=self.id,permission=permission,value=value).first() if p: return True return False def delete_user(self): sql = "SELECT id FROM projects WHERE owner= %s" res= databases["system"].execute_query(sql,(self.id,)) for r in res: p=get_project(r["id"]) p.delete(True) db.session.delete(self) db.session.commit() @staticmethod def get_all_shared_objects(genome,user_id,type,limit=5,offset=0,simple=True): '''Gets the id's of all object's that have been shared with the user Args: genome(str):The name of the genome(database) user_id(int): The id of the user type(str) The type of object : - project,viewset,plugin simple (Optional[boolean]):If True (default) only a list of project ids will be returned otherwise a dicationary of project ids to a list of sharer id,firstname,secondname Returns: Either a list of project ids or a dictionary of ids to a list containing sharerid, firstname, lastname ''' if simple: ids = db.session.query(SharedObject.object_id).filter_by(genome=genome,shared_with=user_id,type=type).all() li =[] for i in ids: li.append(i) return li else: ret_dict={} sql= ("SELECT date_shared,object_id,users.id AS uid,users.first_name AS ufn ,users.last_name uln" " FROM shared_objects INNER JOIN users ON genome = '{}' AND shared_with = {}" " AND type = '{}' AND users.id = shared_objects.owner ORDER BY date_shared DESC" " LIMIT {} OFFSET {}").format(genome,str(user_id),type,limit,offset) results= db.engine.execute(text(sql)) for res in results: ret_dict[res.object_id]=[res.uid,res.ufn,res.uln,res.date_shared] return ret_dict def add_all_create_permissions(self): for project in app.config["MLV_PROJECTS"]: p = app.config["MLV_PROJECTS"][project] if p.get("is_public") and p.get("can_create"): perm = Permission(user_id=self.id,permission="create_project_type",value=project) db.session.add(perm) db.session.commit() def add_create_permission(self,project_type): if not self. has_permission("create_project_type",project_type): perm = Permission(user_id=self.id,permission="create_project_type",value=project_type) db.session.add(perm) db.session.commit() def add_permission(self,permission,value): if not self. has_permission(permission,value): perm = Permission(user_id=self.id,permission=permission,value=value) db.session.add(perm) db.session.commit() def add_view_permission(self,project_type): if not self. has_permission("view_project_type",project_type): perm = Permission(user_id=self.id,permission="view_project_type",value=project_type) db.session.add(perm) db.session.commit() @staticmethod def get_create_permissions(user,genome): '''Checks whether the user has create permissions for plugins.This is a static method as the user may be an AnonymousUserMixin Args: user:the current user (can be AnonymousUserMixin) genome:the genome for which the permissions are to be checked Returns: a list of plugins for which the user has permission to create returns an empty list if the user has no permissions ''' li=[] if not user.is_authenticated: return li for project in app.config['MLV_PROJECTS']: li.append("create_"+project+"_project") if user.administrator: return li perms = db.session.query(Permission.permission).filter(Permission.permission.in_(li), Permission.user_id==user.id, Permission.genome==genome) li=[] for p in perms: li.append(p.permission) return li @staticmethod def find_user_name(term,limit=10): term="%"+term+"%" ret_list=[] results =User.query.filter(or_(User.first_name.ilike(term),User.last_name.ilike(term))).\ order_by(User.last_name).limit(limit).all() for res in results: ret_list.append({ "label":res.first_name+" "+res.last_name, "value":res.id }) return ret_list
class User(Model, UserMixin): __tablename__ = 'users' username = db.Column(db.String(80), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) password = db.Column(db.String(128), nullable=True) created_at = db.Column(db.DateTime, nullable=False, default=dt.datetime.utcnow) active = db.Column(db.Boolean(), default=False) is_admin = db.Column(db.Boolean(), default=False) def __init__(self, username, email, password=None, **kwargs): db.Model.__init__(self, username=username, email=email, **kwargs) if password: self.set_password(password) else: self.password = None def set_password(self, password): self.password = bcrypt.generate_password_hash(password) def check_password(self, value): return bcrypt.check_password_hash(self.password, value) @classmethod def get_admin_user(cls): return cls.query.filter_by(username=SETTINGS["admin_username"]).first() @classmethod def admin_user_id(cls): return 1 @classmethod def login_user(cls, username, password): user = cls.query.filter_by(username=username).first() if user and user.check_password(password): return user else: return None @classmethod def register_user(cls, username, email, password, r_password): if re.search(r'[\s]', username): return "username can't contain spaces" if not re.match(r"[^@]+@[^@]+\.[^@]+", email): return "You must use a valid email address" if password != r_password: return "Your passwords don't match" if len(password) < 7: return "Your password must be atleast 7 characters" user = cls.query.filter_by(username=username).first() if user: return "That username is taken" user = cls.query.filter_by(email=email).first() if user: return "That email address is already in use" return cls.create(username=username, email=email, password=password) @property def writeable(self): return {"username": self.username, "id": self.id} def __repr__(self): return '<User({username!r})>'.format(username=self.username)
class User(db.Model): __tablename__ = 'user' __table_args__ = (dict(sqlite_autoincrement=True)) __searchable__ = ['first_name', 'last_name', 'room_no'] id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), nullable=False) email = db.Column(db.String(80), nullable=False) #: The hashed password password = db.Column(db.String(128), nullable=False) first_name = db.Column(db.String(30), nullable=True) last_name = db.Column(db.String(30), nullable=True) phone_number = db.Column(db.String(11)) d_o_b = db.Column(db.String(120)) gender = db.Column(db.String(10)) profile_pic = db.Column(db.String(200)) # student info matric_no = db.Column(db.String(13)) option = db.Column(db.String(40)) hostel_address = db.Column(db.String(80)) interests = db.Column(db.Text) # lecturer info room_no = db.Column(db.String(8)) specialization = db.Column(db.String(80)) degree = db.Column(db.String(80)) # role is_admin = db.Column(db.Boolean(), default=False) is_what = db.Column(db.String(10)) #post #posts = db.relationship('Post', backref='author', lazy='dynamic') def __init__(self, username, email, password=None, **kwargs): """Create instance.""" db.Model.__init__(self, username=username, email=email, password=password, **kwargs) # if password: # self.set_password(password) # else: # self.password = None # def set_password(self, password): # """Set password.""" # self.password = bcrypt.generate_password_hash(password) # def check_password(self, value): # """Check password.""" # return bcrypt.check_password_hash(self.password, value) @property def full_name(self): """Full user name.""" return '{0} {1}'.format(self.first_name, self.last_name) def __repr__(self): """Represent instance as a unique string.""" return '<User({username!r})>'.format(username=self.username)
class User(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), index=True, unique=True) email = db.Column(db.String(120), index=True, unique=True) password = db.Column(db.String(128)) posts = db.relationship('Post', backref='author', lazy='dynamic') about_me = db.Column(db.String(140)) last_seen = db.Column(db.DateTime, default=datetime.utcnow) image_file = db.Column(db.String(20), default='default.jpg') active = db.Column(db.Boolean()) confirmed_at = db.Column(db.DateTime()) roles = db.relationship('Role', secondary=roles_users, backref=db.backref('users', lazy='dynamic')) followed = db.relationship('User', secondary=followers, primaryjoin=(followers.c.follower_id == id), secondaryjoin=(followers.c.followed_id == id), backref=db.backref('followers', lazy='dynamic'), lazy='dynamic') notifications = db.relationship('Notification', backref='user', lazy='dynamic') messages_sent = db.relationship('Message', foreign_keys='Message.sender_id', backref='author', lazy='dynamic') messages_received = db.relationship('Message', foreign_keys='Message.recipient_id', backref='recipient', lazy='dynamic') last_message_read_time = db.Column(db.DateTime) def new_messages(self): last_read_time = self.last_message_read_time or datetime(1900, 1, 1) return Message.query.filter_by(recipient=self).filter( Message.timestamp > last_read_time).count() def set_password(self, raw_password): self.password = generate_password_hash(raw_password) def check_password(self, raw_password): return check_password_hash(self.password, raw_password) def avatar(self, size): digest = md5(self.email.lower().encode('utf-8')).hexdigest() return 'https://www.gravatar.com/avatar/{}?d=identicon&s={}'.format( digest, size) def add_notification(self, name, data): self.notifications.filter_by(name=name).delete() n = Notification(name=name, payload_json=json.dumps(data), user=self) db.session.add(n) return n # Implementing followers def follow(self, user): if not self.is_following(user): self.followed.append(user) def unfollow(self, user): if self.is_following(user): self.followed.remove(user) def is_following(self, user): # Check if a link between two users already exists return self.followed.filter( followers.c.followed_id == user.id).count() > 0 # Obtaining the Posts from Followed Users def followed_posts(self): followed = Post.query.join( followers, (followers.c.followed_id == Post.user_id)).filter( followers.c.follower_id == self.id) # Users own posts own = Post.query.filter_by(user_id=self.id) # Return a combination of users posts and followers post # order by the date of the posts return followed.union(own).order_by(Post.timestamp.desc()) #Implementing reset email functionality def get_reset_password_token(self, expires_in=600): return jwt.encode( { 'reset_password': self.id, 'exp': time() + expires_in }, current_app.config['SECRET_KEY'], algorithm='HS256').decode('utf-8') @staticmethod def verify_reset_password_token(token): try: id = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])['reset_password'] except: return return User.query.get(id) def __repr__(self): return '<User {}>'.format(self.username)
class Team(db.Model): __tablename__ = "teams" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String, nullable=False, unique=True) description = db.Column(db.String) created_by = db.Column(db.Integer, db.ForeignKey("users.id")) created_at = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(), nullable=False) updated_at = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(), nullable=False) is_active = db.Column(db.Boolean(), default=True) user_team = db.relationship("UserTeam", backref="team", lazy='dynamic', cascade="all, delete") user_requests = db.relationship("JoinTeamRequest", backref="team", lazy='dynamic', cascade="all, delete") @classmethod def get_team_by_name(cls, name): name = name.strip() team = cls.query.filter_by(name=name).first() if not team: raise TeamNotFound return team @classmethod def search_team_by_part_name(cls, part_name): return cls.query.filter(cls.name.contains(part_name)).all() @classmethod def create_team(cls, name, description, creator_id): name = name.strip() description = description.strip() try: cls.check_team_name(name=name) except Exception as e: raise e if cls.query.filter_by(name=name).first(): raise TeamExists team = cls(name=name, description=description) team.created_by = creator_id team.save() UserTeam.admit_user_to_team(team=team, user_id=creator_id, admitted_by=creator_id) return team def update_team(self, name=None, description=None): self.name = name.strip() or self.name try: self.check_team_name(name=name) except Exception as e: raise e self.description = description.strip() or self.description self.save() def save(self): db.session.add(self) db.session.commit() def get_all_users(self): return list( set(user_team.team_member for user_team in self.user_team.all())) def get_pending_requests(self): return list( set((user_request.user, user_request.id) for user_request in self.user_requests.all())) def toggle_status(self): self.is_active = not self.is_active self.save() def delete(self): db.session.delete(self) db.session.commit() @staticmethod def check_team_name(name=None): if not name: raise InvalidTeamName("Team name cannot be empty") if "/" in name: raise InvalidTeamName("Team name cannot contain '/'")
class User(db.Model, UserMixin): __tablename__ = 'user' id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(63), unique=True) passwordhash = db.Column(db.String(127), nullable=False) salt = db.Column(db.String(127), nullable=False) active = db.Column(db.Boolean(), default=False) admin = db.Column(db.Boolean(), default=False) status = db.Column(db.Enum('none', 'applying', 'pass', 'reject', 'banned'), default='none') name = db.Column(db.String(127)) studentno = db.Column(db.String(127)) phone = db.Column(db.String(127)) reason = db.Column(db.Text) applytime = db.Column(db.DateTime) vpnpassword = db.Column(db.String(127)) rejectreason = db.Column(db.Text) banreason = db.Column(db.Text) def __init__(self, email, password): self.email = email self.set_password(password) def set_password(self, password): self.salt = random_string(10) s = hashlib.sha256() s.update(password.encode('utf-8')) s.update(self.salt.encode('utf-8')) self.passwordhash = s.hexdigest() def check_password(self, password): s = hashlib.sha256() s.update(password.encode('utf-8')) s.update(self.salt.encode('utf-8')) return self.passwordhash == s.hexdigest() def enable_vpn(self): if not VPNAccount.get_account_by_email(self.email): if self.vpnpassword is None: self.generate_vpn_password() VPNAccount.add(self.email, self.vpnpassword) def disable_vpn(self): if VPNAccount.get_account_by_email(self.email): VPNAccount.delete(self.email) def change_vpn_password(self): self.generate_vpn_password() VPNAccount.changepass(self.email, self.vpnpassword) @classmethod def get_applying(cls): return cls.query.filter_by(status='applying').all() @classmethod def get_rejected(cls): return cls.query.filter_by(status='reject').all() def pass_apply(self): self.status = 'pass' self.enable_vpn() self.save() def reject_apply(self, reason=''): self.status = 'reject' self.rejectreason = reason self.save() def ban(self, reason=''): self.status = 'banned' self.banreason = reason self.disable_vpn() self.save() def unban(self): self.status = 'pass' self.enable_vpn() self.save() def save(self): db.session.add(self) db.session.commit() @classmethod def get_user_by_email(cls, email): return cls.query.filter_by(email=email).first() @classmethod def get_user_by_id(cls, id): return cls.query.get(id) def get_record(self): return Record.query.filter_by(username=self.email).order_by(Record.radacctid.desc()).first() def get_records(self, n): return Record.query.filter_by(username=self.email).order_by(Record.radacctid.desc()).limit(n) def generate_vpn_password(self): self.vpnpassword = random_string(8) self.save() @classmethod def get_users(cls): return cls.query.filter(db.or_(cls.status == 'pass', cls.status == 'banned'))
class User(db.Model, UserMixin): """ Definition of the User model for the database """ __tablename__ = "users" __bind_key__ = 'innuendo_database' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(120), index=True, unique=True) name = db.Column(db.String(255)) gid = db.Column(db.String(255)) homedir = db.Column(db.String(255)) password = db.Column('password', db.String(255)) active = db.Column(db.Boolean()) email = db.Column(db.String(120), index=True, unique=True) roles = db.relationship('Role', secondary=roles_users, backref=db.backref('users', lazy='dynamic')) projects = db.relationship('Project', backref='author', lazy='dynamic') analysis_parameters_object = db.Column(JSON) @staticmethod def try_login(email, password): """LDAP login Function to login to the LDAP server based on the username and password Parameters ---------- email: str Username of the ldap user password: str Password of the ldap user Returns ------- bool: Returns false if error on login Object: User entry if successful connection """ conn = get_ldap_connection() try: conn.simple_bind_s("cn=" + email + ",ou=users," + baseDN, password) except Exception as e: print e return False search_filter = "uid=" + email entry = "" result = conn.search_s(baseDN, ldap.SCOPE_SUBTREE, search_filter) for dn, ent in result: entry = ent break conn.unbind() if entry != "": return entry else: return False @staticmethod def change_pass(email, old, new_password): """Change LDAP password method Function to change the password of the LDAP user. It requires the username, the old password and a new password. It binds to the ldap server and then performs the operation by storing the encrypted password in the ldap database. Parameters ---------- email: str Username of the ldap user old: str Old password new_password: str New password Returns ------- bool: True if successfully changed the password, False if not. """ conn = get_ldap_connection() try: # Reset Password password_value_old = {"userPassword": ldap_md5.encrypt(str(old))} password_value_new = { "userPassword": ldap_md5.encrypt(str(new_password)) } conn.simple_bind_s("cn=" + email + ",ou=users," + baseDN, old) ldif = modlist.modifyModlist(password_value_old, password_value_new) conn.modify_s("cn=" + email + ",ou=users," + baseDN, ldif) conn.unbind() return True except Exception as e: return False
class Sensor(db.Model): sensor_id = db.Column(db.String(64), primary_key=True) fixed = db.Column(db.Boolean()) lat = db.Column(db.Float()) lon = db.Column(db.Float()) alt = db.Column(db.Float()) points = db.relationship('Point', backref='sensor', lazy='dynamic') readings = db.relationship('Reading', backref='sensor', lazy='dynamic') # TODO Add pressure_offset for fixed=false def __repr__(self): return '<Sensor {}>'.format(self.sensor_id) def save(self): db.session.add(self) db.session.commit() def jsonify(self): if self.fixed: return { 'sensor_id': self.sensor_id, 'fixed': self.fixed, 'lat': self.lat, 'lon': self.lon, 'alt': self.alt } else: return {'sensor_id': self.sensor_id, 'fixed': self.fixed} def csvify(self): return {self.sensor_id, self.fixed, self.lat, self.lon, self.alt} @staticmethod def csv_headers(self): return {'sensor_id', 'fixed', 'latitude', 'longitude', 'elevation'} @staticmethod def get_all(): return Sensor.query.all() @staticmethod def get_all_ids(): return db.session.query(Sensor.sensor_id).distinct().all() @staticmethod def get(sensorId): return Sensor.query.filter_by(sensor_id=sensorId).first() @staticmethod def saveJson(jsonReq): sensor_id = str(jsonReq.get('sensor_id', '')) fixed = jsonReq.get('fixed', False) lat = jsonReq.get('lat') lon = jsonReq.get('lon') alt = jsonReq.get('alt') # verify required fields if (sensor_id and fixed and lat and lon and alt) or (sensor_id and not fixed): # create sensor, save & return sensor = Sensor(sensor_id=sensor_id, fixed=fixed, lat=lat, lon=lon, alt=alt) sensor.save() return sensor
class Project(db.Model): __tablename__ = 'projects' id = db.Column(db.Integer, primary_key=True) short_name = db.Column(db.Unicode(16), nullable=False, server_default=u'', unique=True) long_name = db.Column(db.Unicode(255), nullable=False, server_default=u'') description = db.Column(db.Unicode(255), nullable=False, server_default=u'') active = db.Column(db.Boolean(), nullable=False, server_default='1') insert_date = db.Column(db.DateTime, nullable=False, default=datetime.now) # Relationships admins = db.relationship('user_models.User', secondary='projects_admins', backref=db.backref('admin_for_project', lazy='dynamic')) reviewers = db.relationship('user_models.User', secondary='projects_reviewers', backref=db.backref('reviewer_for_project', lazy='dynamic')) users = db.relationship('user_models.User', secondary='projects_users', backref=db.backref('user_for_project', lazy='dynamic')) data_pool_objects = db.relationship('data_pool_models.DataPool', back_populates='project', cascade="all, delete-orphan") split_types = db.relationship('data_pool_models.SplitType', back_populates='project', cascade="all, delete-orphan") modalities = db.relationship('data_pool_models.Modality', back_populates='project', cascade="all, delete-orphan") contrast_types = db.relationship('data_pool_models.ContrastType', back_populates='project', cascade="all, delete-orphan") automatic_segmentation_models = db.relationship('data_pool_models.AutomaticSegmentationModel', back_populates='project', cascade="all, delete-orphan") def __repr__(self): return f'{self.short_name}' def as_dict(self): # Project meta data result = {c.name: getattr(self, c.name) for c in Project.__table__.columns} # Users result["users"] = [] result["users"].extend((u.as_dict(), "admin") for u in self.admins) result["users"].extend((u.as_dict(), "review") for u in self.reviewers) result["users"].extend((u.as_dict(), "segmentation") for u in self.users) # split_types, Modalities and contrast_types result["split_types"] = [s.name for s in self.split_types] result["modalities"] = [m.name for m in self.modalities] result["contrast_types"] = [c.name for c in self.contrast_types] result["automatic_segmentation_models"] = [m.as_dict() for m in self.automatic_segmentation_models] return result """ Returns a path where the requested image can be found or stored depending on the type of the image. The valid types include: 'image' => Raw case images, e.g. when a new case is created 'manual_segmentation' => Result of the manual segmentation of a user 'automatic_segmentation' => Result of the automatic segmentation via a machine learning model In this case, the model needs to be defined. The model then defines the concrete directory of the image """ def get_image_path(self, image_type = 'image', model_id = None, image_id = None, create_dir = True): if image_id is None: app.logger.error("No image id provided") return None image_dir = None if image_type == 'image': image_dir = os.path.join(app.config['DATA_PATH'], self.short_name, "images") elif image_type == 'manual_segmentation': image_dir = os.path.join(app.config['DATA_PATH'], self.short_name, "manual_segmentations") elif image_type == 'automatic_segmentation': if model_id is None: app.logger.error("No model id provided") return None image_dir = os.path.join(app.config['DATA_PATH'], self.short_name, "automatic_segmentation", f"model_{model_id}") else: app.logger.error(f"Image type {image_type} is not recognized. Returning none") return None if create_dir and not os.path.exists(image_dir): os.makedirs(image_dir, exist_ok = True) return os.path.join(image_dir, f'{image_id}.nii.gz') @property def role_admins(self): return self.admins @property def role_reviewers(self): return self.admins + self.reviewers @property def role_users(self): return self.admins + self.reviewers + self.users
class Reading(db.Model): sensor_id = db.Column(db.String(64), db.ForeignKey('sensor.sensor_id'), primary_key=True) time = db.Column(db.DateTime, primary_key=True) calibration = db.Column(db.Boolean()) height = db.Column(db.Float()) lat = db.Column(db.Float()) lon = db.Column(db.Float()) lat_lon_sd = db.Column(db.Float()) uncal_pressure = db.Column(db.Float()) uncal_pressure_sd = db.Column(db.Float()) uncal_temperature = db.Column(db.Float()) uncal_temperature_sd = db.Column(db.Float()) sample_count = db.Column(db.Integer()) __table_args__ = (db.UniqueConstraint('sensor_id', 'time', name='sensor_time_uc'), ) def __repr__(self): return '<Reading {}>'.format(self.sensor_id, self.time) def save(self): db.session.add(self) db.session.commit() def jsonify(self): return { 'sensor_id': self.sensor_id, 'calibration': self.calibration, 'time': self.time, 'height': self.height, 'lat': self.lat, 'lon': self.lon, 'lat_lon_sd': self.lat_lon_sd, 'uncal_pressure': self.uncal_pressure, 'uncal_pressure_sd': self.uncal_pressure_sd, 'uncal_temprature': self.uncal_temperature, 'uncal_temprature_sd': self.uncal_temperature_sd, 'sample_count': self.sample_count } def csvify(self): return { self.sensor_id, self.calibration, self.time, self.duration, self.lat, self.lon, self.lat_lon_sd, self.uncal_pressure, self.uncal_pressure_sd, self.uncal_temperature, self.uncal_temperature_sd, self.sample_count } @staticmethod def saveJson(jsonItem): s_id = jsonItem.get('sensor_id') time = jsonItem.get('time') reading = Reading( sensor_id=s_id, calibration=jsonItem.get('calibration'), time=datetime.datetime.fromtimestamp(time), height=jsonItem.get('height'), lat=jsonItem.get('lat'), lon=jsonItem.get('lon'), lat_lon_sd=jsonItem.get('lat_lon_sd'), uncal_pressure=jsonItem.get('uncal_pressure'), uncal_pressure_sd=jsonItem.get('uncal_pressure_sd'), uncal_temperature=jsonItem.get('uncal_temperature'), uncal_temperature_sd=jsonItem.get('uncal_temperature_sd'), sample_count=jsonItem.get('sample_count')) reading.save() return reading @staticmethod def csv_headers(self): return { 'sensor_id', 'calibration', 'time', 'duration', 'lat', 'lon', 'lat_lon_sd', 'uncal_pressure', 'uncal_pressure_sd', 'uncal_temprature', 'uncal_temprature_sd', 'sample_count' } @staticmethod def get_all(): return Reading.query.all() @staticmethod def get_sensor(sensorId, count): return Reading.query.filter_by(sensor_id=sensorId).order_by( Reading.time.desc()).limit(count).all() @staticmethod def get_range(start, end): return Reading.query.filter( Reading.time.between(datetime.datetime.fromtimestamp(start), datetime.datetime.fromtimestamp(end))) @staticmethod def get_sensor_range(sensorId, start, end): return Reading.query.filter_by(sensor_id=sensorId).filter( Reading.time.between(datetime.datetime.fromtimestamp(start), datetime.datetime.fromtimestamp(end)))
class User(db.Model): __tablename__ = "users" id = db.Column(db.Integer, primary_key=True, autoincrement=True) username = db.Column(db.String(128), unique=True, nullable=False) email = db.Column(db.String(128), unique=True, nullable=False) password = db.Column(db.String(255), nullable=False) active = db.Column(db.Boolean(), default=True, nullable=False) created_at = db.Column(db.DateTime, nullable=False) def __init__(self, username, email, password, created_at=datetime.datetime.utcnow()): self.username = username self.email = email self.password = bcrypt.generate_password_hash( password, current_app.config.get('BCRYPT_LOG_ROUNDS')).decode() self.created_at = created_at def save(self): if not self.username or not self.email or not self.password: raise ValueError try: db.session.add(self) db.session.commit() except Exception as e: db.session.rollback() raise @staticmethod def login(email, password): if not email or not password: raise ValueError try: user = User.query.filter_by(email=email).one() except NoResultFound: raise if not bcrypt.check_password_hash(user.password, password): raise NoResultFound return user def get_data(self): return { 'id': self.id, 'username': self.username, 'email': self.email, 'created_at': self.created_at, 'active': self.active } @staticmethod def get_by_id(user_id): """Gets a user by its id""" try: user = User.query.get(user_id) except exc.DataError: return None return None if not user else user.get_data() @staticmethod def get_all_users(): """Returns all users""" users_list = [] for user in User.query.order_by(User.created_at.desc()).all(): users_list.append(user.get_data()) return users_list @staticmethod def get_token_from_authorization_header(authorization_header): try: return authorization_header.split(" ")[1] except Exception: return 'Invalid authorization header.' @staticmethod def encode_auth_token(user_id): """Encodes the JWT based on user id :rtype: bytes|string :param user_id: the user id :return: encoded JWT """ try: payload = { # Expiration Time Claim (exp) 'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=current_app.config.get( 'JWT_EXPIRATION_TIME_SECONDS')), # Issued At Claim (iat) 'iat': datetime.datetime.utcnow(), # Subject (sub) 'sub': user_id } return jwt.encode(payload, current_app.config.get('SECRET_KEY'), algorithm='HS256') except Exception: return 'Could not encode token.' @staticmethod def decode_auth_token(auth_token): """Decodes auth token """ try: payload = jwt.decode(auth_token, current_app.config.get('SECRET_KEY'), algorithms='HS256') return payload['sub'] except jwt.ExpiredSignatureError: return 'Expired token, please login again.' except jwt.InvalidTokenError: return 'Invalid token.' except Exception: return 'Could not decode token.'
class UserModel(db.Model, UserMixin): __tablename__ = 'user' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), index=True, unique=True) short_name = db.Column(db.String(64), index=True, nullable=True) email = db.Column(db.String(120), index=True, unique=True) password = db.Column(db.String(255), nullable=False, server_default='') active = db.Column(db.Boolean(), default=True) confirmed_at = db.Column(db.DateTime, index=True) upload_histories = db.relationship( UploadHistoryModel, order_by='desc(UploadHistoryModel.date_uploaded)', backref='user', lazy='dynamic') company_id = db.Column(db.Integer, db.ForeignKey('company.id'), nullable=True) roles = db.relationship('RoleModel', secondary=roles_users, backref=db.backref('users', lazy='dynamic')) token = db.Column(db.String(32), index=True, unique=True) token_expiration = db.Column(db.DateTime) def __init__(self, username, email): self.email = email self.username = username def set_password(self, password): self.password = bcrypt.encrypt(password) def check_password(self, password): return bcrypt.verify(self.password, password) def save_to_db(self): db.session.add(self) db.session.commit() def delete_from_db(self): db.session.delete(self) db.session.commit() @classmethod def get_admins(cls): return cls.query.filter( UserModel.roles.any(RoleModel.name.startswith('Admin'))).all() @classmethod def find_by_username(cls, username): return cls.query.filter_by(username=username).first() @classmethod def find_by_email(cls, email): return cls.query.filter_by(email=email.lower()).first() def __str__(self): return self.username def __repr__(self): return '<User {}>'.format(self.email) def get_token(self, expires_in=3600): now = datetime.utcnow() if self.token and self.token_expiration > now + timedelta(seconds=60): return self.token self.token = base64.b64encode(os.urandom(24)).decode('utf-8') self.token_expiration = now + timedelta(seconds=expires_in) db.session.add(self) db.session.commit() return self.token def revoke_token(self): self.token_expiration = datetime.utcnow() - timedelta(seconds=1) @staticmethod def check_token(token): user = UserModel.query.filter_by(token=token).first() if user is None or user.token_expiration < datetime.utcnow(): return None return user def get_reset_password_token(self, expires_in=600): return jwt.encode( { 'reset_password': self.id, 'exp': time() + expires_in }, current_app.config['SECRET_KEY'], algorithm='HS256').decode('utf-8') @staticmethod def verify_reset_password_token(token): try: id = jwt.decode(token, current_app.config['SECRET_KEY'], algorithms=['HS256'])['reset_password'] except: return return UserModel.query.get(id) def generate_confirmation_token(self): serializer = URLSafeTimedSerializer(current_app.config['SECRET_KEY']) return serializer.dumps( self.email, salt=current_app.config['SECURITY_PASSWORD_SALT']) def confirm_token(token, expiration=3600): serializer = URLSafeTimedSerializer(current_app.config['SECRET_KEY']) try: email = serializer.loads( token, salt=current_app.config['SECURITY_PASSWORD_SALT'], max_age=expiration) except: return False return email
class User(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), index=True, unique=True) email = db.Column(db.String(128), index=True, unique=True, nullable=False) password_hash = db.Column(db.String(128), nullable=False) is_admin = db.Column(db.Boolean(), default=False) description = db.Column(db.String(240)) confirmed = db.Column(db.Boolean(), nullable=False, default=False) last_seen = db.Column(db.DateTime, default=func.now()) polls = db.relationship("Poll", backref="author", lazy="dynamic", cascade="all,delete") votes = db.relationship("Votes", backref="voter", lazy="dynamic", cascade="all,delete") """ Simple function for returning whether a user has voted in a given poll """ def has_voted(self, poll_id): poll = Poll.query.filter_by(id=id).first() if (not poll): return (False) responses = poll.poll_votes for response in responses: if (response.user_id == self.id): return (True) return (False) """ Function to change a user's email confirmation status to true when their email is confirmed. """ def confirm(self): self.confirmed = True db.session.commit() """ Function for generating a JWT email confirmation token """ def generate_confirmation_token(self, expires_in=600): return (jwt.encode( { "confirmation_token": self.id, "exp": time() + expires_in }, app.config["SECRET_KEY"], algorithm="HS256").decode("utf-8")) """ Function for confirming JWT email confirmation token. """ @staticmethod def verify_confirmation_token(token): try: id = jwt.decode(token, app.config["SECRET_KEY"], algorithms=["HS256"])["confirmation_token"] except: return return (User.query.get(id)) """ Function for generating JWT token for password resets. """ def get_reset_password_token(self, expires_in=600): return (jwt.encode( { "reset_password": self.id, "exp": time() + expires_in }, app.config["SECRET_KEY"], algorithm="HS256").decode("utf-8")) """ Function for verifying JWT password reset token. """ @staticmethod def verify_reset_token(token): try: id = jwt.decode(token, app.config["SECRET_KEY"], algorithms=["HS256"])["reset_password"] except: return return (User.query.get(id)) """ Function for deleting the user and any stored profile pictures they may have. """ def delete(self): for file in os.listdir(USER_UPLOAD_FOLDER): file_id = file.split(".")[0] if (file_id == self.username): path = USER_UPLOAD_FOLDER + file os.remove(path) db.session.delete(self) db.session.commit() """ Function that returns the URL for a user's display picture if stored in the application, otherwise uses Gravatar to generate a unique avatar and returns its URL. """ def avatar(self, size): for file in os.listdir(USER_UPLOAD_FOLDER): file_id = file.split(".")[0] if (file_id == self.username): return (url_for("static", filename="user-images/" + file)) digest = md5(self.email.lower().encode("utf-8")).hexdigest() return (("https://www.gravatar.com/avatar/{}?d=retro&s={}").format( digest, size)) """ Function for hashing a provided password and setting it to be the user's password """ def set_password(self, password): self.password_hash = generate_password_hash(password) """ Function for checking whether a provided password matches the user's stored hash. """ def check_password(self, password): return (check_password_hash(self.password_hash, password)) """ Function that returns whether a user is an admin. """ def get_admin(self): return (self.is_admin) """ Function for changing a user's admin status """ def set_admin(self, status): self.is_admin = status db.session.commit() def __repr__(self): return ("User<{}>".format(self.username))
class User(db.Model): """This class defines the users table """ __tablename__ = 'users' # Define the columns of the users table, starting with the primary key id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(15), nullable=False) email = db.Column(db.String(25), nullable=False, unique=True) password = db.Column(db.String(100)) email_confirmed = db.Column(db.Boolean(False)) eventlists = db.relationship('Events', order_by='Events.id', cascade="all, delete-orphan") myrsvps = db.relationship('Events', secondary=rsvps, backref=db.backref('rsvpList', lazy='dynamic'), lazy='dynamic') def __init__(self, name, email, password, email_confirmed): """Initialize the user with a name, an email, a password and email not confirmed.""" self.name = name self.email = email self.email_confirmed = email_confirmed self.password = Bcrypt().generate_password_hash(password).decode() def password_is_valid(self, password): """ Checks the password against it's hash to validates the user's password """ return Bcrypt().check_password_hash(self.password, password) def save(self): """Save a user to the database. This includes creating a new user and editing one. """ db.session.add(self) db.session.commit() @staticmethod def update_user_data(): """ Save a new user password to the database. Save new email confirmation """ db.session.commit() @staticmethod def generate_token(user_id): """ Generates the access token""" try: # set up a payload with an expiration time payload = { 'exp': datetime.utcnow() + timedelta(minutes=1440), 'iat': datetime.utcnow(), 'sub': user_id } # create the byte string token using the payload and the SECRET key jwt_string = jwt.encode(payload, current_app.config.get('SECRET'), algorithm='HS256') return jwt_string except Exception as error: # return an error in string format if an exception occurs return str(error) @staticmethod def decode_token(token): """Decodes the access token from the Authorization header.""" try: # try to decode the token using our SECRET variable payload = jwt.decode(token, current_app.config.get('SECRET')) is_blacklisted_token = BlacklistToken.check_blacklist(token) if is_blacklisted_token: return 'Token blacklisted. Please log in again.' else: return payload['sub'] return payload['sub'] except jwt.ExpiredSignatureError: # the token is expired, return an error string return "Expired token. Please login to get a new token" except jwt.InvalidTokenError: # the token is invalid, return an error string return "Invalid token. Please register or login" def __str__(self): return """User(id={}, name={}, email={}, events={}, email_confirmed={})""".format( self.id, self.name, self.email, self.myrsvps.all(), self.email_confirmed) __repr__ = __str__
class Task(db.Model): id = db.Column(db.Integer, primary_key=True) owner_id = db.Column(db.Integer, db.ForeignKey('person.id'), nullable=False) due = db.Column(db.DateTime, nullable=False) title = db.Column(db.String(), nullable=False) body = db.Column(db.String(), nullable=False) important = db.Column(db.Boolean(), nullable=False) done = db.Column(db.Boolean(), nullable=False) token = db.Column(db.String(64)) def to_dict(self): data = { 'id': self.id, 'token': self.token, 'owner_id': self.owner_id, 'due': self.due.strftime("%Y-%m-%d"), 'title': self.title, 'body': self.body, 'important': self.important, 'done': self.done } return data def from_dict(dct): t = Task( id=dct['id'], owner_id=dct['owner_id'], token=dct['token'], due=dt.datetime.strptime(dct['due'], "%Y-%m-%d"), title=dct['title'], body=dct['body'], important=dct['important'], done=dct['done']) return t def add(task_dict): """ task_dict: { 'owner_token' : str(64) -> person.token, 'due': datetime.datetime, 'title': str(), 'body': str(), 'important': bool(), 'done': bool() } """ p = Person.get(task_dict['owner_token']) if not p: raise Exception('Owner does not exist!') try: t = Task( owner_id= p.id, due= task_dict['due'], title= task_dict['title'], body= task_dict['body'], important= task_dict['important'], done= task_dict['done'], token=token_urlsafe(32) ) except: raise Exception('Problem in request dict') redis_client.delete(Person.get_id(t.owner_id).token + '-tasks') db.session.add(t) db.session.commit() redis_client.set(t.token, json.dumps(t.to_dict()), ex=1800) return t def get(_token): t_redis = redis_client.get(_token) if t_redis: return Task.from_dict(json.loads(t_redis)) else: t = Task.query.filter_by(token=_token).first() if not t: raise Exception('Task does not exist!') else: redis_client.set(_token, json.dumps(t.to_dict()), ex=1800) return t def toggle_done(_token): t = Task.query.filter_by(token=_token).first() if not t: raise Exception('Task does not exist!') else: t.done = not t.done db.session.commit() redis_client.delete(Person.get_id(t.owner_id).token + '-tasks') redis_client.delete(t.token) redis_client.set(t.token, json.dumps(t.to_dict), ex=1800) return t.to_dict() def get_all(_token): p_redis = redis_client.get(_token) if p_redis: p = Person.from_dict(json.loads(p_redis)) else: p = Person.get(_token) if not p: raise Exception('Owner does not exist!') tasks_redis = redis_client.get(_token + '-tasks') if tasks_redis: tasks = json.loads(tasks_redis) else: tasks = list(Task.query.filter_by(owner_id=p.id)) res = [] for t in tasks: res.append(t.to_dict()) tasks = res print(tasks, tasks_redis) if not tasks_redis: redis_client.set(_token + "-tasks", json.dumps(tasks), ex=1800) return tasks def delete(_token): t_redis = redis_client.get(_token) if t_redis: t = Task.from_dict(json.loads(t_redis)) else: t = Task.query.filter_by(token=_token).first() if not t: raise Exception('Task does not exist!') else: redis_client.delete(_token) redis_client.delete(Person.get_id(t.owner_id).token + '-tasks') db.session.delete(Task.get(t.token)) db.session.commit() return 'Task deleted'
class User(db.Model, UserMixin): """ Utilisateur """ __tablename__ = 'user' id = db.Column(db.Integer, primary_key=True, autoincrement=True) # User authentication information username = db.Column(db.String(), nullable=False, unique=True) password = db.Column(db.String(), nullable=False, server_default='') # User email information email = db.Column(db.String(), nullable=False, unique=True) email_confirmed_at = db.Column('confirmed_at', db.DateTime()) # User information active = db.Column('is_active', db.Boolean(), nullable=False, server_default='0') first_name = db.Column('firstname', db.String(), nullable=False, server_default='') last_name = db.Column('lastname', db.String(), nullable=False, server_default='') roles = db.relationship('UserRole', secondary=association_user_has_role) bookmarks = db.relationship("Document", secondary=association_user_has_bookmark) @staticmethod def add_default_users(): password = "******" admin = UserRole.query.filter(UserRole.name == "admin").first() contributor = UserRole.query.filter( UserRole.name == "contributor").first() if not User.query.filter(User.username == "admin").first(): db.session.add( User(username="******", password=password, email="*****@*****.**", active=True, email_confirmed_at=datetime.datetime.now(), roles=[admin, contributor])) if not User.query.filter(User.username == "contributor").first(): db.session.add( User(username="******", password=password, email="*****@*****.**", active=True, email_confirmed_at=datetime.datetime.now(), roles=[contributor])) def to_json(self): return { "username": self.username, "roles": [r.name for r in self.roles] } def is_admin(self): return 'admin' in [r.name for r in self.roles]