2015-02-05 18:06:56 +00:00
|
|
|
import logging
|
2015-01-07 21:20:51 +00:00
|
|
|
|
2016-09-29 00:17:14 +00:00
|
|
|
import peewee
|
2015-07-20 15:39:59 +00:00
|
|
|
|
2015-01-07 21:20:51 +00:00
|
|
|
from flask import Flask
|
2016-09-29 00:17:14 +00:00
|
|
|
|
|
|
|
from app import app, config_provider, get_app_url, OVERRIDE_CONFIG_DIRECTORY
|
|
|
|
from auth.auth_context import get_authenticated_user
|
|
|
|
from bitbucket import BitBucket
|
2016-05-02 19:29:31 +00:00
|
|
|
from data.database import validate_database_url
|
2016-09-29 00:17:14 +00:00
|
|
|
from data.users import LDAP_CERT_FILENAME
|
2017-01-30 22:28:25 +00:00
|
|
|
from oauth.services.github import GithubOAuthService
|
|
|
|
from oauth.services.google import GoogleOAuthService
|
|
|
|
from oauth.services.gitlab import GitLabOAuthService
|
2017-01-31 18:47:49 +00:00
|
|
|
|
2017-02-09 23:51:28 +00:00
|
|
|
from util.config.validators.validate_database import DatabaseValidator
|
|
|
|
from util.config.validators.validate_redis import RedisValidator
|
|
|
|
from util.config.validators.validate_storage import StorageValidator
|
|
|
|
from util.config.validators.validate_email import EmailValidator
|
2017-02-10 00:09:57 +00:00
|
|
|
from util.config.validators.validate_ldap import LDAPValidator
|
2017-02-10 00:30:07 +00:00
|
|
|
from util.config.validators.validate_keystone import KeystoneValidator
|
2017-02-10 01:07:14 +00:00
|
|
|
from util.config.validators.validate_jwt import JWTAuthValidator
|
2017-02-10 01:28:39 +00:00
|
|
|
from util.config.validators.validate_secscan import SecurityScannerValidator
|
2017-02-15 16:56:19 +00:00
|
|
|
from util.config.validators.validate_signer import SignerValidator
|
2017-02-15 17:12:19 +00:00
|
|
|
from util.config.validators.validate_torrent import BittorrentValidator
|
2017-02-15 20:17:07 +00:00
|
|
|
from util.config.validators.validate_ssl import SSLValidator, SSL_FILENAMES
|
2015-01-07 21:20:51 +00:00
|
|
|
|
2015-02-05 18:06:56 +00:00
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
2016-11-29 20:20:46 +00:00
|
|
|
class ConfigValidationException(Exception):
|
|
|
|
""" Exception raised when the configuration fails to validate for a known reason. """
|
|
|
|
pass
|
|
|
|
|
2016-09-29 00:17:14 +00:00
|
|
|
|
2015-07-15 21:49:07 +00:00
|
|
|
# Note: Only add files required for HTTPS to the SSL_FILESNAMES list.
|
|
|
|
DB_SSL_FILENAMES = ['database.pem']
|
2015-06-02 22:19:22 +00:00
|
|
|
JWT_FILENAMES = ['jwt-authn.cert']
|
2016-02-16 20:31:23 +00:00
|
|
|
ACI_CERT_FILENAMES = ['signing-public.gpg', 'signing-private.gpg']
|
2016-05-03 19:02:39 +00:00
|
|
|
LDAP_FILENAMES = [LDAP_CERT_FILENAME]
|
|
|
|
CONFIG_FILENAMES = (SSL_FILENAMES + DB_SSL_FILENAMES + JWT_FILENAMES + ACI_CERT_FILENAMES +
|
|
|
|
LDAP_FILENAMES)
|
2017-01-11 23:45:46 +00:00
|
|
|
EXTRA_CA_DIRECTORY = 'extra_ca_certs'
|
2015-01-07 21:20:51 +00:00
|
|
|
|
2015-01-16 21:10:40 +00:00
|
|
|
|
2015-06-22 22:17:37 +00:00
|
|
|
def validate_service_for_config(service, config, password=None):
|
2015-01-07 21:20:51 +00:00
|
|
|
""" Attempts to validate the configuration for the given service. """
|
2016-11-29 20:20:46 +00:00
|
|
|
if not service in VALIDATORS:
|
2015-01-07 21:20:51 +00:00
|
|
|
return {
|
|
|
|
'status': False
|
|
|
|
}
|
|
|
|
|
|
|
|
try:
|
2016-11-29 20:20:46 +00:00
|
|
|
VALIDATORS[service](config, get_authenticated_user(), password)
|
2015-01-07 21:20:51 +00:00
|
|
|
return {
|
|
|
|
'status': True
|
|
|
|
}
|
|
|
|
except Exception as ex:
|
2015-02-05 18:06:56 +00:00
|
|
|
logger.exception('Validation exception')
|
2015-01-07 21:20:51 +00:00
|
|
|
return {
|
|
|
|
'status': False,
|
|
|
|
'reason': str(ex)
|
|
|
|
}
|
|
|
|
|
2015-01-08 18:26:24 +00:00
|
|
|
|
2016-11-29 20:20:46 +00:00
|
|
|
def _validate_database(config, user_obj, _):
|
2015-01-07 21:20:51 +00:00
|
|
|
""" Validates connecting to the database. """
|
2015-01-08 20:27:49 +00:00
|
|
|
try:
|
2015-06-29 05:08:10 +00:00
|
|
|
validate_database_url(config['DB_URI'], config.get('DB_CONNECTION_ARGS', {}))
|
2015-01-08 20:27:49 +00:00
|
|
|
except peewee.OperationalError as ex:
|
|
|
|
if ex.args and len(ex.args) > 1:
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException(ex.args[1])
|
2015-01-08 20:27:49 +00:00
|
|
|
else:
|
|
|
|
raise ex
|
2015-01-07 21:20:51 +00:00
|
|
|
|
2015-01-08 18:26:24 +00:00
|
|
|
|
2016-11-29 20:20:46 +00:00
|
|
|
def _validate_gitlab(config, user_obj, _):
|
2015-05-03 18:50:26 +00:00
|
|
|
""" Validates the OAuth credentials and API endpoint for a GitLab service. """
|
|
|
|
github_config = config.get('GITLAB_TRIGGER_CONFIG')
|
|
|
|
if not github_config:
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Missing GitLab client id and client secret')
|
2015-05-03 18:50:26 +00:00
|
|
|
|
|
|
|
endpoint = github_config.get('GITLAB_ENDPOINT')
|
|
|
|
if not endpoint:
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Missing GitLab Endpoint')
|
2015-05-03 18:50:26 +00:00
|
|
|
|
|
|
|
if endpoint.find('http://') != 0 and endpoint.find('https://') != 0:
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('GitLab Endpoint must start with http:// or https://')
|
2015-05-03 18:50:26 +00:00
|
|
|
|
|
|
|
if not github_config.get('CLIENT_ID'):
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Missing Client ID')
|
2015-05-03 18:50:26 +00:00
|
|
|
|
|
|
|
if not github_config.get('CLIENT_SECRET'):
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Missing Client Secret')
|
2015-05-03 18:50:26 +00:00
|
|
|
|
|
|
|
client = app.config['HTTPCLIENT']
|
2017-01-30 22:28:25 +00:00
|
|
|
oauth = GitLabOAuthService(config, 'GITLAB_TRIGGER_CONFIG')
|
2015-05-03 18:50:26 +00:00
|
|
|
result = oauth.validate_client_id_and_secret(client, app.config)
|
|
|
|
if not result:
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Invalid client id or client secret')
|
2015-05-03 18:50:26 +00:00
|
|
|
|
|
|
|
|
2015-01-08 18:26:24 +00:00
|
|
|
def _validate_github(config_key):
|
2016-11-29 20:20:46 +00:00
|
|
|
return lambda config, user_obj, _: _validate_github_with_key(config_key, config)
|
2015-01-08 18:26:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
def _validate_github_with_key(config_key, config):
|
|
|
|
""" Validates the OAuth credentials and API endpoint for a Github service. """
|
2015-01-08 18:56:17 +00:00
|
|
|
github_config = config.get(config_key)
|
|
|
|
if not github_config:
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Missing GitHub client id and client secret')
|
2015-01-08 18:56:17 +00:00
|
|
|
|
|
|
|
endpoint = github_config.get('GITHUB_ENDPOINT')
|
2015-01-08 18:26:24 +00:00
|
|
|
if not endpoint:
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Missing GitHub Endpoint')
|
2015-01-08 18:26:24 +00:00
|
|
|
|
|
|
|
if endpoint.find('http://') != 0 and endpoint.find('https://') != 0:
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Github Endpoint must start with http:// or https://')
|
2015-01-08 18:26:24 +00:00
|
|
|
|
2015-01-08 18:56:17 +00:00
|
|
|
if not github_config.get('CLIENT_ID'):
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Missing Client ID')
|
2015-01-08 18:26:24 +00:00
|
|
|
|
2015-01-08 18:56:17 +00:00
|
|
|
if not github_config.get('CLIENT_SECRET'):
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Missing Client Secret')
|
2015-01-08 18:26:24 +00:00
|
|
|
|
2015-03-04 00:58:42 +00:00
|
|
|
if github_config.get('ORG_RESTRICT') and not github_config.get('ALLOWED_ORGANIZATIONS'):
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Organization restriction must have at least one allowed ' +
|
|
|
|
'organization')
|
2015-03-04 00:58:42 +00:00
|
|
|
|
2015-01-07 21:20:51 +00:00
|
|
|
client = app.config['HTTPCLIENT']
|
2017-01-30 22:28:25 +00:00
|
|
|
oauth = GithubOAuthService(config, config_key)
|
2015-05-03 18:50:26 +00:00
|
|
|
result = oauth.validate_client_id_and_secret(client, app.config)
|
2015-01-08 18:26:24 +00:00
|
|
|
if not result:
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Invalid client id or client secret')
|
2015-01-07 21:20:51 +00:00
|
|
|
|
2015-03-04 00:58:42 +00:00
|
|
|
if github_config.get('ALLOWED_ORGANIZATIONS'):
|
|
|
|
for org_id in github_config.get('ALLOWED_ORGANIZATIONS'):
|
|
|
|
if not oauth.validate_organization(org_id, client):
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Invalid organization: %s' % org_id)
|
2015-03-04 00:58:42 +00:00
|
|
|
|
2015-01-07 21:20:51 +00:00
|
|
|
|
2016-11-29 20:20:46 +00:00
|
|
|
def _validate_bitbucket(config, user_obj, _):
|
2015-05-03 18:50:26 +00:00
|
|
|
""" Validates the config for BitBucket. """
|
|
|
|
trigger_config = config.get('BITBUCKET_TRIGGER_CONFIG')
|
|
|
|
if not trigger_config:
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Missing client ID and client secret')
|
2015-05-03 18:50:26 +00:00
|
|
|
|
|
|
|
if not trigger_config.get('CONSUMER_KEY'):
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Missing Consumer Key')
|
2015-05-03 18:50:26 +00:00
|
|
|
|
|
|
|
if not trigger_config.get('CONSUMER_SECRET'):
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Missing Consumer Secret')
|
2015-05-03 18:50:26 +00:00
|
|
|
|
|
|
|
key = trigger_config['CONSUMER_KEY']
|
|
|
|
secret = trigger_config['CONSUMER_SECRET']
|
|
|
|
callback_url = '%s/oauth1/bitbucket/callback/trigger/' % (get_app_url())
|
|
|
|
|
|
|
|
bitbucket_client = BitBucket(key, secret, callback_url)
|
|
|
|
(result, _, _) = bitbucket_client.get_authorization_url()
|
|
|
|
if not result:
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Invalid consumer key or secret')
|
2015-05-03 18:50:26 +00:00
|
|
|
|
|
|
|
|
2016-11-29 20:20:46 +00:00
|
|
|
def _validate_google_login(config, user_obj, _):
|
2015-01-08 18:56:17 +00:00
|
|
|
""" Validates the Google Login client ID and secret. """
|
|
|
|
google_login_config = config.get('GOOGLE_LOGIN_CONFIG')
|
|
|
|
if not google_login_config:
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Missing client ID and client secret')
|
2015-01-08 18:56:17 +00:00
|
|
|
|
|
|
|
if not google_login_config.get('CLIENT_ID'):
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Missing Client ID')
|
2015-01-08 18:56:17 +00:00
|
|
|
|
|
|
|
if not google_login_config.get('CLIENT_SECRET'):
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Missing Client Secret')
|
2015-01-08 18:56:17 +00:00
|
|
|
|
|
|
|
client = app.config['HTTPCLIENT']
|
2017-01-30 22:28:25 +00:00
|
|
|
oauth = GoogleOAuthService(config, 'GOOGLE_LOGIN_CONFIG')
|
2015-05-03 18:50:26 +00:00
|
|
|
result = oauth.validate_client_id_and_secret(client, app.config)
|
2015-01-08 18:56:17 +00:00
|
|
|
if not result:
|
2016-11-29 20:20:46 +00:00
|
|
|
raise ConfigValidationException('Invalid client id or client secret')
|
2015-01-08 18:56:17 +00:00
|
|
|
|
|
|
|
|
2016-11-29 20:20:46 +00:00
|
|
|
VALIDATORS = {
|
2017-01-30 21:24:58 +00:00
|
|
|
DatabaseValidator.name: DatabaseValidator.validate,
|
2017-01-31 18:47:49 +00:00
|
|
|
RedisValidator.name: RedisValidator.validate,
|
2017-01-31 20:56:25 +00:00
|
|
|
StorageValidator.name: StorageValidator.validate,
|
2017-02-09 19:04:57 +00:00
|
|
|
EmailValidator.name: EmailValidator.validate,
|
2015-01-08 18:26:24 +00:00
|
|
|
'github-login': _validate_github('GITHUB_LOGIN_CONFIG'),
|
|
|
|
'github-trigger': _validate_github('GITHUB_TRIGGER_CONFIG'),
|
2015-05-03 18:50:26 +00:00
|
|
|
'gitlab-trigger': _validate_gitlab,
|
|
|
|
'bitbucket-trigger': _validate_bitbucket,
|
2015-01-08 18:56:17 +00:00
|
|
|
'google-login': _validate_google_login,
|
2017-02-15 20:17:07 +00:00
|
|
|
SSLValidator.name: SSLValidator.validate,
|
2017-02-10 00:09:57 +00:00
|
|
|
LDAPValidator.name: LDAPValidator.validate,
|
2017-02-10 01:07:14 +00:00
|
|
|
JWTAuthValidator.name: JWTAuthValidator.validate,
|
2017-02-10 00:30:07 +00:00
|
|
|
KeystoneValidator.name: KeystoneValidator.validate,
|
2017-02-15 16:56:19 +00:00
|
|
|
SignerValidator.name: SignerValidator.validate,
|
2017-02-10 01:28:39 +00:00
|
|
|
SecurityScannerValidator.name: SecurityScannerValidator.validate,
|
2017-02-15 17:12:19 +00:00
|
|
|
BittorrentValidator.name: BittorrentValidator.validate,
|
2015-07-20 17:18:07 +00:00
|
|
|
}
|