Commit 7600bb59 authored by Sasha's avatar Sasha

Mongoengine auth example

parent 8b48823a
from flask import Flask, url_for, redirect, render_template, request
from flask.ext.mongoengine import MongoEngine
from flask.ext import admin, login, wtf
from flask.ext.admin.contrib.mongoengine import ModelView
# Create application
app = Flask(__name__)
# Create dummy secrey key so we can use sessions
app.config['SECRET_KEY'] = '123456790'
# MongoDB settings
app.config['MONGODB_SETTINGS'] = {'DB': 'test'}
db = MongoEngine()
db.init_app(app)
# Create user model. For simplicity, it will store passwords in plain text.
# Obviously that's not right thing to do in real world application.
class User(db.Document):
login = db.StringField(max_length=80, unique=True)
email = db.StringField(max_length=120)
password = db.StringField(max_length=64)
# Flask-Login integration
def is_authenticated(self):
return True
def is_active(self):
return True
def is_anonymous(self):
return False
def get_id(self):
return self.id
# Required for administrative interface
def __unicode__(self):
return self.login
# Define login and registration forms (for flask-login)
class LoginForm(wtf.Form):
login = wtf.TextField(validators=[wtf.required()])
password = wtf.PasswordField(validators=[wtf.required()])
def validate_login(self, field):
user = self.get_user()
if user is None:
raise wtf.ValidationError('Invalid user')
if user.password != self.password.data:
raise wtf.ValidationError('Invalid password')
def get_user(self):
return User.objects(login=self.login.data).first()
class RegistrationForm(wtf.Form):
login = wtf.TextField(validators=[wtf.required()])
email = wtf.TextField()
password = wtf.PasswordField(validators=[wtf.required()])
def validate_login(self, field):
if User.objects(login=self.login.data):
raise wtf.ValidationError('Duplicate username')
# Initialize flask-login
def init_login():
login_manager = login.LoginManager()
login_manager.setup_app(app)
# Create user loader function
@login_manager.user_loader
def load_user(user_id):
return User.objects(id=user_id).first()
# Create customized model view class
class MyModelView(ModelView):
def is_accessible(self):
return login.current_user.is_authenticated()
# Create customized index view class
class MyAdminIndexView(admin.AdminIndexView):
def is_accessible(self):
return login.current_user.is_authenticated()
# Flask views
@app.route('/')
def index():
return render_template('index.html', user=login.current_user)
@app.route('/login/', methods=('GET', 'POST'))
def login_view():
form = LoginForm(request.form)
if form.validate_on_submit():
user = form.get_user()
login.login_user(user)
return redirect(url_for('index'))
return render_template('form.html', form=form)
@app.route('/register/', methods=('GET', 'POST'))
def register_view():
form = RegistrationForm(request.form)
if form.validate_on_submit():
user = User()
form.populate_obj(user)
user.save()
login.login_user(user)
return redirect(url_for('index'))
return render_template('form.html', form=form)
@app.route('/logout/')
def logout_view():
login.logout_user()
return redirect(url_for('index'))
if __name__ == '__main__':
# Initialize flask-login
init_login()
# Create admin
admin = admin.Admin(app, 'Auth', index_view=MyAdminIndexView())
# Add view
admin.add_view(MyModelView(User))
# Start app
app.debug = True
app.run()
<html>
<body>
<form method="POST" action="">
{{ form.hidden_tag() }}
{% for f in form if f.type != 'CSRFTokenField' %}
<div>
{{ f.label }}
{{ f }}
{% if f.errors %}
<ul>
{% for e in f.errrors %}
<li>{{ e }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endfor %}
<input type="submit" />
</form>
</body>
</html>
<html>
<body>
<div>
{% if user and user.is_authenticated() %}
Hello {{ user.login }}! <a href="{{ url_for('logout_view') }}">Logout</a>
{% else %}
Welcome anonymous user!
<a href="{{ url_for('login_view') }}">Login</a>&nbsp;<a href="{{ url_for('register_view') }}">Register</a>
{% endif %}
</div>
<div>
<a href="{{ url_for('admin.index') }}">Go to admin!</a>
</div>
</body>
</html>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment