mirror of
https://github.com/cwinfo/powerdns-admin.git
synced 2024-12-04 19:15:30 +00:00
Fix Github/Google oAuth
This commit is contained in:
parent
ada6f844ff
commit
babf62bae0
@ -3,7 +3,7 @@ from flask import Flask, request, session, redirect, url_for
|
||||
from flask_login import LoginManager
|
||||
from flask_sqlalchemy import SQLAlchemy as SA
|
||||
from flask_migrate import Migrate
|
||||
|
||||
from flask_oauthlib.client import OAuth
|
||||
|
||||
# subclass SQLAlchemy to enable pool_pre_ping
|
||||
class SQLAlchemy(SA):
|
||||
@ -26,89 +26,13 @@ logging = logger('powerdns-admin', app.config['LOG_LEVEL'], app.config['LOG_FILE
|
||||
|
||||
login_manager = LoginManager()
|
||||
login_manager.init_app(app)
|
||||
db = SQLAlchemy(app)
|
||||
migrate = Migrate(app, db) # used for flask-migrate
|
||||
|
||||
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'], # API 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'))
|
||||
|
||||
|
||||
def enable_google_oauth(GOOGLE_ENABLE):
|
||||
if not GOOGLE_ENABLE:
|
||||
return None
|
||||
from flask_oauthlib.client import OAuth
|
||||
oauth = OAuth(app)
|
||||
|
||||
google = oauth.remote_app(
|
||||
'google',
|
||||
consumer_key=app.config['GOOGLE_OAUTH_CLIENT_ID'],
|
||||
consumer_secret=app.config['GOOGLE_OAUTH_CLIENT_SECRET'],
|
||||
request_token_params=app.config['GOOGLE_TOKEN_PARAMS'],
|
||||
base_url=app.config['GOOGLE_BASE_URL'],
|
||||
request_token_url=None,
|
||||
access_token_method='POST',
|
||||
access_token_url=app.config['GOOGLE_TOKEN_URL'],
|
||||
authorize_url=app.config['GOOGLE_AUTHORIZE_URL'],
|
||||
)
|
||||
|
||||
@app.route('/user/authorized')
|
||||
def authorized():
|
||||
resp = google.authorized_response()
|
||||
if resp is None:
|
||||
return 'Access denied: reason=%s error=%s' % (
|
||||
request.args['error_reason'],
|
||||
request.args['error_description']
|
||||
)
|
||||
session['google_token'] = (resp['access_token'], '')
|
||||
return redirect(url_for('.login'))
|
||||
|
||||
@google.tokengetter
|
||||
def get_google_oauth_token():
|
||||
return session.get('google_token')
|
||||
|
||||
return google
|
||||
|
||||
|
||||
google = enable_google_oauth(app.config.get('GOOGLE_OAUTH_ENABLE'))
|
||||
|
||||
from app import views, models
|
||||
db = SQLAlchemy(app) # database
|
||||
migrate = Migrate(app, db) # flask-migrate
|
||||
oauth = OAuth(app) # oauth
|
||||
|
||||
if app.config.get('SAML_ENABLED') and app.config.get('SAML_ENCRYPT'):
|
||||
from app.lib import certutil
|
||||
if not certutil.check_certificate():
|
||||
certutil.create_self_signed_cert()
|
||||
|
||||
from app import models, views
|
||||
|
@ -1805,7 +1805,6 @@ class Setting(db.Model):
|
||||
'google_oauth_enabled': False,
|
||||
'google_oauth_client_id':'',
|
||||
'google_oauth_client_secret':'',
|
||||
'google_redirect_uri': '/user/authorized',
|
||||
'google_token_url': 'https://accounts.google.com/o/oauth2/token',
|
||||
'google_token_params': {'scope': 'email profile'},
|
||||
'google_authorize_url':'https://accounts.google.com/o/oauth2/auth',
|
||||
|
79
app/oauth.py
Normal file
79
app/oauth.py
Normal file
@ -0,0 +1,79 @@
|
||||
from ast import literal_eval
|
||||
from flask import request, session, redirect, url_for
|
||||
from flask_oauthlib.client import OAuth
|
||||
|
||||
from app import app, oauth
|
||||
from app.models import Setting
|
||||
|
||||
# TODO:
|
||||
# - Replace Flask-OAuthlib by authlib
|
||||
# - Fix flask-migrate issue with calling Setting() class during downgrade / upgrade
|
||||
# - Fix github/google enabling (Currently need to reload the flask app)
|
||||
|
||||
def github_oauth():
|
||||
if not Setting().get('github_oauth_enabled'):
|
||||
return None
|
||||
|
||||
github = oauth.remote_app(
|
||||
'github',
|
||||
consumer_key = Setting().get('github_oauth_key'),
|
||||
consumer_secret = Setting().get('github_oauth_secret'),
|
||||
request_token_params = {'scope': Setting().get('github_oauth_scope')},
|
||||
base_url = Setting().get('github_oauth_api_url'),
|
||||
request_token_url = None,
|
||||
access_token_method = 'POST',
|
||||
access_token_url = Setting().get('github_oauth_token_url'),
|
||||
authorize_url = Setting().get('github_oauth_authorize_url')
|
||||
)
|
||||
|
||||
@app.route('/github/authorized')
|
||||
def github_authorized():
|
||||
session['github_oauthredir'] = url_for('.github_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 github
|
||||
|
||||
|
||||
def google_oauth():
|
||||
if not Setting().get('google_oauth_enabled'):
|
||||
return None
|
||||
|
||||
google = oauth.remote_app(
|
||||
'google',
|
||||
consumer_key=Setting().get('google_oauth_client_id'),
|
||||
consumer_secret=Setting().get('google_oauth_client_secret'),
|
||||
request_token_params=literal_eval(Setting().get('google_token_params')),
|
||||
base_url=Setting().get('google_base_url'),
|
||||
request_token_url=None,
|
||||
access_token_method='POST',
|
||||
access_token_url=Setting().get('google_token_url'),
|
||||
authorize_url=Setting().get('google_authorize_url'),
|
||||
)
|
||||
|
||||
@app.route('/google/authorized')
|
||||
def google_authorized():
|
||||
resp = google.authorized_response()
|
||||
if resp is None:
|
||||
return 'Access denied: reason=%s error=%s' % (
|
||||
request.args['error_reason'],
|
||||
request.args['error_description']
|
||||
)
|
||||
session['google_token'] = (resp['access_token'], '')
|
||||
return redirect(url_for('.login'))
|
||||
|
||||
@google.tokengetter
|
||||
def get_google_oauth_token():
|
||||
return session.get('google_token')
|
||||
|
||||
return google
|
@ -159,10 +159,6 @@
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>ADVANCE</legend>
|
||||
<div class="form-group">
|
||||
<label for="google_redirect_uri">Redirect URI</label>
|
||||
<input type="text" class="form-control" name="google_redirect_uri" id="google_redirect_uri" placeholder="e.g. /user/authorized" value="{{ SETTING.get('google_redirect_uri') }}">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="google_token_url">Token URL</label>
|
||||
<input type="text" class="form-control" name="google_token_url" id="google_token_url" placeholder="e.g. https://accounts.google.com/o/oauth2/token" value="{{ SETTING.get('google_token_url') }}">
|
||||
|
41
app/views.py
41
app/views.py
@ -18,8 +18,9 @@ from werkzeug import secure_filename
|
||||
from werkzeug.security import gen_salt
|
||||
|
||||
from .models import User, Account, Domain, Record, Role, Server, History, Anonymous, Setting, DomainSetting, DomainTemplate, DomainTemplateRecord
|
||||
from app import app, login_manager, github, google
|
||||
from app import app, login_manager
|
||||
from app.lib import utils
|
||||
from app.oauth import github_oauth, google_oauth
|
||||
from app.decorators import admin_role_required, can_access_domain, can_configure_dnssec
|
||||
|
||||
if app.config['SAML_ENABLED']:
|
||||
@ -27,6 +28,8 @@ if app.config['SAML_ENABLED']:
|
||||
from onelogin.saml2.utils import OneLogin_Saml2_Utils
|
||||
|
||||
logging = logger.getLogger(__name__)
|
||||
google = google_oauth()
|
||||
github = github_oauth()
|
||||
|
||||
# FILTERS
|
||||
app.jinja_env.filters['display_record_name'] = utils.display_record_name
|
||||
@ -147,16 +150,19 @@ def register():
|
||||
|
||||
@app.route('/google/login')
|
||||
def google_login():
|
||||
if not app.config.get('GOOGLE_OAUTH_ENABLE'):
|
||||
if not Setting().get('google_oauth_enabled'):
|
||||
return abort(400)
|
||||
return google.authorize(callback=url_for('authorized', _external=True))
|
||||
else:
|
||||
return google.authorize(callback=url_for('google_authorized', _external=True))
|
||||
|
||||
|
||||
@app.route('/github/login')
|
||||
def github_login():
|
||||
if not app.config.get('GITHUB_OAUTH_ENABLE'):
|
||||
if not Setting().get('github_oauth_enabled'):
|
||||
return abort(400)
|
||||
return github.authorize(callback=url_for('authorized', _external=True))
|
||||
else:
|
||||
return github.authorize(callback=url_for('github_authorized', _external=True))
|
||||
|
||||
|
||||
@app.route('/saml/login')
|
||||
def saml_login():
|
||||
@ -167,6 +173,7 @@ def saml_login():
|
||||
redirect_url=OneLogin_Saml2_Utils.get_self_url(req) + url_for('saml_authorized')
|
||||
return redirect(auth.login(return_to=redirect_url))
|
||||
|
||||
|
||||
@app.route('/saml/metadata')
|
||||
def saml_metadata():
|
||||
if not app.config.get('SAML_ENABLED'):
|
||||
@ -184,6 +191,7 @@ def saml_metadata():
|
||||
resp = make_response(errors.join(', '), 500)
|
||||
return resp
|
||||
|
||||
|
||||
@app.route('/saml/authorized', methods=['GET', 'POST'])
|
||||
def saml_authorized():
|
||||
errors = []
|
||||
@ -268,6 +276,7 @@ def saml_authorized():
|
||||
else:
|
||||
return render_template('errors/SAML.html', errors=errors)
|
||||
|
||||
|
||||
@app.route('/login', methods=['GET', 'POST'])
|
||||
@login_manager.unauthorized_handler
|
||||
def login():
|
||||
@ -302,14 +311,19 @@ def login():
|
||||
return redirect(url_for('index'))
|
||||
|
||||
if 'github_token' in session:
|
||||
me = github.get('user')
|
||||
user_info = me.data
|
||||
user = User.query.filter_by(username=user_info['name']).first()
|
||||
me = github.get('user').data
|
||||
|
||||
github_username = me['login']
|
||||
github_name = me['name']
|
||||
github_email = me['email']
|
||||
|
||||
user = User.query.filter_by(username=github_username).first()
|
||||
if not user:
|
||||
# create user
|
||||
user = User(username=user_info['name'],
|
||||
user = User(username=github_username,
|
||||
plain_text_password=None,
|
||||
email=user_info['email'])
|
||||
firstname=github_name,
|
||||
lastname='',
|
||||
email=github_email)
|
||||
|
||||
result = user.create_local_user()
|
||||
if not result['status']:
|
||||
@ -387,6 +401,7 @@ def login():
|
||||
except Exception as e:
|
||||
return render_template('register.html', error=e)
|
||||
|
||||
|
||||
def clear_session():
|
||||
session.pop('user_id', None)
|
||||
session.pop('github_token', None)
|
||||
@ -394,6 +409,7 @@ def clear_session():
|
||||
session.clear()
|
||||
logout_user()
|
||||
|
||||
|
||||
@app.route('/logout')
|
||||
def logout():
|
||||
if app.config.get('SAML_ENABLED') and 'samlSessionIndex' in session and app.config.get('SAML_LOGOUT'):
|
||||
@ -409,6 +425,7 @@ def logout():
|
||||
clear_session()
|
||||
return redirect(url_for('login'))
|
||||
|
||||
|
||||
@app.route('/saml/sls')
|
||||
def saml_logout():
|
||||
req = utils.prepare_flask_request(request)
|
||||
@ -426,6 +443,7 @@ def saml_logout():
|
||||
else:
|
||||
return render_template('errors/SAML.html', errors=errors)
|
||||
|
||||
|
||||
@app.route('/dashboard', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def dashboard():
|
||||
@ -1386,7 +1404,6 @@ def admin_setting_authentication():
|
||||
Setting().set('google_oauth_enabled', True if request.form.get('google_oauth_enabled') else False)
|
||||
Setting().set('google_oauth_client_id', request.form.get('google_oauth_client_id'))
|
||||
Setting().set('google_oauth_client_secret', request.form.get('google_oauth_client_secret'))
|
||||
Setting().set('google_redirect_uri', request.form.get('google_redirect_uri'))
|
||||
Setting().set('google_token_url', request.form.get('google_token_url'))
|
||||
Setting().set('google_token_params', request.form.get('google_token_params'))
|
||||
Setting().set('google_authorize_url', request.form.get('google_authorize_url'))
|
||||
|
@ -59,11 +59,10 @@ def update_data():
|
||||
{'id': 32, 'name': 'google_oauth_enabled', 'value': 'False', 'view': 'authentication'},
|
||||
{'id': 33, 'name': 'google_oauth_client_id', 'value': '', 'view': 'authentication'},
|
||||
{'id': 34, 'name': 'google_oauth_client_secret', 'value': '', 'view': 'authentication'},
|
||||
{'id': 35, 'name': 'google_redirect_uri', 'value': '/user/authorized', 'view': 'authentication'},
|
||||
{'id': 36, 'name': 'google_token_url', 'value': 'https://accounts.google.com/o/oauth2/token', 'view': 'authentication'},
|
||||
{'id': 37, 'name': 'google_token_params', 'value': "{'scope': 'email profile'}", 'view': 'authentication'},
|
||||
{'id': 38, 'name': 'google_authorize_url', 'value': 'https://accounts.google.com/o/oauth2/auth', 'view': 'authentication'},
|
||||
{'id': 39, 'name': 'google_base_url', 'value': 'https://www.googleapis.com/oauth2/v1/', 'view': 'authentication'},
|
||||
{'id': 35, 'name': 'google_token_url', 'value': 'https://accounts.google.com/o/oauth2/token', 'view': 'authentication'},
|
||||
{'id': 36, 'name': 'google_token_params', 'value': "{'scope': 'email profile'}", 'view': 'authentication'},
|
||||
{'id': 37, 'name': 'google_authorize_url', 'value': 'https://accounts.google.com/o/oauth2/auth', 'view': 'authentication'},
|
||||
{'id': 38, 'name': 'google_base_url', 'value': 'https://www.googleapis.com/oauth2/v1/', 'view': 'authentication'},
|
||||
]
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user