Ejemplo n.º 1
0
class User(db.Model):
    __tablename__ = 'user'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(LENGTH), index=True, unique=True)
    email = db.Column(db.String(LENGTH), index=True, unique=True)
    status = db.Column(db.SmallInteger, default=OFFLINE)
    profile_pic = db.Column(db.String(LENGTH), index=True, unique=True)
    _password = db.Column('password', db.String(LENGTH), nullable=False)

    @property
    def is_authenticated(self):
        return True

    @property
    def is_active(self):
        return True

    @property
    def is_anonymous(self):
        return False

    def get_id(self):
        try:
            return unicode(self.id)  # python 2
        except NameError:
            return str(self.id)  # python 3

    def _get_password(self):
        return self._password

    def _set_password(self, password):
        self._password = generate_password_hash(password)

    password = db.synonym('_password',
                          descriptor=property(_get_password, _set_password))

    def check_password(self, password):
        if self.password is None:
            return False
        return check_password_hash(self.password, password)

    @classmethod
    def authenticate(cls, username, password):
        the_user = cls.query.filter(User.name == username).first()

        if the_user:
            authenticated = the_user.check_password(password)
        else:
            authenticated = False

        return the_user, authenticated

    def save(self, *args, **kwargs):
        db.session.add(self)
        db.session.commit()

    def __repr__(self):
        return '<User %r>' % (self.name)
Ejemplo n.º 2
0
class User(UserMixin ,  Base):

    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key = True, unique=True)
    username = db.Column(db.Text, nullable=False, unique=False)
    email = db.Column(db.String(120), nullable=False, unique = True)
    _password = db.Column('password', db.Text, nullable=False)
    confirmed = db.Column(db.Boolean, nullable=False, default=False)

    groups = db.relationship('Group',
                             secondary=user_group,
                             collection_class=set,
                             backref=db.backref('users', collection_class=set, lazy='dynamic'))

    def _set_password(self, password):
        self._password = make_hash(password)

    def _get_password(self):
        return self._password

    password = db.synonym('_password', descriptor=property(_get_password,
                                                        _set_password))
    def is_authenticated(self):
        return True

    def valid_password(self, password):
        """Check if provided password is valid."""
        return check_hash(password, self.password)

    def is_active(self):
        return self.active

    def is_anonymous(self):
        return False

    def get_id(self):
        return str(self.id)

    def __repr__(self):
        return '<%s(%r, %r)>' % (self.__class__.__name__, self.id,
                                 self.email)

    def in_groups(self):
        """Return set of groups which user belongs to."""
        perms = set(r.name for r in Group.query.join(Group.users).filter(User.id == self.id).all())
        return perms

    def has_permissions(self):
        """Return set of permissions which user has."""
        perms = set(r.name for r in Permission.query.join(Permission.groups, Group.users).filter(User.id == self.id).all())
        return perms

    def get_name(self):
        return jsonify(username = self.username)
Ejemplo n.º 3
0
class Users(db.Model):
    '''
    This is the User model.
    '''
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    _password = db.Column('password', db.String(120), nullable=False)
    created_on = db.Column(db.DateTime)
    last_logged_in = db.Column(db.DateTime)
    updated_on = db.Column(db.DateTime)
    email = db.Column(db.String(150))
    display_name = db.Column(db.String(120))
    admin = db.Column(db.Boolean, default=False)
    local = db.Column(db.Boolean, default=False)
    username = db.Column(db.String(120))

    token = db.relationship('Token', back_populates='users')

    def __repr__(self):
        return '<User %r>' % (self.username)

    def _set_password(self, password):
        self._password = generate_password_hash(password)

    def _get_password(self):
        return self._password

    password = db.synonym('_password', descriptor=property(
        _get_password, _set_password))

    def valid_password(self, password):
        return check_password_hash(self._password, password)

    def is_authenticated(self):
        return True

    def user_status(self):
        return "Active" if self.active else "Deactivated"

    def get_id(self):
        try:
            return unicode(self.id)  # python 2
        except NameError:
            return str(self.id)  # python 3

    def is_administrator(self):
        return True if self.role == 2 else False
