Roles and Verify Roles
User roles system and verification implimented.
This commit is contained in:
@@ -6,6 +6,7 @@ from flask_moment import Moment
|
|||||||
from flask_sqlalchemy import SQLAlchemy
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
from flask_login import LoginManager
|
from flask_login import LoginManager
|
||||||
from flask_debugtoolbar import DebugToolbarExtension
|
from flask_debugtoolbar import DebugToolbarExtension
|
||||||
|
from flask.ext.principal import Principal
|
||||||
|
|
||||||
from config import config
|
from config import config
|
||||||
|
|
||||||
@@ -15,6 +16,7 @@ mail = Mail()
|
|||||||
moment = Moment()
|
moment = Moment()
|
||||||
db = SQLAlchemy()
|
db = SQLAlchemy()
|
||||||
toolbar = DebugToolbarExtension()
|
toolbar = DebugToolbarExtension()
|
||||||
|
Principal = Principal()
|
||||||
|
|
||||||
# initialize flask_login
|
# initialize flask_login
|
||||||
login_manager = LoginManager()
|
login_manager = LoginManager()
|
||||||
@@ -37,6 +39,7 @@ def create_app(config_name):
|
|||||||
moment.init_app(dash)
|
moment.init_app(dash)
|
||||||
db.init_app(dash)
|
db.init_app(dash)
|
||||||
login_manager.init_app(dash)
|
login_manager.init_app(dash)
|
||||||
|
Principal.init_app(dash)
|
||||||
toolbar.init_app(dash)
|
toolbar.init_app(dash)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,13 +3,17 @@ import datetime
|
|||||||
from flask import render_template, redirect, request, url_for, flash
|
from flask import render_template, redirect, request, url_for, flash
|
||||||
from flask_login import login_user, logout_user, login_required, \
|
from flask_login import login_user, logout_user, login_required, \
|
||||||
current_user
|
current_user
|
||||||
|
from flask_principal import Identity, AnonymousIdentity, \
|
||||||
|
identity_changed
|
||||||
|
|
||||||
from . import admin
|
from . import admin
|
||||||
from .. import db
|
from .. import db
|
||||||
from ..models import User
|
from ..models import User
|
||||||
from ..email import send_email
|
from ..email import send_email
|
||||||
|
from ..decorators import requires_roles
|
||||||
|
|
||||||
@admin.route('/')
|
@admin.route('/index')
|
||||||
@login_required
|
@login_required
|
||||||
|
@requires_roles("admin")
|
||||||
def for_admins_only():
|
def for_admins_only():
|
||||||
return render_template('admin/index.html')
|
return render_template('admin/index.html')
|
||||||
@@ -4,7 +4,7 @@ from flask_login import login_user, logout_user, login_required, \
|
|||||||
current_user
|
current_user
|
||||||
from . import auth
|
from . import auth
|
||||||
from .. import db
|
from .. import db
|
||||||
from ..models import User
|
from ..models import User, Role
|
||||||
from ..email import send_email
|
from ..email import send_email
|
||||||
from .forms import LoginForm, RegistrationForm, PasswordResetRequestForm, \
|
from .forms import LoginForm, RegistrationForm, PasswordResetRequestForm, \
|
||||||
PasswordResetForm
|
PasswordResetForm
|
||||||
@@ -45,13 +45,14 @@ def logout():
|
|||||||
def register():
|
def register():
|
||||||
form = RegistrationForm()
|
form = RegistrationForm()
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
|
r = Role.query.filter_by(default=True).first()
|
||||||
user = User(email=form.email.data,
|
user = User(email=form.email.data,
|
||||||
username=form.username.data,
|
username=form.username.data,
|
||||||
full_name=form.full_name.data,
|
full_name=form.full_name.data,
|
||||||
password=form.password.data,
|
password=form.password.data,
|
||||||
avatar="/static/img/user2-160x160.jpg",
|
avatar="/static/img/user2-160x160.jpg",
|
||||||
created_at=datetime.datetime.now(),
|
created_at=datetime.datetime.now(),
|
||||||
role_id=2)
|
role_id=r.id)
|
||||||
db.session.add(user)
|
db.session.add(user)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
token = user.generate_confirmation_token()
|
token = user.generate_confirmation_token()
|
||||||
|
|||||||
@@ -1,4 +1,18 @@
|
|||||||
from functools import wraps
|
from functools import wraps
|
||||||
from flask import abort
|
from flask import abort, redirect, request, url_for, flash
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
|
|
||||||
|
def requires_roles(*roles):
|
||||||
|
def wrapper(f):
|
||||||
|
@wraps(f)
|
||||||
|
def wrapped(*args, **kwargs):
|
||||||
|
if get_current_user_role() not in roles:
|
||||||
|
flash('Authentication error, please check your details and try again','error')
|
||||||
|
return redirect(url_for('main.index'))
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
return wrapped
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
def get_current_user_role():
|
||||||
|
return current_user.role.name
|
||||||
@@ -17,7 +17,6 @@ class Role(db.Model):
|
|||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
name = db.Column(db.String(128), unique=True)
|
name = db.Column(db.String(128), unique=True)
|
||||||
default = db.Column(db.Boolean, default=False, index=True)
|
default = db.Column(db.Boolean, default=False, index=True)
|
||||||
permissions = db.Column(db.Integer)
|
|
||||||
users = db.relationship('User', backref='role', lazy='dynamic')
|
users = db.relationship('User', backref='role', lazy='dynamic')
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<ul class="sidebar-menu">
|
<ul class="sidebar-menu">
|
||||||
<li class="header">Admin Menu</li>
|
<li class="header">Admin Menu</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="">
|
<a href="/admin/index">
|
||||||
<i class="fa fa-dashboard"></i> <span>Admin Dashboard</span>
|
<i class="fa fa-dashboard"></i> <span>Admin Dashboard</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
{% include 'sidebar.html' %}
|
{% include 'sidebar.html' %}
|
||||||
|
|
||||||
{% if current_user.role_id == 1 %}
|
{% if current_user.role.name == "admin" %}
|
||||||
{% include 'admin/sidebar_menu.html' %}
|
{% include 'admin/sidebar_menu.html' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|||||||
@@ -206,7 +206,7 @@
|
|||||||
<li class="user-header bg-light-blue">
|
<li class="user-header bg-light-blue">
|
||||||
<img src="{{ current_user.avatar }}" class="img-circle" alt="User Image" />
|
<img src="{{ current_user.avatar }}" class="img-circle" alt="User Image" />
|
||||||
<p>
|
<p>
|
||||||
{{ current_user.full_name }} - Web Developer
|
{{ current_user.full_name }} - role : {{ current_user.role.name }}
|
||||||
<small>Member since {{ current_user.created_at.strftime("%b. %Y") }}</small>
|
<small>Member since {{ current_user.created_at.strftime("%b. %Y") }}</small>
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
"""empty message
|
"""empty message
|
||||||
|
|
||||||
Revision ID: 9643649cdb9c
|
Revision ID: 070b614d54f1
|
||||||
Revises: None
|
Revises: None
|
||||||
Create Date: 2016-07-20 23:52:07.223110
|
Create Date: 2016-08-07 18:01:50.124123
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '9643649cdb9c'
|
revision = '070b614d54f1'
|
||||||
down_revision = None
|
down_revision = None
|
||||||
|
|
||||||
from alembic import op
|
from alembic import op
|
||||||
@@ -18,10 +18,13 @@ def upgrade():
|
|||||||
### commands auto generated by Alembic - please adjust! ###
|
### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('roles',
|
op.create_table('roles',
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
sa.Column('name', sa.String(length=64), nullable=True),
|
sa.Column('name', sa.String(length=128), nullable=True),
|
||||||
|
sa.Column('default', sa.Boolean(), nullable=True),
|
||||||
|
sa.Column('permissions', sa.Integer(), nullable=True),
|
||||||
sa.PrimaryKeyConstraint('id'),
|
sa.PrimaryKeyConstraint('id'),
|
||||||
sa.UniqueConstraint('name')
|
sa.UniqueConstraint('name')
|
||||||
)
|
)
|
||||||
|
op.create_index(op.f('ix_roles_default'), 'roles', ['default'], unique=False)
|
||||||
op.create_table('users',
|
op.create_table('users',
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
sa.Column('email', sa.String(length=128), nullable=True),
|
sa.Column('email', sa.String(length=128), nullable=True),
|
||||||
@@ -49,5 +52,6 @@ def downgrade():
|
|||||||
op.drop_index(op.f('ix_users_email'), table_name='users')
|
op.drop_index(op.f('ix_users_email'), table_name='users')
|
||||||
op.drop_index(op.f('ix_users_avatar'), table_name='users')
|
op.drop_index(op.f('ix_users_avatar'), table_name='users')
|
||||||
op.drop_table('users')
|
op.drop_table('users')
|
||||||
|
op.drop_index(op.f('ix_roles_default'), table_name='roles')
|
||||||
op.drop_table('roles')
|
op.drop_table('roles')
|
||||||
### end Alembic commands ###
|
### end Alembic commands ###
|
||||||
26
migrations/versions/ad5c9cae2c6d_.py
Normal file
26
migrations/versions/ad5c9cae2c6d_.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
"""empty message
|
||||||
|
|
||||||
|
Revision ID: ad5c9cae2c6d
|
||||||
|
Revises: 070b614d54f1
|
||||||
|
Create Date: 2016-08-07 18:16:57.701675
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'ad5c9cae2c6d'
|
||||||
|
down_revision = '070b614d54f1'
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects import mysql
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_column('roles', 'permissions')
|
||||||
|
### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column('roles', sa.Column('permissions', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True))
|
||||||
|
### end Alembic commands ###
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
"""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 ###
|
|
||||||
@@ -15,3 +15,4 @@ Werkzeug
|
|||||||
alembic
|
alembic
|
||||||
blinker
|
blinker
|
||||||
itsdangerous
|
itsdangerous
|
||||||
|
flask-principal
|
||||||
Reference in New Issue
Block a user