diff --git a/dash/__init__.py b/dash/__init__.py index c07e539..d9bc5f1 100644 --- a/dash/__init__.py +++ b/dash/__init__.py @@ -54,4 +54,8 @@ def create_app(config_name): from .profile import profile as profile_blueprint dash.register_blueprint(profile_blueprint, url_prefix='/profile') + # admin application + from .admin import admin as admin_blueprint + dash.register_blueprint(admin_blueprint, url_prefix='/admin') + return dash \ No newline at end of file diff --git a/dash/admin/__init__.py b/dash/admin/__init__.py new file mode 100644 index 0000000..8f931aa --- /dev/null +++ b/dash/admin/__init__.py @@ -0,0 +1,5 @@ +from flask import Blueprint + +admin = Blueprint('admin', __name__) + +from . import views \ No newline at end of file diff --git a/dash/admin/forms.py b/dash/admin/forms.py new file mode 100644 index 0000000..082a6fb --- /dev/null +++ b/dash/admin/forms.py @@ -0,0 +1,5 @@ +from flask_wtf import Form +from flask import flash +from wtforms import StringField, PasswordField, BooleanField, SubmitField, ValidationError +from wtforms.validators import Required, Length, Email, Regexp, EqualTo +from ..models import User \ No newline at end of file diff --git a/dash/admin/views.py b/dash/admin/views.py new file mode 100644 index 0000000..1f08935 --- /dev/null +++ b/dash/admin/views.py @@ -0,0 +1,15 @@ +import datetime + +from flask import render_template, redirect, request, url_for, flash +from flask_login import login_user, logout_user, login_required, \ + current_user + +from . import admin +from .. import db +from ..models import User +from ..email import send_email + +@admin.route('/') +@login_required +def for_admins_only(): + return render_template('admin/index.html') \ No newline at end of file diff --git a/dash/auth/views.py b/dash/auth/views.py index c6129c5..b7cf2b0 100644 --- a/dash/auth/views.py +++ b/dash/auth/views.py @@ -50,7 +50,8 @@ def register(): full_name=form.full_name.data, password=form.password.data, avatar="/static/img/user2-160x160.jpg", - created_at=datetime.datetime.now()) + created_at=datetime.datetime.now(), + role_id=2) db.session.add(user) db.session.commit() token = user.generate_confirmation_token() diff --git a/dash/decorators.py b/dash/decorators.py index 7ed8a9f..0b038e0 100644 --- a/dash/decorators.py +++ b/dash/decorators.py @@ -2,18 +2,3 @@ from functools import wraps from flask import abort from flask_login import current_user -from .models import Permission - -def permission_required(permission): - def decorator(f): - @wraps(f) - def decorated_function(*args, **kwargs): - if not current_user.can(permission): - abort(403) - return f(*args, **kwargs) - return decorated_function - return decorator - -def admin_required(f): - return permission_required(Permission.ADMINISTER)(f) - \ No newline at end of file diff --git a/dash/flask_adminlte/templates/adminlte/base.html b/dash/flask_adminlte/templates/adminlte/base.html index bf32020..e8e160e 100644 --- a/dash/flask_adminlte/templates/adminlte/base.html +++ b/dash/flask_adminlte/templates/adminlte/base.html @@ -55,8 +55,8 @@
{% block brand %} {% endblock %} diff --git a/dash/main/__init__.py b/dash/main/__init__.py index cc53e3f..9ca777c 100644 --- a/dash/main/__init__.py +++ b/dash/main/__init__.py @@ -1,11 +1,5 @@ from flask import Blueprint -from ..models import Permission - main = Blueprint('main', __name__) -@main.app_context_processor -def inject_permissions(): - return dict(Permission=Permission) - from . import views, errors \ No newline at end of file diff --git a/dash/main/views.py b/dash/main/views.py index 118596f..ec736c8 100644 --- a/dash/main/views.py +++ b/dash/main/views.py @@ -6,11 +6,10 @@ from flask_login import login_required from .. import db -from ..models import User, Permission +from ..models import User from ..email import send_email from . import main from .forms import NameForm -from ..decorators import admin_required, permission_required @main.route('/', methods=['GET', 'POST']) @@ -23,14 +22,7 @@ def lockscreen(): current_user = User() return render_template('lockscreen.html', current_user=current_user) -@main.route('/admin') -@login_required -@admin_required -def for_admins_only(): - return "For administrators only!" - @main.route('/reseller') @login_required -@permission_required(Permission.LIST_USER) def for_resellers_only(): return "For resellers only! We mean it..." \ No newline at end of file diff --git a/dash/models.py b/dash/models.py index 3053801..b8456f0 100644 --- a/dash/models.py +++ b/dash/models.py @@ -10,35 +10,6 @@ from flask_login import UserMixin, AnonymousUserMixin 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 - ADMINISTER = 0xff class Role(db.Model): __tablename__ = 'roles' @@ -48,39 +19,6 @@ class Role(db.Model): 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 @@ -166,35 +104,10 @@ 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 can(self, permissions): - return self.role is not None and \ - (self.role.permissions & permissions) == permissions - - def is_administrator(self): - return self.can(Permission.ADMINISTER) def __repr__(self): return '' % self.username -class AnonymousUser(AnonymousUserMixin): - def can(self, permissions): - return False - - def is_administrator(): - return False - -login_manager.anonymous_user = AnonymousUser - @login_manager.user_loader def load_user(user_id): return User.query.get(int(user_id)) \ No newline at end of file diff --git a/dash/templates/admin/content_header.html b/dash/templates/admin/content_header.html new file mode 100644 index 0000000..0832165 --- /dev/null +++ b/dash/templates/admin/content_header.html @@ -0,0 +1,8 @@ +

