diff --git a/app/__init__.py b/app/__init__.py index bcb3525..96e36d8 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -11,6 +11,7 @@ login_manager = LoginManager() login_manager.init_app(app) db = SQLAlchemy(app) + def enable_github_oauth(GITHUB_ENABLE): if not GITHUB_ENABLE: return None, None @@ -46,7 +47,47 @@ def enable_github_oauth(GITHUB_ENABLE): 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 diff --git a/app/models.py b/app/models.py index 80b8c2b..a73e784 100644 --- a/app/models.py +++ b/app/models.py @@ -258,12 +258,12 @@ class User(db.Model): # check if username existed user = User.query.filter(User.username == self.username).first() if user: - return 'Username already existed' + return {'status': False, 'msg': 'Username is already in use'} # check if email existed user = User.query.filter(User.email == self.email).first() if user: - return 'Email already existed' + return {'status': False, 'msg': 'Email address is already in use'} # first register user will be in Administrator role self.role_id = Role.query.filter_by(name='User').first().id @@ -274,7 +274,7 @@ class User(db.Model): db.session.add(self) db.session.commit() - return True + return {'status': True, 'msg': 'Created user successfully'} def update_profile(self, enable_otp=None): """ diff --git a/app/templates/admin_createuser.html b/app/templates/admin_createuser.html index b674297..fe7d4ea 100644 --- a/app/templates/admin_createuser.html +++ b/app/templates/admin_createuser.html @@ -28,6 +28,14 @@
+ {% if error %} +
+ +

Error!

