first pass, non-working
This commit is contained in:
		
							parent
							
								
									459a9c2c59
								
							
						
					
					
						commit
						3c2f4a0445
					
				
					 17 changed files with 295 additions and 121 deletions
				
			
		|  | @ -161,4 +161,4 @@ if ENV != "DEV": | ||||||
|     ASSETS_DEBUG = False |     ASSETS_DEBUG = False | ||||||
|     SQLALCHEMY_ECHO = False |     SQLALCHEMY_ECHO = False | ||||||
| 
 | 
 | ||||||
| MODULES = ['wiki', 'auth', 'search'] | MODULES = ['wiki', 'search', 'auth', 'auth.local', 'auth.oauth'] | ||||||
|  |  | ||||||
							
								
								
									
										0
									
								
								realms/modules/auth/ldap/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								realms/modules/auth/ldap/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								realms/modules/auth/local/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								realms/modules/auth/local/__init__.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -1,9 +1,10 @@ | ||||||
| import click | import click | ||||||
| from realms.lib.util import random_string | from realms.lib.util import random_string | ||||||
| from realms.modules.auth.models import User | from realms.modules.auth.local.models import User | ||||||
| from realms.lib.util import green, red, yellow | from realms.lib.util import green, red, yellow | ||||||
| from realms import flask_cli | from realms import flask_cli | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| @flask_cli.group(short_help="Auth Module") | @flask_cli.group(short_help="Auth Module") | ||||||
| def cli(): | def cli(): | ||||||
|     pass |     pass | ||||||
							
								
								
									
										107
									
								
								realms/modules/auth/local/models.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								realms/modules/auth/local/models.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,107 @@ | ||||||
|  | from flask import current_app, render_template | ||||||
|  | from flask.ext.login import logout_user, login_user | ||||||
|  | from realms import login_manager, db | ||||||
|  | from realms.lib.model import Model | ||||||
|  | from ..models import BaseUser | ||||||
|  | from .forms import LoginForm | ||||||
|  | from itsdangerous import URLSafeSerializer, BadSignature | ||||||
|  | from hashlib import sha256 | ||||||
|  | import bcrypt | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @login_manager.token_loader | ||||||
|  | def load_token(token): | ||||||
|  |     # Load unsafe because payload is needed for sig | ||||||
|  |     sig_okay, payload = URLSafeSerializer(current_app.config['SECRET_KEY']).loads_unsafe(token) | ||||||
|  | 
 | ||||||
|  |     if not payload: | ||||||
|  |         return None | ||||||
|  | 
 | ||||||
|  |     # User key *could* be stored in payload to avoid user lookup in db | ||||||
|  |     user = User.get_by_id(payload.get('id')) | ||||||
|  | 
 | ||||||
|  |     if not user: | ||||||
|  |         return None | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         if BaseUser.signer(sha256(user.password).hexdigest()).loads(token): | ||||||
|  |             return user | ||||||
|  |         else: | ||||||
|  |             return None | ||||||
|  |     except BadSignature: | ||||||
|  |         return None | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class User(Model, BaseUser): | ||||||
|  |     __tablename__ = 'users' | ||||||
|  |     type = 'local' | ||||||
|  |     id = db.Column(db.Integer, primary_key=True) | ||||||
|  |     username = db.Column(db.String(128), unique=True) | ||||||
|  |     email = db.Column(db.String(128), unique=True) | ||||||
|  |     password = db.Column(db.String(60)) | ||||||
|  |     admin = False | ||||||
|  | 
 | ||||||
|  |     hidden_fields = ['password'] | ||||||
|  |     readonly_fields = ['email', 'password'] | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def auth_token_id(self): | ||||||
|  |         return self.password | ||||||
|  | 
 | ||||||
|  |     @staticmethod | ||||||
|  |     def load_user(*args, **kwargs): | ||||||
|  |         return User.get_by_id(args[0]) | ||||||
|  | 
 | ||||||
|  |     @staticmethod | ||||||
|  |     def create(username, email, password): | ||||||
|  |         u = User() | ||||||
|  |         u.username = username | ||||||
|  |         u.email = email | ||||||
|  |         u.password = User.hash_password(password) | ||||||
|  |         u.save() | ||||||
|  | 
 | ||||||
|  |     @staticmethod | ||||||
|  |     def get_by_username(username): | ||||||
|  |         return User.query().filter_by(username=username).first() | ||||||
|  | 
 | ||||||
