Exemple #1
0
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))
Exemple #4
0
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'))
Exemple #5
0
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)
Exemple #7
0
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))
Exemple #8
0
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}')"
Exemple #9
0
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>&#127793;</center>').replace(
                '--', '&#8212;'))
        data = Product.replace_product_markup(data)
        return data

    def html_body(self):
        body = markdown(
            self.body.replace('---', '<center>&#127793;</center>').replace(
                '--', '&#8212;'))
        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})>"
Exemple #10
0
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'}
Exemple #11
0
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)
Exemple #12
0
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.'
Exemple #13
0
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
Exemple #14
0
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()
Exemple #15
0
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
Exemple #16
0
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)
Exemple #18
0
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)
Exemple #19
0
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'))
Exemple #21
0
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
Exemple #22
0
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
Exemple #24
0
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.'
Exemple #26
0
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
Exemple #27
0
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))
Exemple #28
0
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__
Exemple #29
0
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'
Exemple #30
0
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]