diff --git a/config.py b/config.py index d2df949..ff36ab7 100644 --- a/config.py +++ b/config.py @@ -4,9 +4,9 @@ basedir = os.path.abspath(os.path.dirname(__file__)) class Config: SECRET_KEY = os.environ.get('SECRET_KEY') or 'hard to guess string' SQLALCHEMY_COMMIT_ON_TEARDOWN = True - FLASKY_MAIL_SUBJECT_PREFIX = '[dash-stack]' - FLASKY_MAIL_SENDER = 'dash-stack Admin ' - FLASKY_ADMIN = os.environ.get('DASH_STACK_ADMIN') + DASH_MAIL_SUBJECT_PREFIX = '[dash-stack]' + DASH_MAIL_SENDER = 'dash-stack Admin ' + DASH_ADMIN = "ozkasgarli@gmail.com" @staticmethod def init_app(dash): diff --git a/dash/email.py b/dash/email.py index 61579ef..9a35b8c 100644 --- a/dash/email.py +++ b/dash/email.py @@ -11,8 +11,8 @@ def send_async_email(dash, msg): def send_email(to, subject, template, **kwargs): dash = current_app._get_current_object() - msg = Message(dash.config['FLASKY_MAIL_SUBJECT_PREFIX'] + ' ' + subject, - sender=dash.config['FLASKY_MAIL_SENDER'], recipients=[to]) + msg = Message(dash.config['DASH_MAIL_SUBJECT_PREFIX'] + ' ' + subject, + sender=dash.config['DASH_MAIL_SENDER'], recipients=[to]) msg.body = render_template(template + '.txt', **kwargs) msg.html = render_template(template + '.html', **kwargs) thr = Thread(target=send_async_email, args=[dash, msg]) diff --git a/dash/models.py b/dash/models.py index cd34292..294262b 100644 --- a/dash/models.py +++ b/dash/models.py @@ -10,14 +10,77 @@ from flask_login import UserMixin from . import db from . import login_manager +# user roles +class Permission: + ## user permissions + # instance management + LAUNCH_INSTANCE = 0x1A + REMOVE_INSTANCE = 0x2A + MANAGE_INSTANCE = 0x3A + LIST_INSTANCE = 0x4A + + ## reseller permissions + # Users Management + CREATE_USER = 0x1B + MANAGE_USER = 0x2B + DELETE_USER = 0x3B + LIST_USER = 0x4B + SUSPEND_USER = 0x5B + UNSUSPEND_USER = 0x6B + + # Tenant Management + CREATE_TENANT = 0x7B + MANAGE_TENANT = 0x8B + DELETE_TENANT = 0x9B + LIST_TENANT = 0xB1 + SUSPEND_TENANT = 0xB2 + UNSUSPEND_TENANT = 0xB3 + MODIFY_TENANT_QUOTA = 0xB4 + + # administrator permissions class Role(db.Model): __tablename__ = 'roles' id = db.Column(db.Integer, primary_key=True) - name = db.Column(db.String(64), unique=True) + name = db.Column(db.String(128), unique=True) + default = db.Column(db.Boolean, default=False, index=True) + permissions = db.Column(db.Integer) users = db.relationship('User', backref='role', lazy='dynamic') - + + # creates roles and permissions in db + @staticmethod + def insert_roles(): + roles = { + 'User': (Permission.LAUNCH_INSTANCE | + Permission.REMOVE_INSTANCE | + Permission.MANAGE_INSTANCE | + Permission.LIST_INSTANCE, True), + 'Reseller': (Permission.CREATE_USER | + Permission.MANAGE_USER | + Permission.DELETE_USER | + Permission.LIST_USER | + Permission.SUSPEND_USER | + Permission.UNSUSPEND_USER | + # tenant management + Permission.CREATE_TENANT | + Permission.MANAGE_TENANT | + Permission.DELETE_TENANT | + Permission.LIST_TENANT | + Permission.SUSPEND_TENANT | + Permission.UNSUSPEND_TENANT | + Permission.MODIFY_TENANT_QUOTA, False), + 'Administrator': (0xff, False) + } + for r in roles: + role = Role.query.filter_by(name=r).first() + if role is None: + role = Role(name=r) + role.permissions = roles[r][0] + role.default = roles[r][1] + db.session.add(role) + db.session.commit() + def __repr__(self): return '' % self.name @@ -34,7 +97,7 @@ class User(UserMixin, db.Model): created_at = db.Column(db.DateTime) role_id = db.Column(db.Integer, db.ForeignKey('roles.id')) confirmed = db.Column(db.Boolean, default=False) - + @property def password(self): raise AttributeError('password is not a readable attribute') @@ -102,7 +165,16 @@ class User(UserMixin, db.Model): self.email = new_email db.session.add(self) return True - + + # Role assignment + def __init__(self, **kwargs): + super(User, self).__init__(**kwargs) + if self.role is None: + if self.email == current_app.config['DASH_ADMIN']: + self.role = Role.query.filter_by(permissions=0xff).first() + if self.role is None: + self.role = Role.query.filter_by(default=True).first() + def __repr__(self): return '' % self.username diff --git a/migrations/versions/c751862fad43_.py b/migrations/versions/c751862fad43_.py new file mode 100644 index 0000000..6533069 --- /dev/null +++ b/migrations/versions/c751862fad43_.py @@ -0,0 +1,30 @@ +"""empty message + +Revision ID: c751862fad43 +Revises: 9643649cdb9c +Create Date: 2016-08-06 20:06:07.900854 + +""" + +# revision identifiers, used by Alembic. +revision = 'c751862fad43' +down_revision = '9643649cdb9c' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + ### commands auto generated by Alembic - please adjust! ### + op.add_column('roles', sa.Column('default', sa.Boolean(), nullable=True)) + op.add_column('roles', sa.Column('permissions', sa.Integer(), nullable=True)) + op.create_index(op.f('ix_roles_default'), 'roles', ['default'], unique=False) + ### end Alembic commands ### + + +def downgrade(): + ### commands auto generated by Alembic - please adjust! ### + op.drop_index(op.f('ix_roles_default'), table_name='roles') + op.drop_column('roles', 'permissions') + op.drop_column('roles', 'default') + ### end Alembic commands ###