+ {{ error }} +
+ {{ error }} + {% endif %}
-
+
- {% if duplicate_email %} - This e-mail address is already in use. - {% endif %}
-
+
- {% if duplicate_username %} - This username is already in use. - {% endif %}
diff --git a/app/templates/login.html b/app/templates/login.html index 9527f22..ca32d04 100644 --- a/app/templates/login.html +++ b/app/templates/login.html @@ -98,6 +98,9 @@
+ {% if google_enabled %} + Google oauth login + {% endif %} {% if github_enabled %} Github oauth login {% endif %} diff --git a/app/views.py b/app/views.py index 37cbfba..a5596ed 100644 --- a/app/views.py +++ b/app/views.py @@ -17,7 +17,7 @@ from werkzeug import secure_filename from werkzeug.security import gen_salt from .models import User, Domain, Record, Server, History, Anonymous, Setting, DomainSetting -from app import app, login_manager, github +from app import app, login_manager, github, google from app.lib import utils @@ -172,6 +172,13 @@ def register(): return render_template('errors/404.html'), 404 +@app.route('/google/login') +def google_login(): + if not app.config.get('GOOGLE_OAUTH_ENABLE'): + return abort(400) + return google.authorize(callback=url_for('authorized', _external=True)) + + @app.route('/github/login') def github_login(): if not app.config.get('GITHUB_OAUTH_ENABLE'): @@ -188,10 +195,34 @@ def login(): BASIC_ENABLED = app.config['BASIC_ENABLED'] SIGNUP_ENABLED = app.config['SIGNUP_ENABLED'] GITHUB_ENABLE = app.config.get('GITHUB_OAUTH_ENABLE') + GOOGLE_ENABLE = app.config.get('GOOGLE_OAUTH_ENABLE') if g.user is not None and current_user.is_authenticated: return redirect(url_for('dashboard')) + if 'google_token' in session: + user_data = google.get('userinfo').data + first_name = user_data['given_name'] + surname = user_data['family_name'] + email = user_data['email'] + user = User.query.filter_by(username=email).first() + if not user: + # create user + user = User(username=email, + firstname=first_name, + lastname=surname, + plain_text_password=gen_salt(7), + email=email) + + result = user.create_local_user() + if not result['status']: + session.pop('google_token', None) + return redirect(url_for('login')) + + session['user_id'] = user.id + login_user(user, remember = False) + return redirect(url_for('index')) + if 'github_token' in session: me = github.get('user') user_info = me.data @@ -201,7 +232,11 @@ def login(): user = User(username=user_info['name'], plain_text_password=gen_salt(7), email=user_info['email']) - user.create_local_user() + + result = user.create_local_user() + if not result['status']: + session.pop('github_token', None) + return redirect(url_for('login')) session['user_id'] = user.id login_user(user, remember = False) @@ -210,6 +245,7 @@ def login(): if request.method == 'GET': return render_template('login.html', github_enabled=GITHUB_ENABLE, + google_enabled=GOOGLE_ENABLE, ldap_enabled=LDAP_ENABLED, login_title=LOGIN_TITLE, basic_enabled=BASIC_ENABLED, signup_enabled=SIGNUP_ENABLED) @@ -263,10 +299,10 @@ def login(): try: result = user.create_local_user() - if result == True: + if result['status'] == True: return render_template('login.html', username=username, password=password, ldap_enabled=LDAP_ENABLED, login_title=LOGIN_TITLE, basic_enabled=BASIC_ENABLED, signup_enabled=SIGNUP_ENABLED) else: - return render_template('register.html', error=result) + return render_template('register.html', error=result['msg']) except Exception as e: return render_template('register.html', error=e) @@ -275,6 +311,7 @@ def login(): def logout(): session.pop('user_id', None) session.pop('github_token', None) + session.pop('google_token', None) logout_user() return redirect(url_for('login')) @@ -628,14 +665,10 @@ def admin_createuser(): return render_template('admin_createuser.html', user=user, blank_password=True) result = user.create_local_user(); + if result['status']: + return redirect(url_for('admin_manageuser')) - if result == 'Email already existed': - return render_template('admin_createuser.html', user=user, duplicate_email=True) - - if result == 'Username already existed': - return render_template('admin_createuser.html', user=user, duplicate_username=True) - - return redirect(url_for('admin_manageuser')) + return render_template('admin_createuser.html', user=user, error=result['msg']) @app.route('/admin/manageuser', methods=['GET', 'POST']) diff --git a/config_template.py b/config_template.py index 94dc0fe..e4e6518 100644 --- a/config_template.py +++ b/config_template.py @@ -65,6 +65,18 @@ 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' +# Google OAuth +GOOGLE_OAUTH_ENABLE = 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' +GOOGLE_BASE_URL='https://www.googleapis.com/oauth2/v1/' + #Default Auth BASIC_ENABLED = True SIGNUP_ENABLED = True diff --git a/configs/development.py b/configs/development.py index 61b8b3c..2aa5c72 100644 --- a/configs/development.py +++ b/configs/development.py @@ -47,6 +47,19 @@ SIGNUP_ENABLED = True # GITHUB_OAUTH_TOKEN = 'http://127.0.0.1:5000/oauth/token' # GITHUB_OAUTH_AUTHORIZE = 'http://127.0.0.1:5000/oauth/authorize' +# GOOGLE AUTHENTICATION +GOOGLE_OAUTH_ENABLE = True +GOOGLE_OAUTH_CLIENT_ID = '829241394512-2dc9shen6tv8ouhot68lg9g6gc029cj3.apps.googleusercontent.com' +GOOGLE_OAUTH_CLIENT_SECRET = 'wsa9oYp8kyCoIum44Pj1oICc' +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' +GOOGLE_BASE_URL='https://www.googleapis.com/oauth2/v1/' + + # POWERDNS CONFIG PDNS_STATS_URL = 'http://192.168.100.100:8081/' PDNS_API_KEY = 'changeme' diff --git a/run.py b/run.py index e159643..7fb4ae4 100755 --- a/run.py +++ b/run.py @@ -3,7 +3,7 @@ from app import app from config import PORT try: - from config import BIND_ADDRESS + from config import BIND_ADDRESS except: BIND_ADDRESS = '127.0.0.1'