From 49638b081b490f61d5851f45eeb24d7f537b289b Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Wed, 15 Feb 2017 15:26:15 -0500 Subject: [PATCH] Pull out google login validation into validator class --- util/config/validator.py | 27 ++------------ .../test/test_validate_google_login.py | 37 +++++++++++++++++++ .../validators/validate_google_login.py | 25 +++++++++++++ 3 files changed, 65 insertions(+), 24 deletions(-) create mode 100644 util/config/validators/test/test_validate_google_login.py create mode 100644 util/config/validators/validate_google_login.py diff --git a/util/config/validator.py b/util/config/validator.py index c2ad42da8..1be17b614 100644 --- a/util/config/validator.py +++ b/util/config/validator.py @@ -2,15 +2,12 @@ import logging import peewee -from flask import Flask - -from app import app, config_provider, get_app_url, OVERRIDE_CONFIG_DIRECTORY +from app import app, get_app_url from auth.auth_context import get_authenticated_user from bitbucket import BitBucket from data.database import validate_database_url from data.users import LDAP_CERT_FILENAME from oauth.services.github import GithubOAuthService -from oauth.services.google import GoogleOAuthService from oauth.services.gitlab import GitLabOAuthService from util.config.validators.validate_database import DatabaseValidator @@ -24,6 +21,7 @@ from util.config.validators.validate_secscan import SecurityScannerValidator from util.config.validators.validate_signer import SignerValidator from util.config.validators.validate_torrent import BittorrentValidator from util.config.validators.validate_ssl import SSLValidator, SSL_FILENAMES +from util.config.validators.validate_google_login import GoogleLoginValidator logger = logging.getLogger(__name__) @@ -160,25 +158,6 @@ def _validate_bitbucket(config, user_obj, _): raise ConfigValidationException('Invalid consumer key or secret') -def _validate_google_login(config, user_obj, _): - """ Validates the Google Login client ID and secret. """ - google_login_config = config.get('GOOGLE_LOGIN_CONFIG') - if not google_login_config: - raise ConfigValidationException('Missing client ID and client secret') - - if not google_login_config.get('CLIENT_ID'): - raise ConfigValidationException('Missing Client ID') - - if not google_login_config.get('CLIENT_SECRET'): - raise ConfigValidationException('Missing Client Secret') - - client = app.config['HTTPCLIENT'] - oauth = GoogleOAuthService(config, 'GOOGLE_LOGIN_CONFIG') - result = oauth.validate_client_id_and_secret(client, app.config) - if not result: - raise ConfigValidationException('Invalid client id or client secret') - - VALIDATORS = { DatabaseValidator.name: DatabaseValidator.validate, RedisValidator.name: RedisValidator.validate, @@ -188,7 +167,7 @@ VALIDATORS = { 'github-trigger': _validate_github('GITHUB_TRIGGER_CONFIG'), 'gitlab-trigger': _validate_gitlab, 'bitbucket-trigger': _validate_bitbucket, - 'google-login': _validate_google_login, + GoogleLoginValidator.name: GoogleLoginValidator.validate, SSLValidator.name: SSLValidator.validate, LDAPValidator.name: LDAPValidator.validate, JWTAuthValidator.name: JWTAuthValidator.validate, diff --git a/util/config/validators/test/test_validate_google_login.py b/util/config/validators/test/test_validate_google_login.py new file mode 100644 index 000000000..8f41668c5 --- /dev/null +++ b/util/config/validators/test/test_validate_google_login.py @@ -0,0 +1,37 @@ +import pytest + +from httmock import urlmatch, HTTMock + +from util.config.validators import ConfigValidationException +from util.config.validators.validate_google_login import GoogleLoginValidator + +@pytest.mark.parametrize('unvalidated_config', [ + ({}), + ({'GOOGLE_LOGIN_CONFIG': {}}), + ({'GOOGLE_LOGIN_CONFIG': {'CLIENT_ID': 'foo'}}), + ({'GOOGLE_LOGIN_CONFIG': {'CLIENT_SECRET': 'foo'}}), +]) +def test_validate_invalid_google_login_config(unvalidated_config): + validator = GoogleLoginValidator() + + with pytest.raises(ConfigValidationException): + validator.validate(unvalidated_config, None, None) + +def test_validate_google_login(): + url_hit = [False] + @urlmatch(netloc=r'www.googleapis.com', path='/oauth2/v3/token') + def handler(_, __): + url_hit[0] = True + return {'status_code': 200, 'content': ''} + + validator = GoogleLoginValidator() + + with HTTMock(handler): + validator.validate({ + 'GOOGLE_LOGIN_CONFIG': { + 'CLIENT_ID': 'foo', + 'CLIENT_SECRET': 'bar', + }, + }, None, None) + + assert url_hit[0] diff --git a/util/config/validators/validate_google_login.py b/util/config/validators/validate_google_login.py new file mode 100644 index 000000000..80e1537f0 --- /dev/null +++ b/util/config/validators/validate_google_login.py @@ -0,0 +1,25 @@ +from app import app +from oauth.services.google import GoogleOAuthService +from util.config.validators import BaseValidator, ConfigValidationException + +class GoogleLoginValidator(BaseValidator): + name = "google-login" + + @classmethod + def validate(cls, config, user, user_password): + """ Validates the Google Login client ID and secret. """ + google_login_config = config.get('GOOGLE_LOGIN_CONFIG') + if not google_login_config: + raise ConfigValidationException('Missing client ID and client secret') + + if not google_login_config.get('CLIENT_ID'): + raise ConfigValidationException('Missing Client ID') + + if not google_login_config.get('CLIENT_SECRET'): + raise ConfigValidationException('Missing Client Secret') + + client = app.config['HTTPCLIENT'] + oauth = GoogleOAuthService(config, 'GOOGLE_LOGIN_CONFIG') + result = oauth.validate_client_id_and_secret(client, app.config) + if not result: + raise ConfigValidationException('Invalid client id or client secret')