Ejemplo n.º 4
0
class Transaction(Meta):
    __tablename__ = 'transaction'

    transaction_hash = db.Column(db.Text, unique=True, primary_key=True)
    customer_id = db.Column(db.Integer, db.ForeignKey(Customer.id))
    date = db.Column(db.DateTime)
    hash_id = db.synonym('transaction_hash')
    currency_id = db.Column(db.Integer, db.ForeignKey('currency.id'))

    books = db.relationship('Books', secondary=books_transactions, back_populates='transactions')

    def __init__(self, transaction_hash, customer_id, currency_id, books: list):
        self.transaction_hash = transaction_hash
        self.customer_id = customer_id
        self.date = datetime.now()
        self.currency = currency_id
        for book in books:
            assert isinstance(book, Books)
            self.books.append(book)

    @property
    def total_cost(self):
        return round(sum((book.cost for book in self.books)), 2)

    @property
    def currency(self):
        return self.currency_id

    @currency.setter
    def currency(self, currency_id):
        self.currency_id = currency_id

    @classmethod
    def create_transaction(cls, customer_id, currency_id, books: list):
        transaction_hash = hashlib.md5((''.join(str(b.id) for b in books)).encode()).hexdigest()
        trans = cls.query.get(transaction_hash)
        if not trans:
            trans = cls(transaction_hash, customer_id, currency_id, books)
            db.session.add(trans)
            db.session.commit()
        return trans
Ejemplo n.º 5
0
class Tag(db.Model, dbFunctions):
    __tablename__ = "tags"
    query_class = TagQuery

    id = db.Column(db.Integer, primary_key=True)
    slug = db.Column(db.String(80), unique=True)
    posts = db.dynamic_loader(Post,
                              secondary=post_tags,
                              query_class=PostQuery,
                              cascade="all, delete")
    #posts = db.relationship(Post, secondary='post_tags', lazy='dynamic',
    #                        backref=db.backref('tags', lazy='dynamic'), cascade="all, delete")

    _name = db.Column("name", db.String(80), unique=True)

    def __str__(self):
        return self.name

    def _get_name(self):
        return self._name

    def _set_name(self, name):
        self._name = name.lower().strip()
        self.slug = slugify(name)

    name = db.synonym("_name", descriptor=property(_get_name, _set_name))

    @cached_property
    def url(self):
        return url_for("home.tag", slug=self.slug)

    num_posts = db.column_property(
        db.select([db.func.count(post_tags.c.post_id)]).\
            where(db.and_(post_tags.c.tag_id==id,
                          Post.id==post_tags.c.post_id,
                          Post.access==Post.PUBLIC)).as_scalar())
Ejemplo n.º 6
0
class User(db.Model, UserMixin):
    """ A user who has an account on the website. """

    __tablename__ = "users"

    first_name = db.Column(db.String)
    last_name = db.Column(db.String)
    phone = db.Column(db.String)
    email = db.Column(db.String, primary_key=True)
    confirmation = db.Column(db.Boolean)
    _password = db.Column(db.String)

    @property
    def full_name(self):
        return "{} {}".format(self.first_name, self.last_name)

    @hybrid_property
    def password(self):
        return self._password

    def _set_password(self, plaintext):
        self._password = bcrypt.generate_password_hash(plaintext)

    def _get_password(self):
        # Hopefully this is salted and hashed
        # TODO: Check to see if this is hashed or not.
        return self.password

    def check_password(self, plaintext):
        return bcrypt.check_password_hash(self.password, plaintext)

    password = db.synonym('_password',
                          descriptor=property(_get_password, _set_password))

    def get_id(self):
        return self.email
