I'm trying to customize my Admin views with Flask and Flask-SuperAdmin, however, the index view and subviews are apparently not using the same is_accessible
method:
EDIT: I managed to figure out what I was doing wrong. I needed to define is_accessible in every view class. This is well-accomplished with a mixin-class, as show in the fixed code:
app/frontend/admin.py (FIXED & WORKING CODE)
from flask.ext.security import current_user, login_required
from flask.ext.superadmin import expose, AdminIndexView
from flask.ext.superadmin.model.base import ModelAdmin
from ..core import db
# all admin views should subclass AuthMixin
class AuthMixin(object):
def is_accessible(self):
if current_user.is_authenticated() and current_user.has_role('Admin'):
return True
return False
# the view that gets used for the admin home page
class AdminIndex(AuthMixin, AdminIndexView):
# use a custom template for the admin home page
@expose('/')
def index(self):
return self.render('admin/index.jade')
# base view for all other admin pages
class AdminBase(AuthMixin, ModelAdmin): # AuthMixin must come before ModelAdmin!
"""A base class for customizing admin views using our DB connection."""
session = db.session
# customize the form displays for User and Role models
class UserAdmin(AdminBase):
list_display = ('email',)
search_fields = ('email',)
exclude = ['password',]
#fields_order = ['email', 'active', 'last_login_at',]
class RoleAdmin(AdminBase):
field_args = {'name': {'label': 'Role Name'},
'description': {'description': "Duties & Responsibilities"}}
list_display = ('name', 'description')
Then set up the Flask app with our admin views:
apps/factory.py
app = Flask(package_name, instance_relative_config=True)
# other app setup stuff like db, mail, ...
from .frontend.admin import AdminIndex, UserAdmin, RoleAdmin
admin = Admin(app, name='PyCBM Admin',
index_view=AdminIndex(url='/admin', name='Admin Home'))
admin.register(User, UserAdmin)
admin.register(Role, RoleAdmin)
So, like the title says, here's the problem:
/admin throws a 403 when an 'Admin' user isn't logged in, like it should, but
/admin/user lets anybody right on in.
I dug through the source code to try to find another "global all-of-admin-blueprint" security function - maybe I'm blind - but I couldn't find one.
The basic concept behind Flask-Admin, is that it lets you build complicated interfaces by grouping individual views together in classes: Each web page you see on the frontend, represents a method on a class that has explicitly been added to the interface.
It's very easy to use flask-admin, just import the Admin class, create a new object with it, and pass in our flask application object as the first parameter, the name argument is the name that's displayed on the admin homepage, it defaults to the application name.
Independent of how you load your config, there is a config object available which holds the loaded configuration values: The config attribute of the Flask object. This is the place where Flask itself puts certain configuration values and also where extensions can put their configuration values.
The config.py file should contain one variable assignment per line. When your app is initialized, the variables in config.py are used to configure Flask and its extensions are accessible via the app. config dictionary – e.g. app. config["DEBUG"] .
If you go to flask_superadmin/base.py
, at line 193 there is the following code snippet:
def _handle_view(self, name, *args, **kwargs):
if not self.is_accessible():
return abort(403)
So maybe this method has to be overriden by AdminIndex
to avoid returning abort(403)
but to redirect to /login
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With