github oauth login

This commit is contained in:
CMGS 2016-08-05 16:20:41 +08:00 committed by timfeirg
parent 68dc4f4148
commit 186aedcfc7
4 changed files with 126 additions and 44 deletions

View File

@ -1,7 +1,7 @@
from werkzeug.contrib.fixers import ProxyFix from werkzeug.contrib.fixers import ProxyFix
from flask import Flask from flask import Flask, request, session, redirect, url_for
from flask.ext.login import LoginManager from flask_login import LoginManager
from flask.ext.sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__) app = Flask(__name__)
app.config.from_object('config') app.config.from_object('config')
@ -11,4 +11,42 @@ login_manager = LoginManager()
login_manager.init_app(app) login_manager.init_app(app)
db = SQLAlchemy(app) db = SQLAlchemy(app)
def enable_github_oauth(GITHUB_ENABLE):
if not GITHUB_ENABLE:
return None, None
from flask_oauthlib.client import OAuth
oauth = OAuth(app)
github = oauth.remote_app(
'github',
consumer_key=app.config['GITHUB_OAUTH_KEY'],
consumer_secret=app.config['GITHUB_OAUTH_SECRET'],
request_token_params={'scope': app.config['GITHUB_OAUTH_SCOPE']},
base_url=app.config['GITHUB_OAUTH_URL'],
request_token_url=None,
access_token_method='POST',
access_token_url=app.config['GITHUB_OAUTH_TOKEN'],
authorize_url=app.config['GITHUB_OAUTH_AUTHORIZE']
)
@app.route('/user/authorized')
def authorized():
session['github_oauthredir'] = url_for('.authorized', _external=True)
resp = github.authorized_response()
if resp is None:
return 'Access denied: reason=%s error=%s' % (
request.args['error'],
request.args['error_description']
)
session['github_token'] = (resp['access_token'], '')
return redirect(url_for('.login'))
@github.tokengetter
def get_github_oauth_token():
return session.get('github_token')
return oauth, github
oauth, github = enable_github_oauth(app.config.get('GITHUB_OAUTH_ENABLE'))
from app import views, models from app import views, models

View File

@ -58,7 +58,6 @@
<div class="form-group"> <div class="form-group">
<input type="otptoken" class="form-control" placeholder="OTP Token" name="otptoken"> <input type="otptoken" class="form-control" placeholder="OTP Token" name="otptoken">
</div> </div>
{% if ldap_enabled and basic_enabled %} {% if ldap_enabled and basic_enabled %}
<div class="form-group"> <div class="form-group">
<select class="form-control" name="auth_method"> <select class="form-control" name="auth_method">
@ -99,6 +98,10 @@
<!-- /.col --> <!-- /.col -->
</div> </div>
</form> </form>
{% if github_enabled %}
<a href="{{ url_for('github_login') }}">Github oauth login</a>
{% endif %}
<br>
{% if signup_enabled %} {% if signup_enabled %}
<a href="{{ url_for('register') }}" class="text-center">Create an account </a> <a href="{{ url_for('register') }}" class="text-center">Create an account </a>
{% endif %} {% endif %}

View File

