예제 #1
0
파일: user.py 프로젝트: zympz/Ignite
class User(Model, UserMixin):
    id = db.Column(db.Integer(), primary_key=True)
    email = db.Column(db.String(), nullable=False)
    password = db.Column(db.String())
    admin = db.Column(db.Boolean())
    role = db.Column(db.String(), default='user')
    email_confirmed = db.Column(db.Boolean())

    def __init__(self, email=None, password=None, admin=False):
        if not email:
            raise ValueError('No Email Provided')

        self.email = email.lower().strip()
        if admin:
            self.admin = True
            self.role = 'admin'  # TODO: Clean this up

        if password:
            self.set_password(password)

    def set_password(self, password):
        self.password = generate_password_hash(password)

    def check_password(self, value):
        return check_password_hash(self.password, value)

    @property
    def is_authenticated(self):
        return not isinstance(self, AnonymousUserMixin)

    @property
    def is_admin(self):
        return self.role == 'admin'

    @property
    def is_anonymous(self):
        return isinstance(self, AnonymousUserMixin)

    def is_active(self):
        return True

    def get_id(self):
        return self.id

    def __repr__(self):
        return '<User {0}>'.format(self.email)

    @classmethod
    def lookup(cls, email):
        return cls.query.filter_by(email=email).first()

    @classmethod
    def lookup_or_create(cls, email, **kwargs):
        existing = cls.query.filter_by(email=email).first()
        if existing:
            return existing
        new_user = User(email=email, **kwargs)
        db.session.add(new_user)
        db.session.commit()
        return new_user
예제 #2
0
class TeamMember(Model):
    id = db.Column(db.Integer(), primary_key=True)
    team_id = db.Column(db.ForeignKey("team.id"), index=True, nullable=False)
    user_id = db.Column(db.ForeignKey("user.id"), index=True, nullable=True)

    invite_email = db.Column(db.String(255))
    role = db.Column(db.String(), default='team_member')

    inviter_id = db.Column(db.ForeignKey("user.id"))
    invite_secret = db.Column(db.String(255), default=url_safe_token)

    activated = db.Column(db.Boolean(), default=False)

    team = db.relationship("Team", backref='members', lazy="joined")
    user = db.relationship("User",
                           foreign_keys=[user_id],
                           backref='memberships')

    inviter = db.relationship("User", foreign_keys=[inviter_id])

    GDPR_EXPORT_COLUMNS = {
        "invite_email": "Email the invite was sent to",
        "activated": "Was the invite activated?",
        "created": "When the invite was created",
        "team_id": "What team was the invite for",
        "inviter_id": "Who sent the invite",
        "role": "Role on team"
    }

    @classmethod
    def invite(cls, team, email, role, inviter):
        invitee = User.lookup(email)
        if (not invitee):
            member = cls(team=team,
                         invite_email=email,
                         role=role,
                         inviter=inviter)
        else:
            member = cls(team=team, user=invitee, role=role, inviter=inviter)

        db.session.add(member)
        db.session.commit()
        InviteEmail(member).send()

    @property
    def email(self):
        if self.user_id:
            return self.user.email
        return self.invite_email

    def activate(self, user_id):
        if not self.activated:
            self.user_id = user_id
            self.activated = True
            db.session.add(self)
            db.session.commit()
            self.team.billing_plan.record_change_in_usage()
        else:
            raise Exception('Already activated')
예제 #3
0
class Team(Model):
    """
    A team is a collection of users sharing the same resources.
    All users get a team. Some teams have more than one member.
    Most resources in the application should belong to a team.

    Usage:
        team.members -> [<TeamMember>, ...]
    """

    id = db.Column(db.Integer(), primary_key=True)
    creator_id = db.Column(db.ForeignKey("user.id"),
                           index=True,
                           nullable=False)

    name = db.Column(db.String(255))
    # Plan may need to become DB backed when billing is introduced.
    plan = db.Column(db.String(), default='default')

    creator = db.relationship("User")

    GDPR_EXPORT_COLUMNS = {
        "name": "Name of the time",
        "plan": "What plan was",
        "created": "When the team was created"
    }

    def has_member(self, user):
        return user in [member.user for member in self.active_members]

    @property
    def active_members(self):
        return [
            membership for membership in self.members if membership.activated
        ]

    @property
    def active_teams(self):
        return [
            membership.team for membership in self.members
            if membership.activated
        ]

    @classmethod
    @transaction
    def create(cls, name, creator):
        new_team = cls(name=name, creator=creator)
        new_team_member = ModelProxy.teams.TeamMember(team=new_team,
                                                      user=creator,
                                                      role='administrator',
                                                      activated=True)

        db.session.add(new_team)
        db.session.add(new_team_member)
        db.session.commit()
        return new_team
