def test_nodestination_given(self): '''This test case ensures redirect response can not be instantiated without a valid destination.''' with self.assertRaises(TypeError): RedirectResponse() for destination in [None, "", " "]: with self.assertRaises(FantasticoError): RedirectResponse(destination)
def test_redirect_response_simple(self): '''This test case ensures simple redirects work as expected (no query params appended).''' response = RedirectResponse(destination="http://www.google.ro") self.assertIsInstance(response, Response) self.assertEqual(302, response.status_code) self.assertEqual("http://www.google.ro", response.headers["Location"]) self.assertTrue( response.headers["Content-Type"].find("text/html") > -1)
def handle_grant(self, request): '''This method provides the algorithm for implementing implicit grant type handler. Internally it will use TokensService in order to generate a new access token. In addition, if redirect query parameter is set to false then a 200 OK response with Location header and no body is sent to the client.''' client_id = self._validate_missing_param(request, "client_id") redirect_uri = self._validate_missing_param(request, "redirect_uri") state = self._validate_missing_param(request, "state") error_redirect = self._get_error_redirect(request, redirect_uri, state) if error_redirect: return error_redirect scopes = self._validate_missing_param(request, "scope") invalid_redirect = self._validate_redirect_uri(redirect_uri) if invalid_redirect: return invalid_redirect encrypted_login = request.params.get("login_token") if not encrypted_login: return self._redirect_to_idp(request) login_token = self._tokens_service.decrypt(encrypted_login) self._tokens_service.validate(login_token) access_token = self._tokens_service.generate( { "client_id": client_id, "user_id": login_token.user_id, "scopes": scopes, "expires_in": self._expires_in }, TokenGeneratorFactory.ACCESS_TOKEN) encrypted_access = self._tokens_service.encrypt( access_token, client_id) prefix_sign = "#" if redirect_uri.find("#") > -1: prefix_sign = "&" return_url = "%s%saccess_token=%s&state=%s&token_type=%s&expires_in=%s&scope=%s" % \ (redirect_uri, prefix_sign, encrypted_access, urllib.parse.quote(state), access_token.type, self._expires_in, urllib.parse.quote(scopes)) is_redirect = int(request.params.get("redirect") or 1) if is_redirect == 1: return RedirectResponse(return_url) response = Response(body=b"") response.headers["Location"] = return_url return response
def test_handle_missing_login(self): '''This test case ensures a redirect response to idp is received if login_token query parameter is missing.''' request_url = "/oauth/authorize?response_type=token&state=xyz&error_format=hash&client_id=11111111-1111-1111-1111-111111111111&scope=scope1&redirect_uri=%2Fexample%2Fcb" expected_url = "%s?redirect_uri=%s" % (self._oauth2_idp["idp_index"], urllib.parse.quote(request_url)) request = Request.blank(request_url) request.redirect = lambda url: RedirectResponse(url) response = self._handler.handle_grant(request) self.assertIsInstance(response, RedirectResponse) self.assertEqual(expected_url, response.headers["Location"])
def test_redirect_response_with_params(self): '''This test case ensures a redirect response with query params correctly builds destination.''' query_params = [("q", "where can I find a restaurant"), ("sourceid", "chrome")] response = RedirectResponse(destination="http://www.google.ro/search", query_params=query_params) self.assertIsInstance(response, Response) self.assertEqual(302, response.status_code) self.assertEqual( "http://www.google.ro/search?q=where can I find a restaurant&sourceid=chrome", response.headers["Location"]) self.assertTrue( response.headers["Content-Type"].find("text/html") > -1)
def _get_error_redirect(self, request, redirect_uri, state): '''This method builds an error redirect response if the request has query parameters indicating error case.''' error = request.params.get("error") if not error: return error_description = request.params.get("error_description", "") error_uri = request.params.get("error_uri") redirect_uri = self._exception_formatter.format_ex( { "error": error, "error_description": error_description, "error_uri": error_uri, "state": state }, ctx={"redirect_uri": redirect_uri}) return RedirectResponse(redirect_uri)
def _mock_authenticate_dependencies(self, token, user, return_url): '''This method mocks authenticate dependencies and returns them as a tuple object.''' if return_url: return_url_base = return_url if return_url_base.find("?") > -1: return_url_base = return_url_base[:return_url_base.find("?")] clienturl_facade = Mock() if return_url: clienturl_facade.get_records_paged = Mock( return_value=[return_url_base]) clienturl_facade.session = Mock() request = Mock() request.params = { "username": user.username, "password": user.password, self._idp_controller.REDIRECT_PARAM: return_url } request.models = Mock() request.models.ClientReturnUrl = clienturl_facade request.redirect = lambda destination: RedirectResponse(destination) user_repo = Mock() user_repo.load_by_username = Mock(return_value=user) user_repo_cls = Mock(return_value=user_repo) self._hasher.hash_password = Mock(return_value="12345") tokens_service = Mock() tokens_service_cls = Mock(return_value=tokens_service) tokens_service.generate = Mock(return_value=token) tokens_service.encrypt = Mock(return_value="123") return (request, user_repo_cls, user_repo, tokens_service_cls, tokens_service, clienturl_facade)
def _build_response(self, environ, body, http_code): '''This method builds transforms the given body into a wsgi response object.''' curr_request = environ["fantastico.request"] redirect_uri = curr_request.params.get("redirect_uri") ex_format = curr_request.params.get("error_format", ExceptionFormattersFactory.JSON) ex_formatter = self._exceptions_factory.get_formatter(ex_format) response = ex_formatter.format_ex(body, ctx={"redirect_uri": redirect_uri}) if ex_format == ExceptionFormattersFactory.JSON: response = Response(body=json.dumps(response).encode(), content_type="application/json; charset=UTF-8", status=http_code) self._add_cors_headers(response) return response response = RedirectResponse(response) self._add_cors_headers(response) return response
def _redirect(self, destination, query_params=None): '''This method is used to build a redirect response base on the given arguments.''' return RedirectResponse(destination=destination, query_params=query_params)