Ejemplo n.º 7
0
class User(db.Model, UserMixin, dbFunctions):
    __tablename__ = "users"

    query_class = UserQuery

    # user roles
    GUEST = 0
    MEMBER = 100
    MODERATOR = 200
    ADMIN = 300

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(60), unique=True, nullable=False)
    email = db.Column(db.String(150), unique=True, nullable=False)
    karma = db.Column(db.Integer, default=0)
    date_joined = db.Column(db.DateTime, default=datetime.utcnow)
    activation_key = db.Column(db.String(80), unique=True)
    role = db.Column(db.Integer, default=MEMBER)
    receive_email = db.Column(db.Boolean, default=False)
    email_alerts = db.Column(db.Boolean, default=False)
    followers = db.Column(DenormalizedText)
    following = db.Column(DenormalizedText)
    _password = db.Column("password", db.String(80))

    class Permissions(Permissions):
        @cached_property
        def send_message(self):
            if not self.receive_email:
                return null

            needs = [UserNeed(username) for username in self.friends]
            if not needs:
                return null

            return Permission(*needs)

    def __init__(self, *args, **kwargs):
        super(User, self).__init__(*args, **kwargs)
        self.followers = self.followers or set()
        self.following = self.following or set()

    def __str__(self):
        return self.username

    def __repr__(self):
        return "<%s>" % self

    @cached_property
    def permissions(self):
        return self.Permissions(self)

    def _get_password(self):
        return self._password

    def _set_password(self, password):
        self._password = generate_password_hash(password)

    password = db.synonym("_password",
                          descriptor=property(_get_password, _set_password))

    def check_password(self, password):
        if self.password is None:
            return False
        return check_password_hash(self.password, password)

    @cached_property
    def provides(self):
        needs = [RoleNeed('authenticated'), UserNeed(self.username)]

        if self.is_moderator:
            needs.append(RoleNeed('moderator'))

        if self.is_admin:
            needs.append(RoleNeed('admin'))

        return needs

    @cached_property
    def num_followers(self):
        if self.followers:
            return len(self.followers)
        return 0

    @cached_property
    def num_following(self):
        return len(self.following)

    def is_following(self, user):
        return user.id in self.following

    @property
    def num_unread_message(self):

        from app.models import Message
        unread = Message.query.unread(self)
        return unread

    @property
    def friends(self):
        return self.following.intersection(self.followers)

    def is_friend(self, user):
        return user.id in self.friends

    def get_friends(self):
        return User.query.filter(User.id.in_(self.friends))

    def follow(self, user):
        user.followers.add(self.id)
        self.following.add(user.id)

    def unfollow(self, user):
        if self.id in user.followers:
            user.followers.remove(self.id)

        if user.id in self.following:
            self.following.remove(user.id)

    def get_following(self):
        """
        Return following users as query
        """
        return User.query.filter(User.id.in_(self.following or set()))

    def get_followers(self):
        """
        Return followers as query
        """
        return User.query.filter(User.id.in_(self.followers or set()))

    @property
    def is_moderator(self):
        return self.role >= self.MODERATOR

    @property
    def is_admin(self):
        return self.role >= self.ADMIN

    def avatar_url(self, type=None):
        file = None
        file_url = None
        if type:
            file = '/%s_%s.jpg' % (self.username, type)
            file_url = 'avatar/%s_%s.jpg' % (self.username, type)
        else:
            file = '/%s.jpg' % self.username
            file_url = 'avatar/%s.jpg' % self.username
        path = setting.AVATAR_PATH + file
        if os.path.exists(path):
            return url_for("static", filename=file_url)
        else:
            return url_for("static", filename="avatar/default_small.png")
Ejemplo n.º 8
0
class Post(db.Model, dbFunctions):
    __tablename__ = "posts"

    PUBLIC = 100
    FRIENDS = 200
    PRIVATE = 300

    PER_PAGE = 20

    query_class = PostQuery

    id = db.Column(db.Integer, primary_key=True)
    author_id = db.Column(db.Integer,
                          db.ForeignKey(User.id, ondelete='CASCADE'),
                          nullable=False)
    title = db.Column(db.String(600))
    description = db.Column(db.String)
    link = db.Column(db.String(250))
    date_created = db.Column(db.DateTime, default=datetime.utcnow)
    last_updated = db.Column(db.DateTime,
                             onupdate=datetime.utcnow,
                             default=datetime.utcnow)
    score = db.Column(db.Integer, default=0)
    num_comments = db.Column(db.Integer, default=0)
    votes = db.Column(DenormalizedText)
    access = db.Column(db.Integer, default=PUBLIC)

    _tags = db.Column("tags", db.String)
    # Many to many Post <-> Tag
    #_tags = db.relationship('Tag', secondary='post_tags',
    #    backref=db.backref('posts', lazy='dynamic'))

    author = db.relation(User, innerjoin=True, lazy="joined")
    __mapper_args__ = {'order_by': id.desc()}

    class Permissions(Permissions):
        @cached_property
        def default(self):
            return Permission(UserNeed(
                self.author.username)) & moderator & admin

        @cached_property
        def view(self):
            if self.access == Post.PUBLIC:
                return Permission()

            if self.access == Post.FRIENDS:
                needs = [UserNeed(User.query.get(user_id).username) for user_id in \
                            self.author.friends]

                return self.default & Permission(*needs)

            return self.default

        @cached_property
        def edit(self):
            return Permission(UserNeed(self.author.username)) & admin

        @cached_property
        def delete(self):
            return Permission(UserNeed(self.author.username)) & admin

        @cached_property
        def vote(self):
            needs = [
                UserNeed(User.query.get(user_id).username)
                for user_id in self.votes
            ]
            needs.append(UserNeed(self.author.username))

            return auth & Denial(*needs)

        @cached_property
        def comment(self):
            return auth

    def __init__(self, *args, **kwargs):
        super(Post, self).__init__(*args, **kwargs)
        self.votes = self.votes or set()
        self.access = self.access or self.PUBLIC

    def __str__(self):
        return self.title

    def __repr__(self):
        return "<%s>" % self

    @cached_property
    def permissions(self):
        return self.Permissions(self)

    def vote(self, user):
        self.votes.add(user.id)

    def _get_tags(self):
        return self._tags

    def _set_tags(self, tags):

        self._tags = tags

        if self.id:
            # ensure existing tag references are removed
            d = db.delete(post_tags, post_tags.c.post_id == self.id)
            db.engine.execute(d)

        for tag in set(self.taglist):

            slug = slugify(tag)

            tag_obj = Tag.query.filter(Tag.slug == slug).first()
            if tag_obj is None:
                tag_obj = Tag(name=tag, slug=slug)
                db.session.add(tag_obj)

            if self not in tag_obj.posts:
                tag_obj.posts.append(self)

    # should after _get_tags _set_tags
    tags = db.synonym("_tags", descriptor=property(_get_tags, _set_tags))

    @property
    def taglist(self):
        if self.tags is None:
            return []

        tags = [t.strip() for t in self.tags.replace(u",", ",").split(",")]
        return [t for t in tags if t]

    @cached_property
    def linked_taglist(self):
        """
        Returns the tags in the original order and format, 
        with link to tag page
        """
        return [(tag, url_for('home.tag',
                              slug=slugify(tag))) \
                for tag in self.taglist]

    @cached_property
    def domain(self):
        if not self.link:
            return ''
        return domain(self.link)

    @cached_property
    def json(self):
        """
        Returns dict of safe attributes for passing into 
        a JSON request.
        """
        return dict(post_id=self.id,
                    score=self.score,
                    title=self.title,
                    link=self.link,
                    description=self.description,
                    num_comments=self.num_comments,
                    author=self.author.username)

    @cached_property
    def access_name(self):
        return {
            Post.PUBLIC: "public",
            Post.FRIENDS: "friends",
            Post.PRIVATE: "private"
        }.get(self.access, "public")

    def can_access(self, user=None):
        if self.access == self.PUBLIC:
            return True

        if user is None:
            return False

        if user.is_moderator or user.id == self.author_id:
            return True

        return self.access == self.FRIENDS and self.author_id in user.friends

    @cached_property
    def comments(self):
        """
        Returns comments in tree. Each parent comment has a "comments" 
        attribute appended and a "depth" attribute.
        """
        from app.models import Comment
        comments = Comment.query.filter(Comment.post_id == self.id).all()

        def _get_comments(parent, depth):

            parent.comments = []
            parent.depth = depth

            for comment in comments:
                if comment.parent_id == parent.id:
                    parent.comments.append(comment)
                    _get_comments(comment, depth + 1)

        parents = [c for c in comments if c.parent_id is None]

        for parent in parents:
            _get_comments(parent, 0)

        return parents

    def _url(self, _external=False):
        return url_for('post.view',
                       post_id=self.id,
                       slug=self.slug,
                       _external=_external)

    @cached_property
    def url(self):
        return self._url()

    @cached_property
    def permalink(self):
        return self._url(True)

    @cached_property
    def markdown(self):
        return tomarkdown(self.description or '')

    @cached_property
    def slug(self):
        return slugify(self.title or '')[:80]
Ejemplo n.º 9
0
class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    nickname = db.Column(db.String(64), index=True, unique=True)
    email = db.Column(db.String(120), index=True, unique=True)
    posts = db.relationship('Post', backref='author', lazy='dynamic')
    about_me = db.Column(db.String(140))
    last_seen = db.Column(db.DateTime)
    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')

    _password = db.Column('password', db.String(64))

    def _get_password(self):
        return self._password

    def _set_password(self, password):
        self._password = generate_password_hash(password)

    password = db.synonym('_password',
                          descriptor=property(_get_password, _set_password))

    def check_password(self, password):
        if self.password is None:
            return False
        return check_password_hash(self.password, password)

    def __repr__(self):
        return '<User %r>' % (self.nickname)

    @classmethod
    def authenticate(cls, nickname, password):
        user = User.query.filter(db.or_(User.nickname == nickname)).first()

        if user:
            authenticated = user.check_password(password)
        else:
            authenticated = False
        return user, authenticated

    @classmethod
    def is_user_name_taken(cls, nickname):
        return db.session.query(
            db.exists().where(User.nickname == nickname)).scalar()

    @classmethod
    def is_email_taken(cls, email):
        return db.session.query(
            db.exists().where(User.email == email)).scalar()

    @staticmethod
    def make_valid_nickname(nickname):
        return re.sub('[^a-zA-Z0-9_\.]', '', nickname)

    @login_manager.user_loader
    def load_user(id):
        return User.query.get(id)

    def follow(self, user):
        if not self.is_following(user):
            self.followed.append(user)
            return self

    def unfollow(self, user):
        if self.is_following(user):
            self.followed.remove(user)
            return self

    def is_following(self, user):
        return self.followed.filter(
            followers.c.followed_id == user.id).count() > 0

    def followed_posts(self):
        return Post.query.join(
            followers, (followers.c.followed_id == Post.user_id)).filter(
                followers.c.follower_id == self.id).order_by(
                    Post.timestamp.desc())