예제 #4
0
class TeamMember(Model):
    id = db.Column(db.Integer(), primary_key=True)
    team_id = db.Column(db.ForeignKey("team.id"), index=True, nullable=False)
    user_id = db.Column(db.ForeignKey("user.id"), index=True, nullable=True)

    invite_email = db.Column(db.String(255))
    role = db.Column(db.String(), default='team_member')

    inviter_id = db.Column(db.ForeignKey("user.id"))
    invite_secret = db.Column(db.String(255), default=url_safe_token)

    activated = db.Column(db.Boolean(), default=False)

    team = db.relationship("Team", backref='members', lazy="joined")
    user = db.relationship("User",
                           foreign_keys=[user_id],
                           backref='memberships')

    inviter = db.relationship("User", foreign_keys=[inviter_id])

    GDPR_EXPORT_COLUMNS = {
        "invite_email": "Email the invite was sent to",
        "activated": "Was the invite activated?",
        "created": "When the invite was created",
        "team_id": "What team was the invite for",
        "role": "Role on team"
    }

    @classmethod
    def invite(cls, team, email, role, inviter):
        invitee = User.lookup(email)
        if (not invitee):
            member = cls(team=team,
                         invite_email=email,
                         role=role,
                         inviter=inviter)
        else:
            member = cls(team=team, user=invitee, role=role, inviter=inviter)

        db.session.add(member)
        db.session.commit()
        InviteEmail(member).send()
예제 #5
0
파일: team_file.py 프로젝트: laranea/Ignite
class TeamFile(Model):
    id = db.Column(db.Integer(), primary_key=True)
    team_id = db.Column(db.ForeignKey("team.id"), index=True,
                        nullable=False)
    user_id = db.Column(db.ForeignKey("user.id"), index=True,
                        nullable=True)

    file_name = db.Column(db.String())
    description = db.Column(db.String())

    file_object_name = db.Column(db.String())

    activated = db.Column(db.Boolean(), default=False)

    team = db.relationship("Team", backref='files', lazy="joined")
    user = db.relationship("User", backref='team_files')

    GDPR_EXPORT_COLUMNS = {
        "created": "When the invite was created",
        "team_id": "What team was the invite for",
        "creator_id": "Who created the file",
        "file_name": "The name of the file",
        "description": "The description of the file",
    }
