def test_show_login_ok(self):
        """This test case ensures login screen is displayed correctly when all required parameters are passed."""

        redirect_param_name = self._idp_controller.REDIRECT_PARAM

        request = Mock()
        request.params = {redirect_param_name: "/simple/test"}

        self._idp_controller.load_template = Mock(return_value="cool result")

        response = self._idp_controller.show_login(request)

        self.assertIsNotNone(response)
        self.assertEqual(200, response.status_code)

        self.assertIsNotNone(response.body)
        body = response.body.decode()

        self.assertEqual("cool result", body)

        self._idp_controller.load_template.assert_called_once_with(
            self._TPL_LOGIN,
            {redirect_param_name: urllib.parse.quote(request.params[redirect_param_name])},
            enable_global_folder=True,
        )
    def _test_authorize_template(self, response_type="supported_grant", factory_ex=None, handler_ex=None):
        """This method provides a template method for testing handle_authorize method from oauth2 controller."""

        expected_response = Mock()

        client_facade = Mock()
        client_facade.session = Mock()

        request = Mock()
        request.params = {"response_type": response_type}

        request.models = Mock()
        request.models.Client = client_facade

        grant_handler = Mock()

        if not handler_ex:
            grant_handler.handle_grant = Mock(return_value=expected_response)
        else:
            grant_handler.handle_grant = Mock(side_effect=handler_ex)

        if not factory_ex:
            self._handlers_factory.get_handler = Mock(return_value=grant_handler)
        else:
            self._handlers_factory.get_handler = Mock(side_effect=factory_ex)

        response = self._oauth2_controller.handle_authorize(request)

        self.assertEqual(expected_response, response)

        self._handlers_factory.get_handler.assert_called_once_with("supported_grant", client_facade.session)
        grant_handler.handle_grant.assert_called_once_with(request)
    def test_error_redirect(self):
        """This test case ensures a redirect response is sent if the implicit handler request contains error query parameter.
        This case occurs only when authentication fails."""

        request = Mock()
        request.params = {
            "client_id": "sample-app",
            "redirect_uri": "/sample/cb",
            "state": "xyz",
            "error": "access_denied",
            "error_description": "Simple error.",
            "error_uri": "/sample/uri/122.html",
        }

        response = self._handler.handle_grant(request)

        self.assertIsInstance(response, RedirectResponse)

        expected_redirect = "%s#error=%s&error_description=%s&error_uri=%s&state=%s" % (
            request.params["redirect_uri"],
            request.params["error"],
            urllib.parse.quote(request.params["error_description"]),
            urllib.parse.quote(request.params["error_uri"]),
            request.params["state"],
        )

        self.assertEqual(expected_redirect, response.headers["Location"])
Example #4
0
    def test_3login_flow(self):
        ver_code_of_last_user, last_uid = DBSession.query(User.ver_code, User.id).all()[-1]
        self.assert_(ver_code_of_last_user, "Wrong order of tests")
        req = DummyRequest(
            path="linkedin_confirm/%s" % ver_code_of_last_user,
            matchdict={"code": ver_code_of_last_user},
            user=self.founder,
        )
        auth_uids = []
        confirm_acc.remember = lambda x, y: auth_uids.append(y)
        ret = confirm_acc.linkedin_confirm_view(req)
        self.assert_(last_uid in auth_uids, "User should be logged in")
        self.assert_(isinstance(ret, HTTPFound), "Should redirect to linkedin")

        # now test the linkedin return but mock out all the linkedin credential checks
        req2 = Mock()
        req2.params = {"code": "test"}
        req2.authenticated_userid = last_uid
        login.get_oauth_flow_linkedin = Mock()
        login.requests = Mock()
        linkedin_user_resp = Mock()
        linkedin_email = "testing2linkeding@f.com"
        linkedin_user_resp.json = {"id": "dummyLinkedinID", "emailAddress": linkedin_email}
        login.requests.get = lambda *x, **k: linkedin_user_resp
        login.check_csrf_token = Mock()
        # end of mocks

        self.assert_(self.get_linkedin_email_db(last_uid) != linkedin_email, "Linkedin email should not be set yet")
        ret = login.oauthcallback_view(req2)
        # oauth callback view calls complete_confirm_acc
        self.assert_(isinstance(ret, HTTPFound), "Should redirect to profile")
        self.assert_(
            self.get_linkedin_email_db(last_uid) == linkedin_email,
            "Linkedin email should be set by complete_confirm_acc",
        )
