def send_credentials_to_idp(s, header, idp_ip, idp_port, redirect_url, url_form, credentials_data, cookie, method): header_login_keycloak = { **header, 'Host': "{ip}:{port}".format(ip=idp_ip, port=idp_port), 'Referer': "{host}".format(host=redirect_url), } req_login_idp = Request(method=method, url="{url}".format(url=url_form), data=credentials_data, cookies=cookie, headers=header_login_keycloak) prepared_request = req_login_idp.prepare() logger.debug( json.dumps(prepared_request_to_json(req_login_idp), sort_keys=True, indent=4, separators=(',', ': '))) response = s.send(prepared_request, verify=False, allow_redirects=False) logger.debug(response.status_code) return response
def access_sp_ws_fed(s, header, sp_ip, sp_port, sp_scheme, sp_path): # Access to the SP header_sp_page = { **header, 'Host': "{ip}:{port}".format(ip=sp_ip, port=sp_port), 'Referer': "{ip}:{port}".format(ip=sp_ip, port=sp_port) } req_get_sp_page = Request( method='GET', url="{scheme}://{ip}:{port}/{path}".format(scheme=sp_scheme, port=sp_port, ip=sp_ip, path=sp_path), headers=header_sp_page, ) prepared_request = req_get_sp_page.prepare() logger.debug( json.dumps(prepared_request_to_json(req_get_sp_page), sort_keys=True, indent=4, separators=(',', ': '))) response = s.send(prepared_request, verify=False, allow_redirects=False) logger.debug(response.status_code) return response
def test_are_all_services_running(self, test_settings, services_json_schema): """ Test if all the services are up by doing a health check :param test_settings: pytest config loaded from config file :return: """ #Challange value fail_value = "KO" #Settings keycloak_bridge_hostname = test_settings['keycloak_bridge']['hostname'] keycloak_bridge_scheme = test_settings['keycloak_bridge'][ 'http_scheme'] keycloak_bridge_ip = test_settings['keycloak_bridge']['ip'] keycloak_bridge_port = test_settings['keycloak_bridge']['port'] #Test s = Session() headers = { 'Accept': "application/json'", 'Host': '{host}'.format(host=keycloak_bridge_hostname) } req = Request(method='GET', url="{scheme}://{ip}:{port}/health".format( scheme=keycloak_bridge_scheme, ip=keycloak_bridge_ip, port=keycloak_bridge_port), headers=headers) prepared_request = req.prepare() logger.debug( json.dumps(prepared_request_to_json(req), sort_keys=True, indent=4, separators=(',', ': '))) response = s.send(prepared_request, verify=False) response_json = response.json() assert jsonschema.Draft3Validator(services_json_schema).is_valid( response_json) assert re.search(fail_value, response.text) is None
def test_is_keycloak_bridge_online(self, test_settings, default_route_json_schema): """ Test if keycloak bridge service is running :param test_settings: pytest config loaded from config file :return: """ #Challange value component_name = test_settings['keycloak_bridge']['component_name'] #Settings keycloak_bridge_hostname = test_settings['keycloak_bridge']['hostname'] keycloak_bridge_scheme = test_settings['keycloak_bridge'][ 'http_scheme'] keycloak_bridge_ip = test_settings['keycloak_bridge']['ip'] keycloak_bridge_port = test_settings['keycloak_bridge']['port'] #Test s = Session() headers = { 'Accept': "application/json'", 'Host': '{host}'.format(host=keycloak_bridge_hostname) } req = Request(method='GET', url="{scheme}://{ip}:{port}/".format( scheme=keycloak_bridge_scheme, ip=keycloak_bridge_ip, port=keycloak_bridge_port), headers=headers) prepared_request = req.prepare() logger.debug( json.dumps(prepared_request_to_json(req), sort_keys=True, indent=4, separators=(',', ': '))) response = s.send(prepared_request, verify=False) response_json = response.json() assert jsonschema.Draft3Validator(default_route_json_schema).is_valid( response_json) assert re.search(component_name, response_json['name'])
def test_is_keycloak_online(self, test_settings): """ Test if keycloak service is running :param test_settings: pytest config loaded from config file :return: """ # Challenge value keycloak_welcome_validation = 'Welcome to Keycloak' # Settings keycloak_hostname = test_settings['keycloak']['hostname'] keycloak_scheme = test_settings['keycloak']['http_scheme'] keycloak_ip = test_settings['keycloak']['ip'] keycloak_port = test_settings['keycloak']['port'] # Test s = Session() headers = { 'Accept': "text/html; charset = UTF-8", 'Host': '{host}'.format(host=keycloak_hostname) } req = Request(method='GET', url="{scheme}://{ip}:{port}/auth/".format( scheme=keycloak_scheme, port=keycloak_port, ip=keycloak_ip), headers=headers) prepared_request = req.prepare() logger.debug( json.dumps(prepared_request_to_json(req), sort_keys=True, indent=4, separators=(',', ': '))) response = s.send(prepared_request, verify=False) assert re.search(keycloak_welcome_validation, response.text)
def redirect_to_idp(s, redirect_url, header, cookie): # Perform the redirect request of the identity provider req_get_keycloak = Request(method='GET', url="{url}".format(url=redirect_url), cookies=cookie, headers=header) prepared_request = req_get_keycloak.prepare() logger.debug( json.dumps(prepared_request_to_json(req_get_keycloak), sort_keys=True, indent=4, separators=(',', ': '))) response = s.send(prepared_request, verify=False) logger.debug(response.status_code) return response
def test_CT_TC_WS_FED_IDP_LOGOUT_SIMPLE(self, settings, login_sso_form): """ Test the CT_TC_WS_FED_IDP_LOGOUT_SIMPLE use case with the SP-initiated flow, i.e. the user that accessed the SP asks to be logged out. This will trigger the logout to be performed on the IDP side and the user will be able to see the "You're logged out" page. :param settings: :return: """ s = Session() # Service provider settings sp_ip = settings["service_provider"]["ip"] sp_port = settings["service_provider"]["port"] sp_scheme = settings["service_provider"]["http_scheme"] sp_logout_path = settings["service_provider"]["logout_path"] sp_message = settings["service_provider"]["logged_out_message"] # Identity provider settings idp_ip = settings["identity_provider"]["ip"] idp_port = settings["identity_provider"]["port"] idp_scheme = settings["identity_provider"]["http_scheme"] # Common header for all the requests header = { 'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", 'Accept-Encoding': "gzip, deflate", 'Accept-Language': "en-US,en;q=0.5", 'User-Agent': "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:59.0) Gecko/20100101 Firefox/59.0", 'Connection': "keep-alive", 'Upgrade-Insecure-Requests': "1", } # Perform login using the fixture login_sso_form sp_cookie, keycloak_cookie = login_sso_form # User is logged in # Access to the SP logout page header_sp_logout_page = { **header, 'Host': "{ip}:{port}".format(ip=sp_ip, port=sp_port), 'Referer': "{scheme}://{ip}:{port}".format(scheme=sp_scheme, ip=sp_ip, port=sp_port) } req_get_sp_logout_page = Request( method='GET', url="{scheme}://{ip}:{port}/{path}".format(scheme=sp_scheme, port=sp_port, ip=sp_ip, path=sp_logout_path), headers=header_sp_logout_page, cookies=sp_cookie) prepared_request = req_get_sp_logout_page.prepare() logger.debug( json.dumps(prepared_request_to_json(req_get_sp_logout_page), sort_keys=True, indent=4, separators=(',', ': '))) response = s.send(prepared_request, verify=False, allow_redirects=False) logger.debug(response.status_code) redirect_url = response.headers['Location'] req_sp_logout_redirect = Request(method='GET', url=redirect_url, headers=header_sp_logout_page, cookies={**sp_cookie}) prepared_request = req_sp_logout_redirect.prepare() logger.debug( json.dumps(prepared_request_to_json(req_sp_logout_redirect), sort_keys=True, indent=4, separators=(',', ': '))) response = s.send(prepared_request, verify=False, allow_redirects=False) logger.debug(response.status_code) redirect_url = response.headers['Location'] header_redirect_idp = { **header, 'Host': "{ip}:{port}".format(ip=idp_ip, port=idp_port), 'Referer': "{ip}:{port}".format(ip=sp_ip, port=sp_port) } response = req.redirect_to_idp(s, redirect_url, header, sp_cookie) assert response.status_code == 200 soup = BeautifulSoup(response.content, 'html.parser') form = soup.body.form url_form = form.get('action') method_form = form.get('method') inputs = form.find_all('input') # Send ws fed response token = {} for input in inputs: token[input.get('name')] = input.get('value') (response, cookie) = req.access_sp_with_token(s, header, sp_ip, sp_port, idp_scheme, idp_ip, idp_port, method_form, url_form, token, sp_cookie, sp_cookie) assert response.status_code == 200 assert re.search(sp_message, response.text) is not None
def test_CT_TC_SAML_IDP_LOGOUT_PERIMETRIC(self, settings, login_sso_form): """ Scenario: user is logged in on several SPs. The user logs out of one SP. Access to all the other SPs should require a new log in. :param settings: :return: """ s = Session() # Service provider settings sp_ip = settings["service_provider"]["ip"] sp_port = settings["service_provider"]["port"] sp_scheme = settings["service_provider"]["http_scheme"] sp_logout_path = settings["service_provider"]["logout_path"] sp_message = settings["service_provider"]["logged_out_message"] sp_path = settings["service_provider"]["path"] # Service provider settings sp2_ip = settings["service_provider2"]["ip"] sp2_port = settings["service_provider2"]["port"] sp2_scheme = settings["service_provider2"]["http_scheme"] sp2_logout_path = settings["service_provider2"]["logout_path"] sp2_path = settings["service_provider2"]["path"] sp2_message = settings["service_provider2"]["logged_in_message"] # Identity provider settings idp_ip = settings["identity_provider"]["ip"] idp_port = settings["identity_provider"]["port"] idp_scheme = settings["identity_provider"]["http_scheme"] # Common header for all the requests header = { 'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", 'Accept-Encoding': "gzip, deflate", 'Accept-Language': "en-US,en;q=0.5", 'User-Agent': "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:59.0) Gecko/20100101 Firefox/59.0", 'Connection': "keep-alive", 'Upgrade-Insecure-Requests': "1", } # Perform login using the fixture login_sso_form sp_cookie, keycloak_cookie = login_sso_form # User is logged in on SP1 # Perform login on SP2 (session_cookie, response) = req.access_sp_saml(s, header, sp2_ip, sp2_port, sp2_scheme, sp2_path, idp_ip, idp_port) session_cookie2 = response.cookies redirect_url = response.headers['Location'] header_redirect_idp = { **header, 'Host': "{ip}:{port}".format(ip=idp_ip, port=idp_port), 'Referer': "{ip}:{port}".format(ip=sp2_ip, port=sp2_port) } response = req.redirect_to_idp(s, redirect_url, header_redirect_idp, {**keycloak_cookie, **session_cookie2}) soup = BeautifulSoup(response.content, 'html.parser') form = soup.body.form url_form = form.get('action') inputs = form.find_all('input') method_form = form.get('method') # Get the saml response from the identity provider token = {} for input in inputs: token[input.get('name')] = input.get('value') (response, sp2_cookie) = req.access_sp_with_token(s, header, sp2_ip, sp2_port, idp_scheme, idp_ip, idp_port, method_form, url_form, token, session_cookie, session_cookie2) # req_get_sp_login_reload_page = Request( # method='GET', # url="{scheme}://{ip}:{port}/{path}".format( # scheme=sp2_scheme, # port=sp2_port, # ip=sp2_ip, # path=sp2_path # ), # headers=header_sp2_reload_page, # cookies={**session_cookie} # ) # # prepared_request = req_get_sp_login_reload_page.prepare() # # logger.debug( # json.dumps( # prepared_request_to_json(req_get_sp_login_reload_page), # sort_keys=True, # indent=4, # separators=(',', ': ') # ) # ) # # response = s.send(prepared_request, verify=False, allow_redirects=False) # # logger.debug(response.status_code) # # # the user is logged in and refreshing the page will return an OK # assert response.status_code == 200 # User is now logged in on both applications: SP1 and SP2 # Logout from the first applications header_sp_logout_page = { **header, 'Host': "{ip}:{port}".format(ip=sp_ip, port=sp_port), 'Referer': "{scheme}://{ip}:{port}".format(scheme=sp_scheme, ip=sp_ip, port=sp_port) } req_get_sp_logout_page = Request( method='GET', url="{scheme}://{ip}:{port}/{path}".format( scheme=sp_scheme, port=sp_port, ip=sp_ip, path=sp_logout_path ), headers=header_sp_logout_page, cookies={**sp_cookie} ) prepared_request = req_get_sp_logout_page.prepare() logger.debug( json.dumps( prepared_request_to_json(req_get_sp_logout_page), sort_keys=True, indent=4, separators=(',', ': ') ) ) response = s.send(prepared_request, verify=False, allow_redirects=False) logger.debug(response.status_code) # new session cookie session_cookie2 = response.cookies # SP redirects me to IDP with a SAML request soup = BeautifulSoup(response.content, 'html.parser') form = soup.body.form url_form = form.get('action') method_form = form.get('method') inputs = form.find_all('input') # Do a SAML request to the identity provider saml_request = {} for input in inputs: saml_request[input.get('name')] = input.get('value') header_redirect_idp = { **header, 'Host': "{ip}:{port}".format(ip=idp_ip, port=idp_port), 'Referer': "{scheme}://{ip}:{port}/{path}".format(scheme=sp_scheme, ip=sp_ip, port=sp_port, path=sp_logout_path), } req_idp_saml_request = Request( method=method_form, url="{url}".format(url=url_form), data=saml_request, headers=header_redirect_idp ) prepared_request = req_idp_saml_request.prepare() logger.debug( json.dumps( prepared_request_to_json(req_idp_saml_request), sort_keys=True, indent=4, separators=(',', ': ') ) ) response = s.send(prepared_request, verify=False, allow_redirects=False) logger.debug(response.status_code) assert response.status_code == 200 soup = BeautifulSoup(response.content, 'html.parser') form = soup.body.form url_form = form.get('action') inputs = form.find_all('input') method_form = form.get('method') # Get the saml response from the identity provider saml_response = {} for input in inputs: saml_response[input.get('name')] = input.get('value') header_idp_saml_response = { **header, 'Host': "{ip}:{port}".format(ip=sp_ip, port=sp_port), 'Referer': "{scheme}://{ip}:{port}".format(scheme=idp_scheme, ip=idp_ip, port=idp_port), } # Provide to the SP the SAML response req_sp_saml_response = Request( method=method_form, url="{url}".format(url=url_form), data=saml_request, headers=header_idp_saml_response ) prepared_request = req_sp_saml_response.prepare() logger.debug( json.dumps( prepared_request_to_json(req_sp_saml_response), sort_keys=True, indent=4, separators=(',', ': ') ) ) response = s.send(prepared_request, verify=False, allow_redirects=False) logger.debug(response.status_code) url_sp = response.headers['Location'] req_logout = Request( method='GET', url="{url}".format(url=url_sp), headers=header_idp_saml_response ) prepared_request = req_logout.prepare() logger.debug( json.dumps( prepared_request_to_json(req_logout), sort_keys=True, indent=4, separators=(',', ': ') ) ) response = s.send(prepared_request, verify=False) logger.debug(response.status_code) assert response.status_code == 200 # Assert the logout page is displayed assert re.search(sp_message, response.text) is not None # Check that when the user accesses the secured page of SP1 with the old session cookie, # he receives a 200 with the SAMl request header_sp_reload_page = { **header, 'Host': "{ip}:{port}".format(ip=sp_ip, port=sp_port), 'Referer': "{scheme}://{ip}:{port}".format(scheme=idp_scheme, ip=idp_ip, port=idp_port) } req_get_sp_login_reload_page = Request( method='GET', url="{scheme}://{ip}:{port}/{path}".format( scheme=sp_scheme, port=sp_port, ip=sp_ip, path=sp_path ), headers=header_sp_reload_page, cookies={**session_cookie} ) prepared_request = req_get_sp_login_reload_page.prepare() logger.debug( json.dumps( prepared_request_to_json(req_get_sp_login_reload_page), sort_keys=True, indent=4, separators=(',', ': ') ) ) response = s.send(prepared_request, verify=False, allow_redirects=False) logger.debug(response.status_code) assert response.status_code == 200 # Response should return a form that requests a post with RelayState and SAMLRequest as input soup = BeautifulSoup(response.content, 'html.parser') form = soup.body.form inputs = form.find_all('input') # Check we get RelayState and SAMLRequest input_name = [] for input in inputs: input_name.append(input.get('name')) assert "RelayState" in input_name assert "SAMLRequest" in input_name # Check if the user is logged out from SP2: perform a refresh of the page; we expect to get a 200 with a form # containing the SAMLRequest header_sp2_reload_page = { **header, 'Host': "{ip}:{port}".format(ip=sp2_ip, port=sp2_port), 'Referer': "{scheme}://{ip}:{port}".format(scheme=idp_scheme, ip=idp_ip, port=idp_port) } req_get_sp_login_reload_page = Request( method='GET', url="{scheme}://{ip}:{port}/{path}".format( scheme=sp2_scheme, port=sp2_port, ip=sp2_ip, path=sp2_path ), headers=header_sp2_reload_page, cookies={**session_cookie} ) prepared_request = req_get_sp_login_reload_page.prepare() logger.debug( json.dumps( prepared_request_to_json(req_get_sp_login_reload_page), sort_keys=True, indent=4, separators=(',', ': ') ) ) response = s.send(prepared_request, verify=False, allow_redirects=False) logger.debug(response.status_code) assert response.status_code == 200 # Response should return a form that requests a post with RelayState and SAMLRequest as input soup = BeautifulSoup(response.content, 'html.parser') form = soup.body.form inputs = form.find_all('input') # Check we get a form with input RelayState and SAMLRequest input_name = [] for input in inputs: input_name.append(input.get('name')) assert "RelayState" in input_name assert "SAMLRequest" in input_name
def access_sp_saml(s, header, sp_ip, sp_port, sp_scheme, sp_path, idp_ip, idp_port): # Access to the SP header_sp_page = { **header, 'Host': "{ip}:{port}".format(ip=sp_ip, port=sp_port), 'Referer': "{ip}:{port}".format(ip=sp_ip, port=sp_port) } req_get_sp_page = Request( method='GET', url="{scheme}://{ip}:{port}/{path}".format(scheme=sp_scheme, port=sp_port, ip=sp_ip, path=sp_path), headers=header_sp_page, ) prepared_request = req_get_sp_page.prepare() logger.debug( json.dumps(prepared_request_to_json(req_get_sp_page), sort_keys=True, indent=4, separators=(',', ': '))) response = s.send(prepared_request, verify=False) logger.debug(response.status_code) # store the session cookie session_cookie = response.cookies # Response returns a form that requests a post with RelayState and SAMLRequest as input soup = BeautifulSoup(response.content, 'html.parser') form = soup.body.form url_form = form.get('action') method_form = form.get('method') inputs = form.find_all('input') # Do a SAML request to the identity provider saml_request = {} for input in inputs: saml_request[input.get('name')] = input.get('value') header_redirect_idp = { **header, 'Host': "{ip}:{port}".format(ip=idp_ip, port=idp_port), 'Referer': "{ip}:{port}".format(ip=sp_ip, port=sp_port) } req_idp_saml_request = Request(method=method_form, url="{url}".format(url=url_form), data=saml_request, headers=header_redirect_idp) prepared_request = req_idp_saml_request.prepare() logger.debug( json.dumps(prepared_request_to_json(req_idp_saml_request), sort_keys=True, indent=4, separators=(',', ': '))) response = s.send(prepared_request, verify=False, allow_redirects=False) logger.debug(response.status_code) return session_cookie, response
def login_idp(s, header, idp_ip, idp_port, idp_scheme, idp_path, idp_username, idp_password): # Requests access to the SP header_idp_page = { **header, 'Host': "{ip}:{port}".format(ip=idp_ip, port=idp_port) } req_get_idp_page = Request( method='GET', url="{scheme}://{ip}:{port}/{path}".format(scheme=idp_scheme, ip=idp_ip, port=idp_port, path=idp_path), headers=header_idp_page, ) prepared_request = req_get_idp_page.prepare() logger.debug( json.dumps(prepared_request_to_json(req_get_idp_page), sort_keys=True, indent=4, separators=(',', ': '))) response = s.send(prepared_request, verify=False, allow_redirects=False) logger.debug(response.status_code) oath_cookie = response.cookies url_redirect = response.headers['Location'] req_idp_redirect = Request(method='GET', url="{url}".format(url=url_redirect), headers=header_idp_page) prepared_request = req_idp_redirect.prepare() logger.debug( json.dumps(prepared_request_to_json(req_idp_redirect), sort_keys=True, indent=4, separators=(',', ': '))) response = s.send(prepared_request, verify=False, allow_redirects=False) logger.debug(response.status_code) keycloak_cookie = response.cookies soup = BeautifulSoup(response.content, 'html.parser') form = soup.body.form url_form = form.get('action') method_form = form.get('method') credentials_data = {} credentials_data["username"] = idp_username credentials_data["password"] = idp_password header_login_keycloak = { **header, 'Host': "{ip}:{port}".format(ip=idp_ip, port=idp_port) } req_login_idp = Request(method=method_form, url="{url}".format(url=url_form), data=credentials_data, cookies=keycloak_cookie, headers=header_login_keycloak) prepared_request = req_login_idp.prepare() logger.debug( json.dumps(prepared_request_to_json(req_login_idp), sort_keys=True, indent=4, separators=(',', ': '))) response = s.send(prepared_request, verify=False, allow_redirects=False) logger.debug(response.status_code) keycloak_cookie2 = response.cookies url_redirect = response.headers['Location'] req_idp_redirect = Request(method='GET', url="{url}".format(url=url_redirect), headers=header_login_keycloak, cookies=keycloak_cookie2) prepared_request = req_idp_redirect.prepare() logger.debug( json.dumps(prepared_request_to_json(req_idp_redirect), sort_keys=True, indent=4, separators=(',', ': '))) response = s.send(prepared_request, verify=False, allow_redirects=False) logger.debug(response.status_code) keycloak_cookie3 = response.cookies url_redirect = response.headers['Location'] req_idp_redirect = Request(method='GET', url="{url}".format(url=url_redirect), headers=header_login_keycloak, cookies=keycloak_cookie3) prepared_request = req_idp_redirect.prepare() logger.debug( json.dumps(prepared_request_to_json(req_idp_redirect), sort_keys=True, indent=4, separators=(',', ': '))) response = s.send(prepared_request, verify=False, allow_redirects=False) logger.debug(response.status_code) return oath_cookie, keycloak_cookie, keycloak_cookie2, response
def access_sp_with_token(s, header, sp_ip, sp_port, idp_scheme, idp_ip, idp_port, method, url, token, session_cookie, keycloak_cookie): # Perform a callback header_callback = { **header, 'Host': "{ip}:{port}".format(ip=sp_ip, port=sp_port), 'Referer': "{scheme}://{ip}:{port}".format(scheme=idp_scheme, ip=idp_ip, port=idp_port), } req_sp_with_response = Request(method=method, url="{url}".format(url=url), data=token, cookies=session_cookie, headers=header_callback) prepared_request = req_sp_with_response.prepare() logger.debug( json.dumps(prepared_request_to_json(req_sp_with_response), sort_keys=True, indent=4, separators=(',', ': '))) response = s.send(prepared_request, verify=False, allow_redirects=False) logger.debug(response.status_code) sp_cookie = response.cookies url_sp = response.headers['Location'] # Browse to the service provider with the saml response header_login_sp = { **header, 'Host': "{ip}:{port}".format(ip=sp_ip, port=sp_port), 'Referer': "{scheme}://{ip}:{port}".format(scheme=idp_scheme, ip=idp_ip, port=idp_port), } req_get_sp_page_final = Request(method='GET', url="{url}".format(url=url_sp), cookies={ **session_cookie, **keycloak_cookie, **response.cookies }, headers=header_login_sp) prepared_request = req_get_sp_page_final.prepare() logger.debug( json.dumps(prepared_request_to_json(req_get_sp_page_final), sort_keys=True, indent=4, separators=(',', ': '))) response = s.send(prepared_request, verify=False) logger.debug(response.status_code) return response, sp_cookie