|  |     @staticmethod | ||||||
|  |     def get_by_email(email): | ||||||
|  |         return User.query().filter_by(email=email).first() | ||||||
|  | 
 | ||||||
|  |     @staticmethod | ||||||
|  |     def signer(salt): | ||||||
|  |         return URLSafeSerializer(current_app.config['SECRET_KEY'] + salt) | ||||||
|  | 
 | ||||||
|  |     @staticmethod | ||||||
|  |     def auth(email, password): | ||||||
|  |         user = User.get_by_email(email) | ||||||
|  | 
 | ||||||
|  |         if not user: | ||||||
|  |             # User doesn't exist | ||||||
|  |             return False | ||||||
|  | 
 | ||||||
|  |         if User.check_password(password, user.password): | ||||||
|  |             # Password is good, log in user | ||||||
|  |             login_user(user, remember=True) | ||||||
|  |             return user | ||||||
|  |         else: | ||||||
|  |             # Password check failed | ||||||
|  |             return False | ||||||
|  | 
 | ||||||
|  |     @staticmethod | ||||||
|  |     def hash_password(password): | ||||||
|  |         return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt(12)) | ||||||
|  | 
 | ||||||
|  |     @staticmethod | ||||||
|  |     def check_password(password, hashed): | ||||||
|  |         return bcrypt.hashpw(password.encode('utf-8'), hashed.encode('utf-8')) == hashed | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def logout(cls): | ||||||
|  |         logout_user() | ||||||
|  | 
 | ||||||
|  |     @staticmethod | ||||||
|  |     def login_form(): | ||||||
|  |         form = LoginForm() | ||||||
|  |         return render_template('auth/local/login.html', form=form) | ||||||
|  | 
 | ||||||
							
								
								
									
										51
									
								
								realms/modules/auth/local/views.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								realms/modules/auth/local/views.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,51 @@ | ||||||
|  | from flask import current_app, render_template, request, redirect, Blueprint, flash, url_for | ||||||
|  | from realms.modules.auth.local.models import User | ||||||
|  | from realms.modules.auth.local.forms import LoginForm, RegistrationForm | ||||||
|  | 
 | ||||||
|  | blueprint = Blueprint('auth.local', __name__) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @blueprint.route("/login/local", methods=['POST']) | ||||||
|  | def login(): | ||||||
|  |     form = LoginForm() | ||||||
|  | 
 | ||||||
|  |     if not form.validate(): | ||||||
|  |         flash('Form invalid', 'warning') | ||||||
|  |         return redirect(url_for('auth.login')) | ||||||
|  | 
 | ||||||
|  |     if User.auth(request.form['email'], request.form['password']): | ||||||
|  |         return redirect(request.args.get("next") or url_for(current_app.config['ROOT_ENDPOINT'])) | ||||||
|  |     else: | ||||||
|  |         flash('Email or Password Incorrect', 'warning') | ||||||
|  |         return redirect(url_for('auth.login')) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @blueprint.route("/register", methods=['GET', 'POST']) | ||||||
|  | def register(): | ||||||
|  | 
 | ||||||
|  |     if not current_app.config['REGISTRATION_ENABLED']: | ||||||
|  |         flash("Registration is disabled") | ||||||
|  |         return redirect(url_for(current_app.config['ROOT_ENDPOINT'])) | ||||||
|  | 
 | ||||||
|  |     form = RegistrationForm() | ||||||
|  | 
 | ||||||
|  |     if request.method == "POST": | ||||||
|  | 
 | ||||||
|  |         if not form.validate(): | ||||||
|  |             flash('Form invalid', 'warning') | ||||||
|  |             return redirect(url_for('auth.local.register')) | ||||||
|  | 
 | ||||||
|  |         if User.get_by_username(request.form['username']): | ||||||
|  |             flash('Username is taken', 'warning') | ||||||
|  |             return redirect(url_for('auth.local.register')) | ||||||
|  | 
 | ||||||
|  |         if User.get_by_email(request.form['email']): | ||||||
|  |             flash('Email is taken', 'warning') | ||||||
|  |             return redirect(url_for('auth.local.register')) | ||||||
|  | 
 | ||||||
|  |         User.create(request.form['username'], request.form['email'], request.form['password']) | ||||||
|  |         User.auth(request.form['email'], request.form['password']) | ||||||
|  | 
 | ||||||