Example #5
0
    def test_raises_csrf_error_with_wrong_request_param(self):
        """Requests must have the right ``_csrf``."""

        from ..csrf import CSRFError

        mock_request = Mock()
        mock_request.method = "a"
        mock_request.params = {"_csrf": "wrong"}

        validator = self.makeOne("token", target_methods=["a"])
        self.assertRaises(CSRFError, validator.validate, mock_request)
Example #6
0
    def test_validates_with_correct_request_param(self):
        """Requests validate OK when they have the correct ``_csrf``."""

        from ..csrf import CSRFError

        mock_request = Mock()
        mock_request.method = "a"
        mock_request.params = {"_csrf": "token"}

        validator = self.makeOne("token", target_methods=["a"])
        retval = validator.validate(mock_request)
        self.assertTrue(retval is None)
    def test_show_login_missingreturn(self):
        """This test case ensures login screen is not displayed if return_url query parameter is not provided."""

        request = Mock()
        request.params = {}

        for return_url in [None, "", "    "]:
            request.params[self._idp_controller.REDIRECT_PARAM] = return_url

            with self.assertRaises(OAuth2MissingQueryParamError) as ctx:
                self._idp_controller.show_login(request)

            self.assertEqual(self._idp_controller.REDIRECT_PARAM, ctx.exception.param_name)
