Unverified Commit 02bbb4bc authored by mvdbeek's avatar mvdbeek
Browse files

Fix display_as with authz_method=rbac

Fixes
https://sentry.galaxyproject.org/share/issue/57576c6c0bfe44c498ccd2bf519deceb/:
```
AttributeError: 'HistoryDatasetAssociation' object has no attribute 'actions'
  File "uvicorn/protocols/http/h11_impl.py", line 366, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "uvicorn/middleware/proxy_headers.py", line 75, in __call__
    return await self.app(scope, receive, send)
  File "fastapi/applications.py", line 269, in __call__
    await super().__call__(scope, receive, send)
  File "starlette/applications.py", line 124, in __call__
    await self.middleware_stack(scope, receive, send)
  File "starlette/middleware/errors.py", line 184, in __call__
    raise exc
  File "starlette/middleware/errors.py", line 162, in __call__
    await self.app(scope, receive, _send)
  File "starlette/middleware/base.py", line 69, in __call__
    await response(scope, receive, send)
  File "starlette/responses.py", line 260, in __call__
    await wrap(partial(self.listen_for_disconnect, receive))
  File "anyio/_backends/_asyncio.py", line 662, in __aexit__
    raise exceptions[0]
  File "starlette/responses.py", line 256, in wrap
    await func()
  File "starlette/responses.py", line 245, in stream_response
    async for chunk in self.body_iterator:
  File "starlette/middleware/base.py", line 58, in body_stream
    raise app_exc
  File "starlette/middleware/base.py", line 36, in coro
    await self.app(scope, request.receive, send_stream.send)
  File "starlette_context/middleware/raw_middleware.py", line 96, in __call__
    await self.app(scope, receive, send_wrapper)
  File "starlette/middleware/base.py", line 69, in __call__
    await response(scope, receive, send)
  File "starlette/responses.py", line 260, in __call__
    await wrap(partial(self.listen_for_disconnect, receive))
  File "anyio/_backends/_asyncio.py", line 662, in __aexit__
    raise exceptions[0]
  File "starlette/responses.py", line 256, in wrap
    await func()
  File "starlette/responses.py", line 245, in stream_response
    async for chunk in self.body_iterator:
  File "starlette/middleware/base.py", line 58, in body_stream
    raise app_exc
  File "starlette/middleware/base.py", line 36, in coro
    await self.app(scope, request.receive, send_stream.send)
  File "starlette/middleware/base.py", line 69, in __call__
    await response(scope, receive, send)
  File "starlette/responses.py", line 260, in __call__
    await wrap(partial(self.listen_for_disconnect, receive))
  File "anyio/_backends/_asyncio.py", line 662, in __aexit__
    raise exceptions[0]
  File "starlette/responses.py", line 256, in wrap
    await func()
  File "starlette/responses.py", line 245, in stream_response
    async for chunk in self.body_iterator:
  File "starlette/middleware/base.py", line 58, in body_stream
    raise app_exc
  File "starlette/middleware/base.py", line 36, in coro
    await self.app(scope, request.receive, send_stream.send)
  File "starlette/exceptions.py", line 93, in __call__
    raise exc
  File "starlette/exceptions.py", line 82, in __call__
    await self.app(scope, receive, sender)
  File "fastapi/middleware/asyncexitstack.py", line 21, in __call__
    raise e
  File "fastapi/middleware/asyncexitstack.py", line 18, in __call__
    await self.app(scope, receive, send)
  File "starlette/routing.py", line 670, in __call__
    await route.handle(scope, receive, send)
  File "starlette/routing.py", line 418, in handle
    await self.app(scope, receive, send)
  File "a2wsgi/wsgi.py", line 140, in __call__
    return await responder(scope, receive, send)
  File "a2wsgi/wsgi.py", line 179, in __call__
    raise self.exc_info[0].with_traceback(
  File "galaxy/web/framework/middleware/error.py", line 165, in __call__
    app_iter = self.application(environ, sr_checker)
  File "/cvmfs/main.galaxyproject.org/venv/lib/python3.8/site-packages/paste/recursive.py", line 85, in __call__
    return self.application(environ, start_response)
  File "galaxy/web/framework/middleware/statsd.py", line 29, in __call__
    req = self.application(environ, start_response)
  File "/cvmfs/main.galaxyproject.org/venv/lib/python3.8/site-packages/paste/httpexceptions.py", line 640, in __call__
    return self.application(environ, start_response)
  File "galaxy/web/framework/base.py", line 159, in __call__
    return self.handle_request(environ, start_response)
  File "galaxy/web/framework/base.py", line 244, in handle_request
    body = method(trans, **kwargs)
  File "galaxy/webapps/galaxy/controllers/root.py", line 111, in display_as
    if authz_method == "rbac" and trans.app.security_agent.can_access_dataset(current_user_roles, data):
  File "galaxy/model/security.py", line 506, in can_access_dataset
    retval = self.dataset_is_public(dataset) or self.allow_action(
  File "galaxy/model/security.py", line 1132, in dataset_is_public
    return self.permitted_actions.DATASET_ACCESS.action not in [a.action for a in dataset.actions]
```
parent 881ed5c7
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -500,7 +500,7 @@ class GalaxyRBACAgent(RBACAgent):
    def item_permission_map_for_add(self, trans, user_roles, libitems):
        return self.allow_action_on_libitems(trans, user_roles, self.permitted_actions.LIBRARY_ADD, libitems)

    def can_access_dataset(self, user_roles, dataset):
    def can_access_dataset(self, user_roles, dataset: galaxy.model.Dataset):
        # SM: dataset_is_public will access dataset.actions, which is a
        # backref that causes a query to be made to DatasetPermissions
        retval = self.dataset_is_public(dataset) or self.allow_action(
@@ -1122,7 +1122,7 @@ class GalaxyRBACAgent(RBACAgent):
            if not dataset.purged and not self.dataset_is_public(dataset):
                self.make_dataset_public(dataset)

    def dataset_is_public(self, dataset):
    def dataset_is_public(self, dataset: galaxy.model.Dataset):
        """
        A dataset is considered public if there are no "access" actions
        associated with it.  Any other actions ( 'manage permissions',
+3 −2
Original line number Diff line number Diff line
@@ -107,8 +107,9 @@ class RootController(controller.JSAppLauncher, UsesAnnotations):
        if "authz_method" in kwd:
            authz_method = kwd["authz_method"]
        if data:
            current_user_roles = trans.get_current_user_roles()
            if authz_method == "rbac" and trans.app.security_agent.can_access_dataset(current_user_roles, data):
            if authz_method == "rbac" and trans.app.security_agent.can_access_dataset(
                trans.get_current_user_roles(), data.dataset
            ):
                trans.response.set_content_type(data.get_mime())
                trans.log_event(f"Formatted dataset id {str(id)} for display at {display_app}")
                return data.as_display_type(display_app, **kwd)