|  |         return redirect(request.args.get("next") or url_for(current_app.config['ROOT_ENDPOINT'])) | ||||||
|  | 
 | ||||||
|  |     return render_template("auth/register.html", form=form) | ||||||
|  | @ -1,39 +1,41 @@ | ||||||
| from flask import current_app | from flask import current_app | ||||||
| from flask.ext.login import UserMixin, logout_user, login_user, AnonymousUserMixin | from flask.ext.login import UserMixin, logout_user, login_user, AnonymousUserMixin | ||||||
| from realms import login_manager, db | from realms import login_manager | ||||||
| from realms.lib.model import Model |  | ||||||
| from realms.lib.util import gravatar_url | from realms.lib.util import gravatar_url | ||||||
| from itsdangerous import URLSafeSerializer, BadSignature | from itsdangerous import URLSafeSerializer, BadSignature | ||||||
| from hashlib import sha256 | from hashlib import sha256 | ||||||
| import bcrypt | import bcrypt | ||||||
|  | import importlib | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @login_manager.user_loader | @login_manager.user_loader | ||||||
| def load_user(user_id): | def load_user(auth_id): | ||||||
|     return User.get_by_id(user_id) |     return Auth.load_user(auth_id) | ||||||
|  | 
 | ||||||
|  | auth_users = {} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @login_manager.token_loader | class Auth(object): | ||||||
| def load_token(token): |  | ||||||
|     # Load unsafe because payload is needed for sig |  | ||||||
|     sig_okay, payload = URLSafeSerializer(current_app.config['SECRET_KEY']).loads_unsafe(token) |  | ||||||
| 
 | 
 | ||||||
|     if not payload: |     @staticmethod | ||||||
|         return None |     def get_auth_user(auth_type): | ||||||
|  |         print auth_type | ||||||
|  |         mod = importlib.import_module('realms.modules.auth.%s.models' % auth_type) | ||||||
|  |         return mod.User | ||||||
| 
 | 
 | ||||||
|     # User key *could* be stored in payload to avoid user lookup in db |     @staticmethod | ||||||
|     user = User.get_by_id(payload.get('id')) |     def load_user(auth_id): | ||||||
|  |         print auth_id | ||||||
|  |         auth_type, user_id = auth_id.split("/") | ||||||
|  |         return Auth.get_auth_user(auth_type).load_user(user_id) | ||||||
| 
 | 
 | ||||||
|     if not user: |     @staticmethod | ||||||
|         return None |     def login_forms(): | ||||||
| 
 |         forms = [] | ||||||
|     try: |         # TODO be dynamic | ||||||
|         if User.signer(sha256(user.password).hexdigest()).loads(token): |         for t in ['local']: | ||||||
|             return user |             forms.append(Auth.get_auth_user(t).login_form()) | ||||||
|         else: |         return forms | ||||||
|             return None |  | ||||||
|     except BadSignature: |  | ||||||
|         return None |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class AnonUser(AnonymousUserMixin): | class AnonUser(AnonymousUserMixin): | ||||||
|  | @ -42,40 +44,42 @@ class AnonUser(AnonymousUserMixin): | ||||||
|     admin = False |     admin = False | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class User(Model, UserMixin): | class BaseUser(UserMixin): | ||||||
|     __tablename__ = 'users' |     id = None | ||||||
|     id = db.Column(db.Integer, primary_key=True) |     email = None | ||||||
|     username = db.Column(db.String(128), unique=True) |     username = None | ||||||
|     email = db.Column(db.String(128), unique=True) |     type = 'base' | ||||||
|     password = db.Column(db.String(60)) |  | ||||||
|     admin = False |  | ||||||
| 
 | 
 | ||||||
|     hidden_fields = ['password'] |     def get_id(self): | ||||||
|     readonly_fields = ['email', 'password'] |         return unicode("%s/%s" % (self.type, self.id)) | ||||||
| 
 | 
 | ||||||
|     def get_auth_token(self): |     def get_auth_token(self): | ||||||
|         key = sha256(self.password).hexdigest() |         key = sha256(self.auth_token_id).hexdigest() | ||||||
|         return User.signer(key).dumps(dict(id=self.id)) |         return BaseUser.signer(key).dumps(dict(id=self.id)) | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def auth_token_id(self): | ||||||
|  |         raise NotImplementedError | ||||||
| 
 | 
 | ||||||