예제 #6
0
파일: user.py 프로젝트: laranea/Ignite
class User(Model, UserMixin):
    id = db.Column(db.Integer(), primary_key=True)
    full_name = db.Column(db.String())
    email = db.Column(db.String(), nullable=False)
    password = db.Column(db.String())
    admin = db.Column(db.Boolean())
    role = db.Column(db.String(), default='user')
    email_confirmed = db.Column(db.Boolean())
    user_api_key_hash = db.Column(db.String())
    billing_customer_id = db.Column(db.String())

    # Encrypted Secret (used for Two Factor Authentication)
    encrypted_totp_secret = db.Column(
        EncryptedType(db.String,
                      key=global_encryption_key_iv,
                      engine=FernetEngine))

    GDPR_EXPORT_COLUMNS = {
        "id": "ID of the user",
        "hashid": "ID of User",
        "email": "User Email",
        "created": "When the user was created",
        "full_name": "The users full name",
        "email_confirmed": "Whether the email was confirmation"
    }

    def __init__(self,
                 email=None,
                 password=None,
                 admin=False,
                 email_confirmed=False,
                 team=None,
                 name=None):
        if not email:
            raise ValueError('No Email Provided')

        self.email = email.lower().strip()
        self.full_name = name
        self.email_confirmed = email_confirmed

        if admin:
            self.admin = True
            self.role = 'admin'  # TODO: Clean this up

        if password:
            self.set_password(password)

        if not team:
            team_name = "{0}'s team".format(email)
            ModelProxy.teams.Team.create(team_name, self)

    def set_password(self, password):
        self.password = generate_password_hash(password)

    def check_password(self, value):
        return check_password_hash(self.password, value)

    def check_api_key_hash(self, api_key):
        # Potential timing attack here
        if self.user_api_key_hash:
            return check_password_hash(self.user_api_key_hash, api_key)
        return False

    def hash_api_key(self, api_key):
        self.user_api_key_hash = generate_password_hash(api_key)
        db.session.add(self)
        db.session.commit()

    @property
    def is_authenticated(self):
        return not isinstance(self, AnonymousUserMixin)

    @property
    def is_admin(self):
        return self.role == 'admin'

    @property
    def is_anonymous(self):
        return isinstance(self, AnonymousUserMixin)

    def is_active(self):
        return True

    def get_id(self):
        return self.id

    @property
    def active_memberships(self):
        return [member for member in self.memberships if member.activated]

    @property
    def admin_memberships(self):
        return [
            member for member in self.memberships
            if member.activated and member.role == 'administrator'
        ]

    @property
    def active_teams(self):
        return [member.team for member in self.active_memberships]

    # TODO: Cache
    @property
    def primary_membership_id(self):
        if len(self.active_memberships) == 0:
            return None
        return self.active_memberships[0].id

    def __repr__(self):
        return '<User {0}>'.format(self.email)

    @classmethod
    def lookup(cls, email):
        return cls.query.filter_by(email=email).first()

    @classmethod
    def lookup_or_create_by_email(cls, email, **kwargs):
        existing = cls.query.filter_by(email=email).first()
        if existing:
            return existing
        new_user = User(email=email, **kwargs)
        db.session.add(new_user)
        db.session.commit()
        return new_user
예제 #7
0
class Team(Model):
    """
    A team is a collection of users sharing the same resources.
    All users get a team. Some teams have more than one member.
    Most resources in the application should belong to a team.

    Usage:
        team.members -> [<TeamMember>, ...]
    """

    id = db.Column(db.Integer(), primary_key=True)
    creator_id = db.Column(db.ForeignKey("user.id"), index=True,
                           nullable=False)

    name = db.Column(db.String(255))
    # Plan may need to become DB backed when billing is introduced.
    plan = db.Column(db.String(), default='free')
    plan_owner_id = db.Column(db.ForeignKey("user.id"))
    subscription_id = db.Column(db.String())
    billing_customer_id = db.Column(db.String())


    creator = db.relationship("User", foreign_keys=[creator_id])
    plan_owner = db.relationship("User", foreign_keys=[plan_owner_id])

    GDPR_EXPORT_COLUMNS = {
        "id": "ID of the team",
        "hashid": "ID of User",
        "name": "Name of the team",
        "plan": "What plan the team was on",
        "created": "When the team was created"
    }

    def has_member(self, user):
        return user in [member.user for member in self.active_members]

    @property
    def is_paid_plan(self):
        return not self.billing_plan.is_free

    @property
    def billing_plan(self):
        # TODO: Might benefit from a validation to ensure `plan` is a recognized type in billing_plans
        billing_plan = plans_by_name.get(self.plan) or FreePlan
        return billing_plan(self)

    @property
    def active_members(self):
        return [membership for membership in self.members if membership.activated]

    @property
    def active_teams(self):
        return [membership.team for membership in self.members if membership.activated]

    @classmethod
    @transaction
    def create(cls, name, creator):
        new_team = cls(name=name, creator=creator)
        new_team_member = ModelProxy.teams.TeamMember(team=new_team, user=creator, role='administrator', activated=True)

        db.session.add(new_team)
        db.session.add(new_team_member)
        db.session.commit()
        return new_team