def test_auth_read_secret(self):
     ret = self.run_handler(
         handle_read,
         workflow=Workflow(secret_id="wsecret", public=False),
         workflow_id_or_secret_id="wsecret",
     )
     self.assertHandlerResponse(ret, {"role": "read"})
Exemple #2
0
    def build_request(self, **kwargs):
        request_kwargs = {
            "request_id": kwargs.get("request_id", 1),
            "scope": kwargs.get(
                "scope",
                {
                    "user": kwargs.get("user", AnonymousUser()),
                    "session": kwargs.get("session", Session()),
                    "headers": kwargs.get("headers", ()),
                },
            ),
            "workflow": kwargs.get("workflow", Workflow()),
            "path": kwargs.get("path", "test.path"),
            "arguments": kwargs.get("arguments", {}),
        }
        for key in list(request_kwargs["scope"].keys()) + list(request_kwargs.keys()):
            try:
                del kwargs[key]
            except KeyError:
                pass

        # Turn other params, like `wf_module_id=123`, into
        # `arguments={'wf_module_id':123}`
        request_kwargs["arguments"].update(kwargs)

        return HandlerRequest(**request_kwargs)
Exemple #3
0
 def test_auth_owner_deny_public(self):
     ret = self.run_handler(
         handle_owner, workflow=Workflow(owner=User(), public=True)
     )
     self.assertHandlerResponse(
         ret, error=("AuthError: no owner access to workflow")
     )
    def test_all_arguments_optional(self):
        @decorators.websockets_handler(role="read")
        async def x(**kwargs):
            return {"x": "y"}

        user = User()
        ret = self.run_handler(x, user=user, workflow=Workflow(owner=user))
        self.assertHandlerResponse(ret, {"x": "y"})
    def test_return_something(self):
        @decorators.websockets_handler(role="read")
        async def x(scope, workflow):
            return {"x": "y"}

        user = User()
        ret = self.run_handler(x, user=user, workflow=Workflow(owner=user))
        self.assertHandlerResponse(ret, {"x": "y"})
    def test_catch_handlererror(self):
        @decorators.websockets_handler(role="read")
        async def x(**kwargs):
            raise HandlerError("should not be logged")

        user = User()
        ret = self.run_handler(x, user=user, workflow=Workflow(owner=user))
        self.assertHandlerResponse(ret, error="should not be logged")
Exemple #7
0
 def test_auth_owner_anonymous_owner(self):
     user = AnonymousUser()
     session = Session(session_key="foo")
     workflow = Workflow(anonymous_owner_session_key=session.session_key)
     ret = self.run_handler(
         handle_owner, user=user, session=session, workflow=workflow
     )
     self.assertHandlerResponse(ret, {"role": "owner"})
    def test_catch_any_error(self):
        @decorators.websockets_handler(role="read")
        async def x(**kwargs):
            raise ValueError("bad value")

        user = User()
        with self.assertLogs(level=logging.ERROR):
            ret = self.run_handler(x, user=user, workflow=Workflow(owner=user))
        self.assertHandlerResponse(ret, error="ValueError: bad value")
Exemple #9
0
 def test_auth_role_none(self):
     # Hopefully, the only way to get here is a race:
     #
     # 1. Server receives request and authorizes that the user still has
     #    access to the workflow;
     # 2. Another process revokes access
     # 3. Server invokes handler
     ret = self.run_handler(handle_none, workflow=Workflow(owner=User()))
     self.assertHandlerResponse(ret, {"role": None})
Exemple #10
0
    def test_invalid_arguments(self):
        @decorators.websockets_handler(role="read")
        async def x(scope, workflow, x):
            return None

        user = User()
        ret = self.run_handler(
            x, user=user, workflow=Workflow(owner=user), arguments={"y": 3}
        )
        self.assertHandlerResponse(
            ret, error=("invalid arguments: x() got an unexpected keyword argument 'y'")
        )
Exemple #11
0
    def test_log_requests(self):
        @decorators.websockets_handler(role="read")
        async def x(scope, workflow):
            return {"x": "y"}

        user = User()
        workflow = Workflow(id=1, owner=user)
        request = self.build_request(path="a.path", user=user, workflow=workflow)
        with self.assertLogs(decorators.logger, level=logging.INFO) as cm:
            self.run_with_async_db(x(request))
            self.assertEqual(
                cm.output, ["INFO:server.handlers.decorators:a.path(workflow=1)"]
            )
    def test_passthrough_cancellederror(self):
        """
        CancelledError must be re-raised.

        Async functions may raise CancelledError at any time It must be
        re-raised. There's no way to avoid it. (asyncio.shield() in particular
        is not a way to avoid CancelledError: it's nothing but a waste of time;
        if you don't believe that go and look it up -- proving it.)
        """
        @decorators.websockets_handler(role="read")
        async def x(**kwargs):
            raise asyncio.CancelledError

        user = User()
        with self.assertRaises(asyncio.CancelledError):
            self.run_handler(x, user=user, workflow=Workflow(owner=user))
 def test_auth_owner_owner(self):
     user = User()
     ret = self.run_handler(handle_owner,
                            user=user,
                            workflow=Workflow(owner=user))
     self.assertHandlerResponse(ret, {"role": "owner"})
 def test_auth_write_deny_non_owner(self):
     ret = self.run_handler(handle_write, workflow=Workflow(owner=User()))
     self.assertHandlerResponse(
         ret, error=("AuthError: no write access to workflow"))
 def test_auth_read_public(self):
     ret = self.run_handler(handle_read,
                            workflow=Workflow(owner=User(), public=True))
     self.assertHandlerResponse(ret, {"role": "read"})

@decorators.websockets_handler(role="write")
async def handle_write(workflow, **kwargs):
    return {"role": "write"}


@decorators.websockets_handler(role="owner")
async def handle_owner(workflow, **kwargs):
    return {"role": "owner"}


DefaultKwargs = {
    "user": AnonymousUser(),
    "session": Session(),
    "workflow": Workflow(),
    "path": "path",
    "arguments": {},
}


class WebsocketsHandlerDecoratorTest(HandlerTestCase):
    def handle(self, **kwargs):
        """handlers.handle(), synchronous."""
        request = self.build_request(**kwargs)
        return async_to_sync(handlers.handle)(request)

    def assertHandlerResponse(self, response, data=None, error=""):
        self.assertEqual(
            {
                "data": response.data,