|     @property |     @property | ||||||
|     def avatar(self): |     def avatar(self): | ||||||
|         return gravatar_url(self.email) |         return gravatar_url(self.email) | ||||||
| 
 | 
 | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def create(username, email, password): |     def load_user(*args, **kwargs): | ||||||
|         u = User() |         raise NotImplementedError | ||||||
|         u.username = username | 
 | ||||||
|         u.email = email |     @staticmethod | ||||||
|         u.password = User.hash_password(password) |     def create(*args, **kwargs): | ||||||
|         u.save() |         pass | ||||||
| 
 | 
 | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def get_by_username(username): |     def get_by_username(username): | ||||||
|         return User.query().filter_by(username=username).first() |         pass | ||||||
| 
 | 
 | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def get_by_email(email): |     def get_by_email(email): | ||||||
|         return User.query().filter_by(email=email).first() |         pass | ||||||
| 
 | 
 | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def signer(salt): |     def signer(salt): | ||||||
|  | @ -83,19 +87,7 @@ class User(Model, UserMixin): | ||||||
| 
 | 
 | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def auth(email, password): |     def auth(email, password): | ||||||
|         user = User.get_by_email(email) |         raise NotImplementedError() | ||||||
| 
 |  | ||||||
|         if not user: |  | ||||||
|             # User doesn't exist |  | ||||||
|             return False |  | ||||||
| 
 |  | ||||||
|         if User.check_password(password, user.password): |  | ||||||
|             # Password is good, log in user |  | ||||||
|             login_user(user, remember=True) |  | ||||||
|             return user |  | ||||||
|         else: |  | ||||||
|             # Password check failed |  | ||||||
|             return False |  | ||||||
| 
 | 
 | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def hash_password(password): |     def hash_password(password): | ||||||
|  | @ -109,4 +101,8 @@ class User(Model, UserMixin): | ||||||
|     def logout(cls): |     def logout(cls): | ||||||
|         logout_user() |         logout_user() | ||||||
| 
 | 
 | ||||||
|  |     @staticmethod | ||||||
|  |     def login_form(): | ||||||
|  |         pass | ||||||
|  | 
 | ||||||
| login_manager.anonymous_user = AnonUser | login_manager.anonymous_user = AnonUser | ||||||
|  |  | ||||||
							
								
								
									
										0
									
								
								realms/modules/auth/oauth/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								realms/modules/auth/oauth/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										36
									
								
								realms/modules/auth/oauth/models.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								realms/modules/auth/oauth/models.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | ||||||
|  | from flask import render_template | ||||||
|  | from flask_oauthlib.client import OAuth | ||||||
|  | from realms import config | ||||||
|  | from ..models import BaseUser | ||||||
|  | 
 | ||||||
|  | oauth = OAuth() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class OAuthUser(BaseUser): | ||||||
|  |     # OAuth remote app | ||||||
|  |     app = None | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class TwitterUser(OAuthUser): | ||||||
|  | 
 | ||||||
|  |     app = oauth.remote_app( | ||||||
|  |         'twitter', | ||||||
|  |         base_url='https://api.twitter.com/1/', | ||||||
|  |         request_token_url='https://api.twitter.com/oauth/request_token', | ||||||
|  |         access_token_url='https://api.twitter.com/oauth/access_token', | ||||||
|  |         authorize_url='https://api.twitter.com/oauth/authenticate', | ||||||
|  |         consumer_key=config.TWITTER_KEY, | ||||||
|  |         consumer_secret=config.TWITTER_SECRET) | ||||||
|  | 
 | ||||||
|  |     def __init__(self, id_, username, email=None): | ||||||
|  |         self.id = id_ | ||||||
|  |         self.username = username | ||||||
|  |         self.email = email | ||||||
|  | 
 | ||||||
|  |     @staticmethod | ||||||
|  |     def load_user(*args, **kwargs): | ||||||
|  |         return TwitterUser(args[0]) | ||||||
|  | 
 | ||||||
|  |     @staticmethod | ||||||
|  |     def login_form(): | ||||||
|  |         return render_template('auth/oauth/twitter.html') | ||||||
							
								
								
									
										30
									
								
								realms/modules/auth/oauth/views.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								realms/modules/auth/oauth/views.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | ||||||
|  | from flask import Blueprint, url_for, request, flash, redirect | ||||||
|  | from .models import TwitterUser | ||||||
|  | 
 | ||||||
|  | blueprint = Blueprint('auth.oauth', __name__) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def oauth_failed(next_url): | ||||||
|  |     flash(u'You denied the request to sign in.') | ||||||
|  |     return redirect(next_url) | ||||||
|  | 
 | ||||||
