Skip to content

Commit 3e5e7ce

Browse files
committed
added authentication to admin route using flask-security
1 parent b9a11d2 commit 3e5e7ce

File tree

6 files changed

+292
-9
lines changed

6 files changed

+292
-9
lines changed

app/admin.py

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,32 @@
1-
from flask_admin import Admin
1+
from flask_admin import Admin, AdminIndexView
22
from flask_admin.contrib.sqla import ModelView
3-
3+
from flask import Flask, url_for, redirect, render_template, request, abort
44
from app import db
5-
from .models import Resource, Category, Language
5+
from .models import Resource, Category, Language, User, Role
6+
from flask_security import current_user
7+
8+
9+
class AdminView(ModelView):
10+
def is_accessible(self):
11+
return current_user.has_role("admin")
12+
13+
def inaccessible_callback(self):
14+
return redirect(url_for("security.login", next=request.url))
15+
16+
class HomeAdminView(AdminIndexView):
17+
def is_accessible(self):
18+
return current_user.has_role("admin")
19+
20+
def inaccessible_callback(self, name):
21+
return redirect(url_for("security.login", next=request.url))
622

723

824
def run_flask_admin(app):
9-
admin = Admin(app, name="Admin")
10-
admin.add_view(ModelView(Resource, db.session))
11-
admin.add_view(ModelView(Category, db.session))
12-
admin.add_view(ModelView(Language, db.session))
25+
admin = Admin(app, name="Resources_api", url='/', index_view=HomeAdminView(name="Home"))
26+
admin.add_view(AdminView(Role, db.session))
27+
admin.add_view(AdminView(User, db.session))
28+
admin.add_view(AdminView(Resource, db.session))
29+
admin.add_view(AdminView(Category, db.session))
30+
admin.add_view(AdminView(Language, db.session))
31+
return admin
32+

app/models.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from sqlalchemy import DateTime
33
from sqlalchemy.sql import func
44
from sqlalchemy_utils import URLType
5+
from flask_security import RoleMixin, UserMixin
56

67
language_identifier = db.Table('language_identifier',
78
db.Column(
@@ -203,3 +204,42 @@ class VoteInformation(db.Model):
203204
current_direction = db.Column(db.String, nullable=False)
204205
resource = db.relationship('Resource', back_populates='voters')
205206
voter = db.relationship('Key', back_populates='voted_resources')
207+
208+
209+
roles_users = db.Table(
210+
'roles_users',
211+
db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
212+
db.Column('role_id', db.Integer(), db.ForeignKey('role.id'))
213+
)
214+
215+
216+
# Role class
217+
class Role(db.Model, RoleMixin):
218+
# Our Role has three fields, ID, name and description
219+
id = db.Column(db.Integer(), primary_key=True)
220+
name = db.Column(db.String(80), unique=True)
221+
description = db.Column(db.String(255))
222+
223+
def __str__(self):
224+
return self.name
225+
226+
# __hash__ is required to avoid the exception TypeError: unhashable type: 'Role' when saving a User
227+
def __hash__(self):
228+
return hash(self.name)
229+
230+
231+
# User class
232+
class User(db.Model, UserMixin):
233+
234+
# Our User has six fields: ID, email, password, active, confirmed_at and roles. The roles field represents a
235+
# many-to-many relationship using the roles_users table. Each user may have no role, one role, or multiple roles.
236+
id = db.Column(db.Integer, primary_key=True)
237+
email = db.Column(db.String(255), unique=True)
238+
password = db.Column(db.String(255))
239+
active = db.Column(db.Boolean())
240+
confirmed_at = db.Column(db.DateTime())
241+
roles = db.relationship(
242+
'Role',
243+
secondary=roles_users,
244+
backref=db.backref('users', lazy='dynamic')
245+
)

configs.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ class Config:
4545

4646
SQLALCHEMY_DATABASE_URI = f"postgresql://{pg_user}:{pg_pw}@{pg_host}:5432/{pg_db}"
4747

48+
SECRET_KEY = os.urandom(24)
49+
# Set config values for Flask-Security.
50+
# We're using PBKDF2 with salt.
51+
SECURITY_PASSWORD_HASH = 'pbkdf2_sha512'
52+
# Replace this with your own salt.
53+
SECURITY_PASSWORD_SALT = os.urandom(140)
54+
4855
ALGOLIA_APP_ID = algolia_app_id
4956
ALGOLIA_API_KEY = algolia_api_key
5057
INDEX_NAME = index_name

0 commit comments

Comments
 (0)