Beispiel #1
0
class Inventory(db.Model):
    __tablename__ = "inventories"

    id = db.Column(UUID(as_uuid=True), primary_key=True)
    book = db.Column(db.String(32), nullable=False)
    author = db.Column(db.String(32), nullable=True)
    url = db.Column(db.String(128), unique=True, nullable=False)
    added_date = db.Column(db.DateTime(), default=datetime.utcnow)

    readings = db.relationship("Reading", back_populates="book")
    vacant_date = db.Column(db.DateTime(), default=datetime.utcnow)

    user_id = db.Column(UUID(as_uuid=True), db.ForeignKey('users.id'))
    user = db.relationship('User', back_populates="added_books")

    def __init__(self, book, author, url):
        self.id = uuid.uuid4()
        self.author = author
        self.book = book
        self.url = url

    def __repr__(self):
        if self.user is not None:
            return "<<%r>>(Added by: %s): %r" % (self.book, self.user.username, self.url)
        else:
            return "<<%r>>: %r" % (self.book, self.url)

    @staticmethod
    def exists(url):
        return Inventory.query.filter_by(url=url).count() > 0

    @staticmethod
    def get_book(book_name):
        return Inventory.query.filter_by(book=book_name).first()
Beispiel #2
0
class Role(db.Model):
    id = db.Column(db.String(32),
                   default=lambda: str(uuid4()).replace('-', ''),
                   primary_key=True)
    name = db.Column(db.String(32), unique=True, nullable=False, index=True)
    permits = db.relationship('Permission',
                              secondary=authority,
                              backref=db.backref('roles', lazy='dynamic'))
    users = db.relationship('Users', backref='role', lazy='dynamic')

    def generate_access_key(self):
        s = Serializer(app.config['SECRET_KEY'],
                       expires_in=app.config['SECURITY']['expiration'])
        return s.dumps({'id': self.id}).decode('utf-8')

    @staticmethod
    def verify_access_authority(page, access_key):
        s = Serializer(app.config['SECRET_KEY'])
        try:
            role_id = s.loads(access_key.encode('utf-8'))['id']
            role = Role.query.get(role_id)
            permissions = role.permits
            permits = [each.permit for each in permissions]
            return True if page in permits else False
        except SignatureExpired and BadSignature:
            return False

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

    def __repr__(self):
        return "用户 <%s>" % self.name
Beispiel #3
0
class User(UserMixin, db.Model):
    __tablename__ = "users"

    id = db.Column(UUID(as_uuid=True), primary_key=True)
    username = db.Column(db.String(64), unique=True)
    password_hash = db.Column(db.String(128))
    admin = db.Column(db.BOOLEAN(), default=False, nullable=False)
    books = db.relationship('Reading', backref='books', lazy=True)
    added_books = db.relationship("Inventory", back_populates="user")

    def __init__(self, username):
        self.username = username
        self.id = self.get_id()

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

    @property
    def password(self):
        return self.password_hash

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password, SECURITY["iterations"]).decode("utf-8")

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

    def get_id(self):
        if self.id is not None:
            return self.id
        else:
            return uuid.uuid4()

    @staticmethod
    def find(username):
        return User.query.filter_by(username=username).first()

    @staticmethod
    def get(user_id):
        try:
            res = User.query.get(user_id)
        except OperationalError:
            res = User.query.get(user_id)

        return res
Beispiel #4
0
class UserStatus(db.Model):
    id = db.Column(db.String(32),
                   default=lambda: str(uuid4()).replace('-', ''),
                   primary_key=True)
    state = db.Column(db.String(16), unique=True, nullable=False)
    user = db.relationship('Users', backref='state', lazy='dynamic')

    def __repr__(self):
        return "帐号状态: <%s> " % self.state
Beispiel #5
0
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True, nullable=False)
    email = db.Column(db.String(80), unique=True, nullable=False)
    password = db.Column(db.String(64), nullable=False)
    routes = db.relationship('Routes', backref='author', lazy=True)

    def __repr__(self):
        return f'User {self.id}: ({self.username}, {self.email})'
Beispiel #6
0
class Reading(db.Model):
    __tablename__ = "reading"

    id = db.Column(UUID(as_uuid=True), primary_key=True)

    book_id = db.Column(UUID(as_uuid=True), db.ForeignKey('inventories.id'))
    book = db.relationship('Inventory', back_populates="readings")

    progress = db.Column(db.Integer(), nullable=False)
    user_id = db.Column(UUID(as_uuid=True),
                        db.ForeignKey("users.id"),
                        nullable=False)
    chapter_id = db.Column(UUID(as_uuid=True),
                           db.ForeignKey("chapters.id"),
                           nullable=False)

    def __init__(self, book, user_id):
        chapter = Chapters.get_first_chapter(book.book)
        self.book = book
        self.id = uuid.uuid4()
        self.user_id = user_id
        self.chapter_id, self.progress = chapter.id, chapter.index

    def __repr__(self):
        return "<User: %r>: 《%r》" % (self.user_id, self.book.book)

    def get_progress(self):
        chapter = Chapters.get(self.chapter_id)
        remains = Chapters.query.filter(
            Chapters.book == chapter.book,
            Chapters.index > chapter.index).count()
        return "%s_%s_%s_%s_%s" % (self.book.book, chapter.chapter,
                                   chapter.title, chapter.id, remains)

    @staticmethod
    def exists(book, user_id):
        return Reading.query.filter(Reading.book == book, Reading.user_id
                                    == user_id).count() > 0