|  | @blueprint.route("/login/twitter") | ||||||
|  | def login_twitter(): | ||||||
|  |     return TwitterUser.app.authorize(callback=url_for('twitter_callback', | ||||||
|  |                                                       next=request.args.get('next') or request.referrer or None)) | ||||||
|  | 
 | ||||||
|  | @blueprint.route('/login/twitter/callback') | ||||||
|  | def twitter_callback(): | ||||||
|  |     next_url = request.args.get('next') or url_for('index') | ||||||
|  |     resp = TwitterUser.app.authorized_response() | ||||||
|  |     if resp is None: | ||||||
|  |         return oauth_failed(next_url) | ||||||
|  | 
 | ||||||
|  |     session['twitter_token'] = ( | ||||||
|  |         resp['oauth_token'], | ||||||
|  |         resp['oauth_token_secret'] | ||||||
|  |     ) | ||||||
|  |     session['twitter_user'] = resp['screen_name'] | ||||||
|  | 
 | ||||||
|  |     flash('You were signed in as %s' % resp['screen_name']) | ||||||
|  |     return redirect(next_url) | ||||||
|  | @ -1,72 +1,22 @@ | ||||||
| from flask import current_app, render_template, request, redirect, Blueprint, flash, url_for | from flask import current_app, render_template, request, redirect, Blueprint, flash, url_for | ||||||
| from realms.modules.auth.models import User | from flask.ext.login import logout_user | ||||||
| from realms.modules.auth.forms import LoginForm, RegistrationForm | from realms.modules.auth.models import Auth | ||||||
| 
 | 
 | ||||||
| blueprint = Blueprint('auth', __name__) | blueprint = Blueprint('auth', __name__) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @blueprint.route("/logout") |  | ||||||
| def logout_page(): |  | ||||||
|     User.logout() |  | ||||||
|     flash("You are now logged out") |  | ||||||
|     return redirect(url_for(current_app.config['ROOT_ENDPOINT'])) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @blueprint.route("/login", methods=['GET', 'POST']) | @blueprint.route("/login", methods=['GET', 'POST']) | ||||||
| def login(): | def login(): | ||||||
|     form = LoginForm() |     return render_template("auth/login.html", forms=Auth.login_forms()) | ||||||
| 
 |  | ||||||
|     if request.method == "POST": |  | ||||||
|         if not form.validate(): |  | ||||||
|             flash('Form invalid', 'warning') |  | ||||||
|             return redirect(url_for('auth.login')) |  | ||||||
| 
 |  | ||||||
|         if User.auth(request.form['email'], request.form['password']): |  | ||||||
|             return redirect(request.args.get("next") or url_for(current_app.config['ROOT_ENDPOINT'])) |  | ||||||
|         else: |  | ||||||
|             flash('Email or Password Incorrect', 'warning') |  | ||||||
|             return redirect(url_for('auth.login')) |  | ||||||
| 
 |  | ||||||
|     return render_template("auth/login.html", form=form) |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @blueprint.route("/register", methods=['GET', 'POST']) | @blueprint.route("/logout") | ||||||
| def register(): | def logout(): | ||||||
| 
 |     logout_user() | ||||||
|     if not current_app.config['REGISTRATION_ENABLED']: |     flash("You are now logged out") | ||||||
|         flash("Registration is disabled") |  | ||||||
|     return redirect(url_for(current_app.config['ROOT_ENDPOINT'])) |     return redirect(url_for(current_app.config['ROOT_ENDPOINT'])) | ||||||
| 
 | 
 | ||||||
|     form = RegistrationForm() |  | ||||||
| 
 |  | ||||||
|     if request.method == "POST": |  | ||||||
| 
 |  | ||||||
|         if not form.validate(): |  | ||||||
|             flash('Form invalid', 'warning') |  | ||||||
|             return redirect(url_for('auth.register')) |  | ||||||
| 
 |  | ||||||
|         if User.get_by_username(request.form['username']): |  | ||||||
|             flash('Username is taken', 'warning') |  | ||||||
|             return redirect(url_for('auth.register')) |  | ||||||
| 
 |  | ||||||
|         if User.get_by_email(request.form['email']): |  | ||||||
|             flash('Email is taken', 'warning') |  | ||||||
|             return redirect(url_for('auth.register')) |  | ||||||
| 
 |  | ||||||
