diff --git a/admin/mailu/models.py b/admin/mailu/models.py index a0cda366..f207fa16 100644 --- a/admin/mailu/models.py +++ b/admin/mailu/models.py @@ -1,7 +1,7 @@ from mailu import app, db, dkim, login_manager from sqlalchemy.ext import declarative -from passlib import context +from passlib import context, hash from datetime import datetime import re @@ -249,6 +249,29 @@ class Alias(Base, Email): destination = db.Column(CommaSeparatedList, nullable=False, default=[]) +class Token(Base): + """ A token is an application password for a given user. + """ + __tablename__ = "token" + + id = db.Column(db.Integer(), primary_key=True) + user_email = db.Column(db.String(255), db.ForeignKey(User.email), + nullable=False) + user = db.relationship(User, + backref=db.backref('tokens', cascade='all, delete-orphan')) + password = db.Column(db.String(255), nullable=False) + ip = db.Column(db.String(255)) + + def check_password(self, password): + return hash.sha256_crypt.verify(password, self.password) + + def set_password(self, password): + self.password = hash.sha256_crypt.hash(password) + + def __str__(self): + return self.comment + + class Fetch(Base): """ A fetched account is a repote POP/IMAP account fetched into a local account. diff --git a/admin/migrations/versions/9400a032eb1a_.py b/admin/migrations/versions/9400a032eb1a_.py new file mode 100644 index 00000000..f629a7eb --- /dev/null +++ b/admin/migrations/versions/9400a032eb1a_.py @@ -0,0 +1,32 @@ +""" Add authentication tokens + +Revision ID: 9400a032eb1a +Revises: 9c28df23f77e +Create Date: 2017-10-29 14:31:58.032989 + +""" + +# revision identifiers, used by Alembic. +revision = '9400a032eb1a' +down_revision = '9c28df23f77e' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + op.create_table('token', + sa.Column('created_at', sa.Date(), nullable=False), + sa.Column('updated_at', sa.Date(), nullable=True), + sa.Column('comment', sa.String(length=255), nullable=True), + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('user_email', sa.String(length=255), nullable=False), + sa.Column('password', sa.String(length=255), nullable=False), + sa.Column('ip', sa.String(length=255), nullable=True), + sa.ForeignKeyConstraint(['user_email'], ['user.email'], ), + sa.PrimaryKeyConstraint('id') + ) + + +def downgrade(): + op.drop_table('token')