Beispiel #7
0
class Chapters(db.Model):
    __tablename__ = "chapters"

    id = db.Column(UUID(as_uuid=True), primary_key=True)
    url = db.Column(db.String(128), unique=True, nullable=False)
    book = db.Column(db.String(32), nullable=False)
    chapter = db.Column(db.String(32), nullable=False)
    title = db.Column(db.String(32), nullable=False)
    index = db.Column(db.Integer(), nullable=False)
    content = db.Column(db.Text(), nullable=False)

    readers = db.relationship("Reading", backref="chapter", lazy=True)

    def __init__(self, url, book, chapter, title, index, content):
        self.id = uuid.uuid4()
        self.url = url
        self.book = book
        self.chapter = chapter
        self.title = title
        self.index = index
        self.content = content

    def __repr__(self):
        return "<<%r>>: %r" % (self.book, self.chapter)

    @staticmethod
    def get_books():
        books = [each.book for each in Chapters.query.distinct(Chapters.book)]
        last_chapters = [
            Chapters.query.filter_by(book=book).order_by(
                Chapters.index.desc()).first() for book in books
        ]
        return [
            "%s_%s_%s" % (chapter.book, chapter.chapter, chapter.title)
            for chapter in last_chapters
        ]

    @staticmethod
    def get_first_chapter(book_name):
        chapter = Chapters.query.filter_by(book=book_name).order_by(
            Chapters.index).first()
        return chapter

    @staticmethod
    def get_last_chapter(book_name):
        chapter = Chapters.query.filter_by(book=book_name).order_by(
            Chapters.index.desc()).first()
        return chapter

    @staticmethod
    def get(chapter_id):
        return Chapters.query.get(chapter_id)

    @staticmethod
    def download(book_name):
        chapters = Chapters.query.filter_by(book=book_name).order_by(
            Chapters.index).all()

        doc = ""
        doc += "#%s\n\n" % book_name

        for c in chapters:
            doc += "\n\n##%s %s\n\n" % (c.chapter, c.title)
            doc += c.content

        return doc

    def menu(self):
        return "%s\t%s_%s" % (self.chapter, self.title, self.id)
Beispiel #8
0
class Users(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    role_id = db.Column(
        db.String(32),
        db.ForeignKey('role.id'),
        index=True,
        default=lambda: Role.query.filter_by(name='user').first().id)
    state_id = db.Column(
        db.String(32),
        db.ForeignKey('user_status.id'),
        default=lambda: UserStatus.query.filter_by(state='reserve').first().id)

    email = db.Column(db.String(32), unique=True)
    username = db.Column(db.String(16))
    password = db.Column(db.String(128))

    finger_print = db.Column(
        db.String(28),
        default=lambda: ''.join(sample(ascii_letters + digits, 28)),
        nullable=False)
    keeper = db.relationship('Keeper', backref='owner', lazy='dynamic')
    keeper_key = db.Column(db.String(64))
    keeper_active = db.Column(db.Boolean, default=False)
    keeper_length = db.Column(db.SmallInteger, default=12)

    register_date = db.Column(db.DateTime, default=lambda: datetime.utcnow())
    last_signin_date = db.Column(db.DateTime,
                                 default=lambda: datetime.utcnow())

    @staticmethod
    def hash_password(password):
        return crypt.generate_password_hash(
            password, app.config['SECURITY']['iterations'])

    @staticmethod
    def pad(original):
        data = str(original).encode()
        padding_length = AES.block_size - len(data) % AES.block_size
        return original + padding_length * chr(padding_length)

    @staticmethod
    def unpad(padded):
        return padded[:-ord(padded[len(padded) - 1:])]

    def generate_keeper_key(self, pin):
        sha = SHA256.new()
        sha.update(("%s%s" % (self.finger_print, pin)).encode())
        return sha.hexdigest()

    def verify_keeper_key(self, pin):
        return self.generate_keeper_key(pin) == self.keeper_key

    def encrypt(self, data, pin, iv):
        cipher = AES.new("%s%s" % (self.finger_print, pin), AES.MODE_CBC,
                         self.pad(iv))
        return "{0}".format(b64encode(cipher.encrypt(self.pad(data))).decode())

    def decrypt(self, ciphered, pin, iv):
        cipher = AES.new("%s%s" % (self.finger_print, pin), AES.MODE_CBC,
                         self.pad(iv))
        return self.unpad(cipher.decrypt(b64decode(ciphered))).decode()

    def verify_password(self, _password):
        try:
            return crypt.check_password_hash(self.password, _password)
        except:
            return False

    def generate_auth_token(self):
        s = Serializer(app.config['SECRET_KEY'],
                       expires_in=app.config['SECURITY']['expiration'])
        return s.dumps({'id': self.id}).decode('utf-8')

    @staticmethod
    def verify_auth_token(token):
        s = Serializer(app.config['SECRET_KEY'])
        try:
            data = s.loads(token.encode('utf-8'))
            return Users.query.get(data['id'])
        except SignatureExpired and BadSignature:
            return None
        except:
            return None

    def user_info(self):
        return {
            'name': self.username,
            'access_key': self.role.generate_access_key(),
            'keeper_active': self.keeper_active,
            'keeper_length': self.keeper_length
        }

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