@ -4,14 +4,16 @@ import jinja2
import traceback import traceback
import pyqrcode import pyqrcode
import base64 import base64
import random
import string
from functools import wraps from functools import wraps
from flask_login import login_user, logout_user, current_user, login_required from flask_login import login_user, logout_user, current_user, login_required
from flask import Flask, g, request, make_response, jsonify, render_template, session, redirect, url_for, send_from_directory from flask import Flask, g, request, make_response, jsonify, render_template, session, redirect, url_for, send_from_directory, abort
from werkzeug import secure_filename from werkzeug import secure_filename
from lib import utils from lib import utils
from app import app, login_manager from app import app, login_manager, github
from .models import User, Role, Domain, DomainUser, Record, Server, History, Anonymous, Setting, DomainSetting from .models import User, Role, Domain, DomainUser, Record, Server, History, Anonymous, Setting, DomainSetting
from io import BytesIO from io import BytesIO
@ -32,6 +34,9 @@ if StrictVersion(PDNS_VERSION) >= StrictVersion('4.0.0'):
else: else:
NEW_SCHEMA = False NEW_SCHEMA = False
def random_password(n):
return ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(n))
@app.context_processor @app.context_processor
def inject_fullscreen_layout_setting(): def inject_fullscreen_layout_setting():
fullscreen_layout_setting = Setting.query.filter(Setting.name == 'fullscreen_layout').first() fullscreen_layout_setting = Setting.query.filter(Setting.name == 'fullscreen_layout').first()
@ -153,6 +158,12 @@ def register():
else: else:
return render_template('errors/404.html'), 404 return render_template('errors/404.html'), 404
@app.route('/github/login')
def github_login():
if not app.config.get('GITHUB_OAUTH_ENABLE'):
return abort(400)
return github.authorize(callback=url_for('authorized', _external=True))
@app.route('/login', methods=['GET', 'POST']) @app.route('/login', methods=['GET', 'POST'])
@login_manager.unauthorized_handler @login_manager.unauthorized_handler
def login(): def login():
@ -161,12 +172,31 @@ def login():
LOGIN_TITLE = app.config['LOGIN_TITLE'] if 'LOGIN_TITLE' in app.config.keys() else '' LOGIN_TITLE = app.config['LOGIN_TITLE'] if 'LOGIN_TITLE' in app.config.keys() else ''
BASIC_ENABLED = app.config['BASIC_ENABLED'] BASIC_ENABLED = app.config['BASIC_ENABLED']
SIGNUP_ENABLED = app.config['SIGNUP_ENABLED'] SIGNUP_ENABLED = app.config['SIGNUP_ENABLED']
GITHUB_ENABLE = app.config.get('GITHUB_OAUTH_ENABLE')
if g.user is not None and current_user.is_authenticated: if g.user is not None and current_user.is_authenticated:
return redirect(url_for('dashboard')) return redirect(url_for('dashboard'))
if 'github_token' in session:
me = github.get('user')
user_info = me.data
user = User.query.filter_by(username=user_info['name']).first()
if not user:
# create user
user = User(username=user_info['name'],
plain_text_password=random_password(7),
email=user_info['email'])
user.create_local_user()
session['user_id'] = user.id
login_user(user, remember = False)
return redirect(url_for('index'))
if request.method == 'GET': if request.method == 'GET':
return render_template('login.html', ldap_enabled=LDAP_ENABLED, login_title=LOGIN_TITLE, basic_enabled=BASIC_ENABLED, signup_enabled=SIGNUP_ENABLED) return render_template('login.html',
github_enabled=GITHUB_ENABLE,
ldap_enabled=LDAP_ENABLED, login_title=LOGIN_TITLE,
basic_enabled=BASIC_ENABLED, signup_enabled=SIGNUP_ENABLED)
# process login # process login
username = request.form['username'] username = request.form['username']
@ -229,6 +259,8 @@ def login():
@app.route('/logout') @app.route('/logout')
def logout(): def logout():
session.pop('user_id')
session.pop('github_token')
logout_user() logout_user()
return redirect(url_for('login')) return redirect(url_for('login'))

View File

@ -33,6 +33,15 @@ LDAP_SEARCH_BASE = 'ou=System Admins,ou=People,dc=duykhanh,dc=me'
LDAP_USERNAMEFIELD = 'uid' LDAP_USERNAMEFIELD = 'uid'
LDAP_FILTER = '(objectClass=inetorgperson)' LDAP_FILTER = '(objectClass=inetorgperson)'
# Github Oauth
GITHUB_OAUTH_ENABLE = False
GITHUB_OAUTH_KEY = 'G0j1Q15aRsn36B3aD6nwKLiYbeirrUPU8nDd1wOC'
GITHUB_OAUTH_SECRET = '0WYrKWePeBDkxlezzhFbDn1PBnCwEa0vCwVFvy6iLtgePlpT7WfUlAa9sZgm'
GITHUB_OAUTH_SCOPE = 'email'
GITHUB_OAUTH_URL = 'http://127.0.0.1:5000/api/v3/'
GITHUB_OAUTH_TOKEN = 'http://127.0.0.1:5000/oauth/token'
GITHUB_OAUTH_AUTHORIZE = 'http://127.0.0.1:5000/oauth/authorize'
#Default Auth #Default Auth
BASIC_ENABLED = True BASIC_ENABLED = True
SIGNUP_ENABLED = True SIGNUP_ENABLED = True