~fluix/tilde

ref: 8f46b9d65448ed50e322f49ecdbad39737700a1b tilde/auth/models.py -rw-r--r-- 1.5 KiB
8f46b9d6Steven Guikal Add user account activation 9 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# SPDX-FileCopyrightText: 2021 Steven Guikal <void@fluix.one>
#
# SPDX-License-Identifier: AGPL-3.0-only

from enum import Enum, auto

from flask import current_app
from flask_login.mixins import UserMixin
from itsdangerous import BadSignature
from itsdangerous.url_safe import URLSafeSerializer
from werkzeug.security import check_password_hash, generate_password_hash

db = current_app.config["db"]


class Status(Enum):
    PENDING = "User is pending verification. Login with the activation link provided in the email."
    ACTIVE = None
    BANNED = "User is banned."
    DELETED = "User is deleted."

    def __init__(self, error):
        self.error = error


class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20, collation="NOCASE"), unique=True)
    email = db.Column(db.String())
    password_hash = db.Column(db.String())
    status = db.Column(db.Enum(Status), default=Status.PENDING)
    bio = db.Column(db.Text())

    @property
    def is_active(self):
        return self.status == Status.ACTIVE

    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 check_activation(self, code):
        signer = URLSafeSerializer(current_app.secret_key, salt="activate")
        try:
            return signer.loads(code) == [self.id, self.username]
        except BadSignature:
            return False