def exchange_code(self, app_config, http_client, code, form_encode=False, redirect_suffix='', client_auth=False): """ Exchanges an OAuth access code for associated OAuth token and other data. """ url_scheme_and_hostname = URLSchemeAndHostname.from_app_config( app_config) payload = { 'code': code, 'grant_type': 'authorization_code', 'redirect_uri': self.get_redirect_uri(url_scheme_and_hostname, redirect_suffix) } headers = {'Accept': 'application/json'} auth = None if client_auth: auth = (self.client_id(), self.client_secret()) else: payload['client_id'] = self.client_id() payload['client_secret'] = self.client_secret() token_url = self.token_endpoint().to_url() if form_encode: get_access_token = http_client.post(token_url, data=payload, headers=headers, auth=auth) else: get_access_token = http_client.post(token_url, params=payload, headers=headers, auth=auth) if get_access_token.status_code // 100 != 2: logger.debug('Got get_access_token response %s', get_access_token.text) raise OAuthExchangeCodeException( 'Got non-2XX response for code exchange: %s' % get_access_token.status_code) json_data = get_access_token.json() if not json_data: raise OAuthExchangeCodeException( 'Got non-JSON response for code exchange') if 'error' in json_data: raise OAuthExchangeCodeException( json_data.get('error_description', json_data['error'])) return json_data
def test_auth_url(oidc_service, discovery_handler, http_client, authorize_handler): config = {"PREFERRED_URL_SCHEME": "https", "SERVER_HOSTNAME": "someserver"} with HTTMock(discovery_handler, authorize_handler): url_scheme_and_hostname = URLSchemeAndHostname.from_app_config(config) auth_url = oidc_service.get_auth_url(url_scheme_and_hostname, "", "some csrf token", ["one", "two"]) # Hit the URL and ensure it works. result = http_client.get(auth_url).json() assert result["state"] == "some csrf token" assert result["scope"] == "one two"
def test_auth_url(oidc_service, discovery_handler, http_client, authorize_handler): config = {'PREFERRED_URL_SCHEME': 'https', 'SERVER_HOSTNAME': 'someserver'} with HTTMock(discovery_handler, authorize_handler): url_scheme_and_hostname = URLSchemeAndHostname.from_app_config(config) auth_url = oidc_service.get_auth_url(url_scheme_and_hostname, '', 'some csrf token', ['one', 'two']) # Hit the URL and ensure it works. result = http_client.get(auth_url).json() assert result['state'] == 'some csrf token' assert result['scope'] == 'one two'
def exchange_code( self, app_config, http_client, code, form_encode=False, redirect_suffix="", client_auth=False, ): """ Exchanges an OAuth access code for associated OAuth token and other data. """ url_scheme_and_hostname = URLSchemeAndHostname.from_app_config(app_config) payload = { "code": code, "grant_type": "authorization_code", "redirect_uri": self.get_redirect_uri(url_scheme_and_hostname, redirect_suffix), } headers = {"Accept": "application/json"} auth = None if client_auth: auth = (self.client_id(), self.client_secret()) else: payload["client_id"] = self.client_id() payload["client_secret"] = self.client_secret() token_url = self.token_endpoint().to_url() if form_encode: get_access_token = http_client.post(token_url, data=payload, headers=headers, auth=auth) else: get_access_token = http_client.post( token_url, params=payload, headers=headers, auth=auth ) if get_access_token.status_code // 100 != 2: logger.debug("Got get_access_token response %s", get_access_token.text) raise OAuthExchangeCodeException( "Got non-2XX response for code exchange: %s" % get_access_token.status_code ) json_data = get_access_token.json() if not json_data: raise OAuthExchangeCodeException("Got non-JSON response for code exchange") if "error" in json_data: raise OAuthExchangeCodeException(json_data.get("error_description", json_data["error"])) return json_data
def from_app( cls, app, config, user_password, ip_resolver, instance_keys, client=None, config_provider=None, init_scripts_location=None, ): """ Creates a ValidatorContext from an app config, with a given config to validate. :param app: the Flask app to pull configuration information from :param config: the config to validate :param user_password: request password :param instance_keys: The instance keys handler :param ip_resolver: an App :param client: http client used to connect to services :param config_provider: config provider used to access config volume(s) :param init_scripts_location: location where initial load scripts are stored :return: ValidatorContext """ url_scheme_and_hostname = URLSchemeAndHostname.from_app_config( app.config) return cls( config, user_password=user_password, http_client=client or app.config["HTTPCLIENT"], context=app.app_context, url_scheme_and_hostname=url_scheme_and_hostname, jwt_auth_max=app.config.get("JWT_AUTH_MAX_FRESH_S", 300), registry_title=app.config["REGISTRY_TITLE"], ip_resolver=ip_resolver, feature_sec_scanner=app.config.get("FEATURE_SECURITY_SCANNER", False), is_testing=app.config.get("TESTING", False), uri_creator=get_blob_download_uri_getter( app.test_request_context("/"), url_scheme_and_hostname), config_provider=config_provider, instance_keys=instance_keys, init_scripts_location=init_scripts_location, )
def exchange_code( self, app_config, http_client, code, form_encode=False, redirect_suffix="", client_auth=False, ): """ Exchanges an OAuth access code for associated OAuth token and other data. """ url_scheme_and_hostname = URLSchemeAndHostname.from_app_config(app_config) payload = { "code": code, "grant_type": "authorization_code", "redirect_uri": self.get_redirect_uri(url_scheme_and_hostname, redirect_suffix), } headers = {"Accept": "application/json"} auth = None if client_auth: auth = (self.client_id(), self.client_secret()) else: payload["client_id"] = self.client_id() payload["client_secret"] = self.client_secret() token_url = self.token_endpoint().to_url() def perform_request(): attempts = 0 max_attempts = 3 timeout = 5 / 1000 while attempts < max_attempts: if self._is_testing: headers["X-Quay-Retry-Attempts"] = str(attempts) try: if form_encode: return http_client.post( token_url, data=payload, headers=headers, auth=auth, timeout=5 ) else: return http_client.post( token_url, params=payload, headers=headers, auth=auth, timeout=5 ) except requests.ConnectionError: logger.debug("Got ConnectionError during OAuth token exchange, retrying.") attempts += 1 time.sleep(timeout) get_access_token = perform_request() if get_access_token is None: logger.debug("Received too many ConnectionErrors during code exchange") raise OAuthExchangeCodeException( "Received too many ConnectionErrors during code exchange" ) if get_access_token.status_code // 100 != 2: logger.debug("Got get_access_token response %s", get_access_token.text) raise OAuthExchangeCodeException( "Got non-2XX response for code exchange: %s" % get_access_token.status_code ) json_data = get_access_token.json() if not json_data: raise OAuthExchangeCodeException("Got non-JSON response for code exchange") if "error" in json_data: raise OAuthExchangeCodeException(json_data.get("error_description", json_data["error"])) return json_data