Login works great on my standard views, and the admin works great, but i can't seem to add login to my admin/yikes!!!
It seems straightforward flask admin docs but when I add this section
class MyView(BaseView):
def is_accessible(self):
return login.current_user.is_authenticated()
def _handle_view(self, name, **kwargs):
if not self.is_accessible():
return redirect(url_for('login', next=request.url))
I don't get sent to the login page for unauthenticated users.
any idea what else i need to do?
Does this look correct in my init file?
from flask.ext.admin import BaseView
class MyView(BaseView):
def is_accessible(self):
return login.current_user.is_authenticated()
def _handle_view(self, name, **kwargs):
if not self.is_accessible():
return redirect(url_for('login', next=request.url))
app = Flask(__name__)
app.config.from_object('config')
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
Bootstrap(app)
from app import views, models
admin = Admin(app)
admin.add_view(ModelView(models.User, db.session))
admin.add_view(ModelView(models.rutable, db.session))
admin.add_view(ModelView(models.rustage, db.session))
admin.add_view(ModelView(models.TOC, db.session))
admin.add_view(ModelView(models.Request, db.session))
admin.add_view(ModelView(models.Staff, db.session))
admin.add_view(ModelView(models.Status, db.session))
admin.add_view(ModelView(models.Challenge, db.session))
here are my login views which are connected to ldap auth
from flask.ext.admin import BaseView
def logged_in(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if session.get('logged_in') is not None:
return f(*args, **kwargs)
else:
flash('Please log in first...', 'error')
next_url = request.url
login_url = '%s?next=%s' % (url_for('login'), next_url)
return redirect(login_url)
return decorated_function
@login_manager.unauthorized_handler
def unauthorized():
print 'unauthorized'
flash("You must be logged in.")
return redirect(url_for("login"))
@login_manager.user_loader
def user_loader(user_id):
"""Given *user_id*, return the associated User object.
:param unicode user_id: user_id (email) user to retrieve
"""
g.user=current_user
return models.User.query.get(user_id)
@app.route("/logout")
# @logged_in
def logout():
logout_user()
session.pop('logged_in', None)
flash("Logged Out.")
return redirect(url_for("login"))
@app.before_request
def before_request():
g.user = current_user
@app.route("/login", methods=["GET", "POST"])
def login():
form = LoginForm()
if form.validate_on_submit():
if app.config['ENVIRONMENT']=='dev':
try:
print "Authentification Successful"
namedb=models.User.query.filter_by(name=unicode(form.username.data)).first()
email=models.User.query.first().email
login_user(user_loader(unicode(email)),remember=form.remember_me.data)
flash("Logged in successfully.")
g.email=email
session['logged_in'] = True
return redirect( request.values.get('next') or url_for("main"))
except Exception as e:
flash("Invalid Credentials.")
return render_template("login.html", form=form)
else:
try:
if '@' in form.username.data:
form.username.data=re.sub(' /d+','', (re.sub("\d+",'', form.username.data.split('@')[0]))[1:]+(re.sub("\d+",'', form.username.data.split('@')[0]))[0:1])
l = ldap.initialize("ldap://10.129.18.101")
l.simple_bind_s("program\%s" % form.username.data,form.password.data)
print "Authentification Successful"
r=l.search_s('cn=Users,dc=BHCS,dc=Internal',ldap.SCOPE_SUBTREE,'(sAMAccountName=*%s*)' % form.username.data,['mail','objectGUID','displayName'])
email=r[0][1]['mail'][0]
GUID=r[0][1]['objectGUID'][0]
FullName=r[0][1]['displayName'][0]
import uuid
guid = uuid.UUID(bytes=GUID)
if not models.User.query.filter_by(email=unicode(email)).first():
p=models.User(name=FullName,email=email)
db.session.add(p)
db.session.commit()
login_user(user_loader(unicode(email)),remember=form.remember_me.data)
flash("Logged in successfully.")
g.email=email
session['logged_in'] = True
return redirect( request.values.get('next') or url_for("main"))
except Exception as e:
flash("Invalid Credentials.")
return render_template("login.html", form=form)
return render_template("login.html", form=form)
As requested, here is my user class from my model
class User(db.Model):
"""An admin user capable of viewing reports.
:param str email: email address of user
:param str password: encrypted password for the user
"""
__tablename__ = 'user'
name=db.Column(db.String)
email = db.Column(db.String, primary_key=True)
authenticated = db.Column(db.Boolean, default=True)
admin = db.Column(db.Boolean, default=False)
def is_active(self):
"""True, as all users are active."""
return True
def get_id(self):
"""Return the email address to satisfy Flask-Login's requirements."""
return self.email
def is_authenticated(self):
"""Return True if the user is authenticated."""
return self.authenticated
def is_anonymous(self):
"""False, as anonymous users aren't supported."""
return False
After a lot of trial and error (more error) i finally copied enough from the example (partial understanding) to get it working. It seems i needed to add a super to MyAdminIndexView() to get it working. that is
I moved my "MyView" function out of the init and added this line
admin = Admin(app, 'example',index_view=views.MyAdminIndexView())
Changed my view significantly based on the example
class MyModelView(sqla.ModelView):
def is_accessible(self):
return g.user.is_authenticated()
class MyAdminIndexView(admin.AdminIndexView):
@expose('/')
def index(self):
if not g.user.is_authenticated():
flash('Please log in first...', 'error')
next_url = request.url
login_url = '%s?next=%s' % (url_for('login'), next_url)
return redirect(login_url)
# import pdb;pdb.set_trace()
if g.user.admin == True:
return super(MyAdminIndexView,self).index()
else:
return redirect(url_for("main"))
def logged_in(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if session.get('logged_in') is not None:
return f(*args, **kwargs)
else:
flash('Please log in first...', 'error')
next_url = request.url
login_url = '%s?next=%s' % (url_for('login'), next_url)
return redirect(login_url)
return decorated_function
@login_manager.unauthorized_handler
def unauthorized():
print 'unauthorized'
flash("You must be logged in.")
return redirect(url_for("login"))
@login_manager.user_loader
def user_loader(user_id):
"""Given *user_id*, return the associated User object.
:param unicode user_id: user_id (email) user to retrieve
"""
g.user=current_user
return models.User.query.get(user_id)
@app.route("/logout")
# @logged_in
def logout():
logout_user()
session.pop('logged_in', None)
flash("Logged Out.")
return redirect(url_for("login"))
@app.before_request
def before_request():
g.user = current_user
And now I have it working. Thank you so much for the examples!