|         User.create(request.form['username'], request.form['email'], request.form['password']) |  | ||||||
|         User.auth(request.form['email'], request.form['password']) |  | ||||||
| 
 |  | ||||||
|         return redirect(request.args.get("next") or url_for(current_app.config['ROOT_ENDPOINT'])) |  | ||||||
| 
 |  | ||||||
|     return render_template("auth/register.html", form=form) |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| @blueprint.route("/settings", methods=['GET', 'POST']) | @blueprint.route("/settings", methods=['GET', 'POST']) | ||||||
| def settings(): | def settings(): | ||||||
|     return render_template("auth/settings.html") |     return render_template("auth/settings.html") | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @blueprint.route("/logout") |  | ||||||
| def logout(): |  | ||||||
|     User.logout() |  | ||||||
|     return redirect(url_for(current_app.config['ROOT_ENDPOINT'])) |  | ||||||
|  |  | ||||||
							
								
								
									
										5
									
								
								realms/templates/auth/local/login.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								realms/templates/auth/local/login.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | ||||||
|  | {% from 'macros.html' import render_form, render_field %} | ||||||
|  | {% call render_form(form, action_url=url_for('auth.local.login'), action_text='Login', btn_class='btn btn-primary') %} | ||||||
|  | {{ render_field(form.email, placeholder='Email', type='email', required=1) }} | ||||||
|  | {{ render_field(form.password, placeholder='Password', type='password', required=1) }} | ||||||
|  | {% endcall %} | ||||||
|  | @ -1,8 +1,6 @@ | ||||||
| {% extends 'layout.html' %} | {% extends 'layout.html' %} | ||||||
| {% from 'macros.html' import render_form, render_field %} |  | ||||||
| {% block body %} | {% block body %} | ||||||
|   {% call render_form(form, action_url=url_for('auth.login'), action_text='Login', btn_class='btn btn-primary') %} |   {% for form in forms %} | ||||||
|     {{ render_field(form.email, placeholder='Email', type='email', required=1) }} |     {{ form|safe }} | ||||||
|     {{ render_field(form.password, placeholder='Password', type='password', required=1) }} |   {% endfor %} | ||||||
|   {% endcall %} |  | ||||||
| {% endblock %} | {% endblock %} | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| {% extends 'layout.html' %} | {% extends 'layout.html' %} | ||||||
| {% from 'macros.html' import render_form, render_field %} | {% from 'macros.html' import render_form, render_field %} | ||||||
| {% block body %} | {% block body %} | ||||||
|   {% call render_form(form, action_url=url_for('auth.register'), action_text='Register', btn_class='btn btn-primary') %} |   {% call render_form(form, action_url=url_for('auth.local.register'), action_text='Register', btn_class='btn btn-primary') %} | ||||||
|     {{ render_field(form.username, placeholder='Username', type='username', **{"required": 1, "data-parsley-type": "alphanum"}) }} |     {{ render_field(form.username, placeholder='Username', type='username', **{"required": 1, "data-parsley-type": "alphanum"}) }} | ||||||
|     {{ render_field(form.email, placeholder='Email', type='email', required=1) }} |     {{ render_field(form.email, placeholder='Email', type='email', required=1) }} | ||||||
|     {{ render_field(form.password, placeholder='Password', type='password', **{"required": 1, "data-parsley-minlength": "6"}) }} |     {{ render_field(form.password, placeholder='Password', type='password', **{"required": 1, "data-parsley-minlength": "6"}) }} | ||||||
|  |  | ||||||
|  | @ -74,7 +74,7 @@ | ||||||
|             {% else %} |             {% else %} | ||||||
|               <li><a href="{{ url_for('auth.login') }}"><i class="fa fa-user"></i>  Login</a></li> |               <li><a href="{{ url_for('auth.login') }}"><i class="fa fa-user"></i>  Login</a></li> | ||||||
|               {% if config.REGISTRATION_ENABLED %} |               {% if config.REGISTRATION_ENABLED %} | ||||||
|                 <li><a href="{{ url_for('auth.register') }}"><i class="fa fa-users"></i>  Register</a></li> |                 <li><a href="{{ url_for('auth.local.register') }}"><i class="fa fa-users"></i>  Register</a></li> | ||||||
|               {% endif %} |               {% endif %} | ||||||
|             {% endif %} |             {% endif %} | ||||||
|           </ul> |           </ul> | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue