Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask-Admin & Authentication: "/admin" is protected but "/admin/anything-else" is not

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.

like image 444
Brian Avatar asked Jul 11 '13 00:07

Brian


People also ask

What does Flask-Admin do?

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.

How do I make myself admin in Flask?

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.

How do I use config in Flask?

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.

Where is app config in Flask?

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"] .


1 Answers

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

like image 138
crm Avatar answered Sep 18 '22 14:09

crm