Ejemplo n.º 10
0
class User(db.Model):
    __tablename__ ="users"
    __searchable__ =['username','email']

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(30),unique=True,nullable=False)
    email = db.Column(db.String(100),unique=True,nullable=False)
    _password = db.Column('password',db.String(120),nullable=False)
    date_joined = db.Column(db.DateTime,default=datetime.utcnow())
    nick = db.Column(db.String(80))
    age = db.Column(db.Integer)
    gender = db.Column(db.String(10))
    department = db.Column(db.String(120))
    phone = db.Column(db.String(16))
    qq = db.Column(db.String(12))
    #TODO : avatar

    posts = db.relationship("Post",backref="author",lazy="dynamic")

    post_count = db.Column(db.Integer,default=0)

    @property
    def last_post(self):
        pass

    @property
    def url(self):
        """Returns the url for the user"""
        return url_for("profile", username=self.username)

    @property
    def permissions(self):
        """Returns the permission for the user"""
        return self.get_permissions()

    @property
    def days_registered(self):
        """Returns the amount of days the user is registered."""
        days_registered = (datetime.utcnow() - self.date_joined).days
        if not days_registered:
            return 1
        return days_registered


    #method
    def _get_password(self):
        """Returns the hashed password"""
        return self._password

    def _set_password(self,password):
        """Generates a password hash for the provieded password"""
        self._password = generate_password_hash(password)

    # Hide password encryption by exposing password field only
    password = db.synonym('_password',descriptor=property(_get_password,_set_password))

    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:
            authenticated = user.check_password(password)
        else:
            authenticated = False
        return user, authenticated

    @classmethod
    def get(cls,uid):
        return cls.query.filter(User.username == uid).first()

    def _make_token(self, data, timeout):
        s = Serializer(current_app.config['SECRET_KEY'], timeout)
        return s.dumps(data)

    def _verify_token(self, token):
        s = Serializer(current_app.config['SECRET_KEY'])
        data = None
        expired, invalid = False, False
        try:
            data = s.loads(token)
        except SignatureExpired:
            expired = True
        except Exception:
            invalid = True
        return expired, invalid, data

    def make_reset_token(self, expiration=3600):
        """Creates a reset token. The duration can be configured through the
        expiration parameter.
        :param expiration: The time in seconds how long the token is valid.
        """
        return self._make_token({'id': self.id, 'op': 'reset'}, expiration)

    def verify_reset_token(self, token):
        """Verifies a reset token. It returns three boolean values based on
        the state of the token (expired, invalid, data)
        :param token: The reset token that should be checked.
        """

        expired, invalid, data = self._verify_token(token)
        if data and data.get('id') == self.id and data.get('op') == 'reset':
            data = True
        else:
            data = False
        return expired, invalid, data

    def all_posts(self,page):
        """Returns a paginated result with all posts the user has created."""

        return Post.query.filter(Post.user_id == self.id).\
                paginate(page,app_config['TOPICS_PER_PAGE'],False)

    def get_permissions(self,exclude=None):
        """Returns a dictionary with all the permissions the user has.

        :param exclude: a list with excluded permissions. default is None.
        """
        pass

    def ban(self):
        """Bans the uesr.Returns True upon success"""
        #TODO: ban user
        pass

        #if not self.get_permissions()['banned']:

    def unban(self):
        """Unbans the user. Returns True upon success."""
        #TODO: unban user
        pass

    def save(self, groups=None):
        """Saves a user. If a list with groups is provided, it will add those
        to the secondary groups from the user.
        :param groups: A list with groups that should be added to the secondary groups from user.
        """
        # TODO: groups
        db.session.add(self)
        db.session.commit()
        return self

    def delete(self):
        """Deletes the User"""

        #TODO: delete user

    def is_authenticated(self):
        return True

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        return self.username