+ Admin Dashboard + Dashboard for Administrators +

+ \ No newline at end of file diff --git a/dash/templates/admin/index.html b/dash/templates/admin/index.html new file mode 100644 index 0000000..3c0f304 --- /dev/null +++ b/dash/templates/admin/index.html @@ -0,0 +1,23 @@ +{% extends "adminlte/base.html" %} +{% import "adminlte/layout.html" as layout with context %} +{% import "adminlte/widgets.html" as widgets with context %} + +{% block navbar %} + + {% include "navbar.html" %} + +{%- endblock navbar %} + + +{% block sidebar -%} + + {% include 'sidebar.html' %} + + {% include 'admin/sidebar_menu.html' %} + +{%- endblock sidebar %} + + +{% block content_header -%} + {% include 'admin/content_header.html' %} +{%- endblock content_header %} \ No newline at end of file diff --git a/dash/templates/admin/sidebar_menu.html b/dash/templates/admin/sidebar_menu.html new file mode 100644 index 0000000..33cdd17 --- /dev/null +++ b/dash/templates/admin/sidebar_menu.html @@ -0,0 +1,36 @@ + \ No newline at end of file diff --git a/dash/templates/content_header.html b/dash/templates/content_header.html new file mode 100644 index 0000000..60e95aa --- /dev/null +++ b/dash/templates/content_header.html @@ -0,0 +1,8 @@ +

+ Dashboard + Preview page +

+ \ No newline at end of file diff --git a/dash/templates/index.html b/dash/templates/index.html index 9d60073..14065f1 100644 --- a/dash/templates/index.html +++ b/dash/templates/index.html @@ -3,304 +3,28 @@ {% import "adminlte/widgets.html" as widgets with context %} {% block navbar %} - - - Toggle navigation - - - - - + {% include "navbar.html" %} + {%- endblock navbar %} + + {% block sidebar -%} - - -
-
- User Image -
-
-

{{ current_user.full_name }}

- - - Online - -
-
- - {%- endblock sidebar %} + + {% block content_header -%} -

- Dashboard - Preview page -

- + {% include 'content_header.html' %} {%- endblock content_header %} + + {% block content -%}