I'm building a Flask blog and setting up an admin interface now. I've read about setting up security for Flask-Admin. I've managed to set up security (access is restricted only to logged-in users) for all my models, but users can still access the '/admin' route which has just a bare home button in it.
My question is: is there any way I could hide or protect the '/admin' route, so an unauthenticated user is just redirected to the login page/ denied access?
Thanks a lot!
Attaching my current admin setup:
from flask_admin import Admin
from flask_login import current_user
from flask_admin.contrib import sqla
from wtforms.widgets import TextArea
from wtforms import TextAreaField
from samo.models import User, Post, Tag
from samo import app,db
admin = Admin(app, name='Admin', template_mode='bootstrap3')
class CKTextAreaWidget(TextArea):
def __call__(self, field, **kwargs):
if kwargs.get('class'):
kwargs['class'] += ' ckeditor'
else:
kwargs.setdefault('class', 'ckeditor')
return super(CKTextAreaWidget, self).__call__(field, **kwargs)
class CKTextAreaField(TextAreaField):
widget = CKTextAreaWidget()
class PostAdmin(sqla.ModelView):
form_overrides = dict(content=CKTextAreaField)
create_template = 'blog/ckeditor.html'
edit_template = 'blog/ckeditor.html'
form_excluded_columns = ('slug')
def is_accessible(self):
return current_user.is_authenticated
admin.add_view(PostAdmin(Post, db.session))
class TagAdmin(sqla.ModelView):
def is_accessible(self):
return current_user.is_authenticated
admin.add_view(TagAdmin(Tag, db.session))
class UserAdmin(sqla.ModelView):
def is_accessible(self):
return current_user.is_authenticated
admin.add_view(UserAdmin(User, db.session))
I use such a configuration like you described it for all my Websites. Use an AdminIndexView. Here is an example of how handle login, logout and redirection in case the user is not authorized.
class FlaskyAdminIndexView(AdminIndexView):
@expose('/')
def index(self):
if not login.current_user.is_authenticated:
return redirect(url_for('.login'))
return super(FlaskyAdminIndexView, self).index()
@expose('/login', methods=['GET', 'POST'])
def login(self):
form = LoginForm(request.form)
if helpers.validate_form_on_submit(form):
user = form.get_user()
if user is not None and user.verify_password(form.password.data):
login.login_user(user)
else:
flash('Invalid username or password.')
if login.current_user.is_authenticated:
return redirect(url_for('.index'))
self._template_args['form'] = form
return super(FlaskyAdminIndexView, self).index()
@expose('/logout')
@login_required
def logout(self):
login.logout_user()
return redirect(url_for('.login'))
In your __init__.py
where you create your admin object do this:
admin = Admin(index_view=FlaskyAdminIndexView())