Example #8
0
    def test_xmlhttprequests_headers(self):
        """``X-CSRFToken`` will be overriden by ``_csrf``."""

        from ..csrf import CSRFError

        mock_request = Mock()
        mock_request.method = "A"
        mock_request.headers = {"X-Requested-With": "XMLHttpRequest", "X-CSRFToken": "wrong"}
        validator = self.makeOne("token", target_methods=["a"])
        self.assertRaises(CSRFError, validator.validate, mock_request)

        mock_request.params = {"_csrf": "token"}
        validator = self.makeOne("token", target_methods=["a"])
        retval = validator.validate(mock_request)
        self.assertTrue(retval is None)
    def test_get_item_ok(self):
        """This test case ensures an item can be correctly retrieved from collection."""

        self._controller.validate_security_context = Mock(return_value=None)

        url = "/simple-resources"
        version = "1.0"
        fields = "id,name,description"

        model = Mock()

        resource = Resource(name="Mock Simple Resource", url=url, version=float(version))
        resource(MockSimpleResourceRoa, self._resources_registry)

        request = Mock()
        request.params = {"fields": fields}

        resource_id = 1986

        expected_body = {"id": resource_id, "name": "Test resource", "description": "Simple description."}

        self._resources_registry.find_by_url = Mock(return_value=resource)

        self._model_facade.model_pk_cols = [MockSimpleResourceRoa.id]
        self._model_facade.find_by_pk = Mock(return_value=model)

        self._json_serializer.serialize = Mock(return_value=expected_body)

        response = self._controller.get_item(request, version, url, resource_id)

        self.assertIsNotNone(response)
        self.assertEqual(200, response.status_code)
        self.assertEqual("application/json", response.content_type)
        self._assert_cors_headers(response)

        self.assertIsNotNone(response.body)
        body = json.loads(response.body.decode())

        self.assertEqual(expected_body, body)

        self._resources_registry.find_by_url.assert_called_once_with(url, float(version))
        self._model_facade.find_by_pk.assert_called_once_with({MockSimpleResourceRoa.id: resource_id})
        self._json_serializer_cls.assert_called_once_with(resource)
        self._json_serializer.serialize(model, fields)
        self._controller.validate_security_context.assert_called_once_with(request, "read")
    def test_handle_grant_invalidredirect(self):
        """This test case ensures an exception is raised if the given redirect uri is not supported by the current client."""

        client_id = "abcd"
        redirect_uri = "/abcduri"

        request = Mock()
        request.params = {"client_id": client_id, "redirect_uri": redirect_uri, "state": "xyz", "scope": "a b c"}

        self._client_repo.load_client_by_returnurl = Mock(return_value=None)

        response = self._handler.handle_grant(request)

        self.assertIsNotNone(response)
        self.assertEqual(401, response.status_code)
        self.assertTrue(response.body.decode().find(redirect_uri) > -1)

        self._client_repo.load_client_by_returnurl.assert_called_once_with(redirect_uri)
    def test_get_collection_resource_notfound(self):
        """This test case ensures 404 is returned if we try to access a resource which does not exist."""

        url = "/resource-not-found"
        version = "1.0"

        request = Mock()
        request.params = {}

        self._settings_facade.get = Mock(return_value=self._doc_base)

        self._resources_registry.find_by_url = Mock(return_value=None)

        response = self._controller.get_collection(request, version, url)

        self._assert_resource_error(response, 404, 10000, version, url)

        self._resources_registry.find_by_url.assert_called_once_with(url, float(version))
    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 _test_exception_json(self, ex):
        """This method provides a template test case for ensuring invalid request error response is correctly built."""

        request = Mock()
        request.params = {}

        environ = {"fantastico.request": request}
        start_response = Mock()
        app = Mock(side_effect=ex)
        middleware = OAuth2ExceptionsMiddleware(app, settings_facade_cls=self._mock_settings_facade())

        body = middleware(environ, start_response)

        self.assertIsNotNone(body)

        content_length = len(body[0])
        body = json.loads(body[0].decode())

        app.assert_called_once_with(environ, start_response)

        http_code = ex.http_code

        if http_code >= 500:
            http_code = 400

        http_code = "%s %s" % (http_code, status_reasons[http_code])
        start_response.assert_called_once_with(
            http_code,
            [
                ("Content-Type", "application/json; charset=UTF-8"),
                ("Content-Length", str(content_length)),
                ("Access-Control-Allow-Origin", "*"),
                ("Access-Control-Allow-Methods", "OPTIONS,GET,POST,PUT,DELETE"),
            ],
        )

        return body
    def _test_exception_form(self, ex, error, description, uri, return_url, expected_url=None):
        """This method provides a test case template for application/x-www-form-urlencoded exception handling."""

        if not expected_url:
            expected_url = "%s&error=%s&error_description=%s&error_uri=%s" % (
                return_url,
                error,
                description,
                urllib.parse.quote(uri),
            )

        request = Mock()
        request.params = {"error_format": ExceptionFormattersFactory.HASH, "redirect_uri": return_url}

        environ = {"fantastico.request": request}
        start_response = Mock()
        app = Mock(side_effect=ex)
        middleware = OAuth2ExceptionsMiddleware(app, settings_facade_cls=self._mock_settings_facade())

        body = middleware(environ, start_response)

        self.assertIsNotNone(body)
        self.assertEqual(b"", body[0])

        app.assert_called_once_with(environ, start_response)

        start_response.assert_called_once_with(
            "302 Found",
            [
                ("Location", expected_url),
                ("Content-Type", "text/html"),
                ("Content-Length", "0"),
                ("Access-Control-Allow-Origin", "*"),
                ("Access-Control-Allow-Methods", "OPTIONS,GET,POST,PUT,DELETE"),
            ],
        )
    def test_get_collection_default_values_emptyresult(self):
        """This test case ensures get collection works as expected without any query parameters passed. It ensures
        empty items returns correct """

        self._controller.validate_security_context = Mock(return_value=None)

        expected_records = []
        expected_records_count = 0

        version = "1.0"
        resource_url = "/sample-resources"

        request = Mock()
        request.params = {}

        resource = Mock()
        resource.user_dependent = False
        resource.model = Mock()

        self._mock_model_facade(records=expected_records, records_count=expected_records_count)

        self._resources_registry.find_by_url = Mock(return_value=resource)

        response = self._controller.get_collection(request, version, resource_url)

        self._assert_get_collection_response(
            request,
            response,
            records=expected_records,
            records_count=expected_records_count,
            offset=self._controller.OFFSET_DEFAULT,
            limit=self._controller.LIMIT_DEFAULT,
        )

        self._resources_registry.find_by_url.assert_called_once_with(resource_url, float(version))
        self._json_serializer_cls.assert_called_once_with(resource)
    def test_get_collection_first_page(self):
        """This test case ensures get collection can return first page populated with items. In addition it ensures
        filtering and sorting is supported."""

        self._controller.validate_security_context = Mock(return_value=None)

        expected_fields = "name,description"
        expected_records = [{"name": "Resource 1", "description": ""}, {"name": "Resource 2", "description": ""}]
        expected_records_count = 3
        expected_filter = Mock()
        expected_sort = Mock()

        version = "latest"
        resource_url = "/sample-resources"

        request = Mock()
        request.params = {
            "offset": "0",
            "limit": "2",
            "filter": 'like(name, "resource 1")',
            "order": "asc(name)",
            "fields": expected_fields,
        }

        resource = Mock()
        resource.user_dependent = False
        resource.model = Mock()

        self._query_parser.parse_filter = Mock(return_value=expected_filter)
        self._query_parser.parse_sort = Mock(return_value=expected_sort)

        self._mock_model_facade(records=expected_records, records_count=expected_records_count)
        self._model_facade.get_records_paged = Mock(return_value=expected_records)
        self._model_facade.count_records = Mock(return_value=expected_records_count)

        self._resources_registry.find_by_url = Mock(return_value=resource)

        def mock_serialize(model, fields):
            self.assertEqual(expected_fields, fields)

            return model

        self._json_serializer.serialize = mock_serialize

        response = self._controller.get_collection(request, version, resource_url)

        self._assert_get_collection_response(
            request,
            response,
            records=expected_records,
            records_count=expected_records_count,
            offset=0,
            limit=2,
            expected_filter=expected_filter,
            expected_sort=expected_sort,
        )

        self._resources_registry.find_by_url.assert_called_once_with(resource_url, version)
        self._json_serializer_cls.assert_called_once_with(resource)
        self._query_parser.parse_filter.assert_called_once_with(request.params["filter"], resource.model)
        self._query_parser.parse_sort.assert_called_once_with([request.params["order"]], resource.model)
    def _test_handle_template(
        self,
        client_id,
        redirect_uri,
        scope,
        state,
        encrypted_login,
        expected_redirect=None,
        encrypted_access=None,
        redirect_qparam=None,
    ):
        """This method provides a template for testing handle_grant method from implicit grant provider."""

        if not encrypted_access:
            encrypted_access = "encrypted access token"

        if not expected_redirect:
            scope = scope or ""
            state = state or ""
            expected_redirect = "%s#access_token=%s&state=%s&token_type=access&expires_in=%s&scope=%s" % (
                redirect_uri,
                encrypted_access,
                urllib.parse.quote(state),
                self._EXPIRES_IN,
                urllib.parse.quote(scope),
            )

        login_token = Token({"user_id": 1})

        access_token = Token({"type": "access"})

        request = Mock()
        request.params = {
            "client_id": client_id,
            "redirect_uri": redirect_uri,
            "scope": scope,
            "state": state,
            "login_token": encrypted_login,
            "redirect": redirect_qparam,
        }

        self._tokens_service.decrypt = Mock(return_value=login_token)
        self._tokens_service.generate = Mock(return_value=access_token)
        self._tokens_service.encrypt = Mock(return_value=encrypted_access)

        response = self._handler.handle_grant(request)

        if not redirect_qparam:
            self.assertIsInstance(response, RedirectResponse)
        else:
            self.assertIsInstance(response, Response)

        self.assertEqual(expected_redirect, response.headers.get("Location"))

        self._tokens_service.decrypt.assert_called_once_with(encrypted_login)
        self._tokens_service.validate.assert_called_once_with(login_token)
        self._tokens_service.generate.assert_called_once_with(
            {"client_id": client_id, "user_id": login_token.user_id, "scopes": scope, "expires_in": self._EXPIRES_IN},
            TokenGeneratorFactory.ACCESS_TOKEN,
        )
        self._tokens_service.encrypt.assert_called_once_with(access_token, client_id)