about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--gn_auth/auth/authorisation/data/views.py99
1 files changed, 62 insertions, 37 deletions
diff --git a/gn_auth/auth/authorisation/data/views.py b/gn_auth/auth/authorisation/data/views.py
index 584b239..228d95f 100644
--- a/gn_auth/auth/authorisation/data/views.py
+++ b/gn_auth/auth/authorisation/data/views.py
@@ -104,10 +104,22 @@ def authorisation() -> Response:
                         authconn, _dset_traits["ProbeSet"]))
             for _rrow in _rtypes
         }
-        if len(_all_resources.keys()) == 0:
+        if (len(_all_resources.keys()) == 0 and
+                len(_dset_traits.get("Temp", tuple())) == 0):
             raise NotFoundError(
                 "No resource(s) found for specified trait(s). Do(es) the "
                 "trait(s) actually exist?")
+
+        # Handle Temp traits specially - they should be public/anonymous resources
+        if len(_dset_traits.get("Temp", tuple())) > 0:
+            # Create a synthetic public resource for Temp traits
+            # Use a predictable ID to identify synthetic temp resources
+            temp_resource_id = "gn-auth-temp-traits"
+            _all_resources[temp_resource_id] = {
+                "resource_id": temp_resource_id,
+                "resource_data": tuple(f"{dset}::{trait}" for dset, trait in _dset_traits["Temp"])
+            }
+
         _resource_ids = tuple(_all_resources.keys())
 
 
@@ -125,42 +137,55 @@ def authorisation() -> Response:
             }
 
         _paramstr = ", ".join(["?"] * len(_resource_ids))
-        try:
-            with require_oauth.acquire("profile group resource") as _token:
-                user = _token.user
-                cursor.execute(
-                    "SELECT ur.resource_id, r.role_id, rp.privilege_id "
-                    "FROM user_roles AS ur "
-                    "INNER JOIN roles AS r ON ur.role_id=r.role_id "
-                    "INNER JOIN role_privileges AS rp ON r.role_id=rp.role_id "
-                    "WHERE ur.user_id = ? "
-                    f"AND ur.resource_id IN ({_paramstr})",
-                    (str(user.user_id),) + _resource_ids
-                )
-                _privileges_by_resource: dict[str, tuple[str, ...]] = reduce(
-                    lambda acc, curr: {
-                        **acc,
-                        curr["resource_id"]: (
-                            acc.get(curr["resource_id"], tuple())
-                            + (curr["privilege_id"],))
-                    },
-                    cursor.fetchall(),
-                    {})
-        except _HTTPException as exc:
-            err_msg = json.loads(exc.body)
-            if err_msg["error"] == "missing_authorization":
-                cursor.execute(
-                    "SELECT rsc.resource_id "
-                    "FROM resources AS rsc "
-                    "WHERE rsc.public = '1' "
-                    f"AND rsc.resource_id IN ({_paramstr}) ",
-                    _resource_ids)
-                _privileges_by_resource = {
-                    row["resource_id"]: ('group:resource:view-resource',)
-                    for row in cursor.fetchall()
-                }
-            else:
-                raise exc from None
+        _privileges_by_resource: dict[str, tuple[str, ...]] = {}
+
+        # Separate synthetic temp resources from real resources
+        temp_resource_id = "gn-auth-temp-traits"
+        real_resource_ids = tuple(rid for rid in _resource_ids if rid != temp_resource_id)
+
+        # Query privileges only for real resources
+        if len(real_resource_ids) > 0:
+            real_paramstr = ", ".join(["?"] * len(real_resource_ids))
+            try:
+                with require_oauth.acquire("profile group resource") as _token:
+                    user = _token.user
+                    cursor.execute(
+                        "SELECT ur.resource_id, r.role_id, rp.privilege_id "
+                        "FROM user_roles AS ur "
+                        "INNER JOIN roles AS r ON ur.role_id=r.role_id "
+                        "INNER JOIN role_privileges AS rp ON r.role_id=rp.role_id "
+                        "WHERE ur.user_id = ? "
+                        f"AND ur.resource_id IN ({real_paramstr})",
+                        (str(user.user_id),) + real_resource_ids
+                    )
+                    _privileges_by_resource = reduce(
+                        lambda acc, curr: {
+                            **acc,
+                            curr["resource_id"]: (
+                                acc.get(curr["resource_id"], tuple())
+                                + (curr["privilege_id"],))
+                        },
+                        cursor.fetchall(),
+                        {})
+            except _HTTPException as exc:
+                err_msg = json.loads(exc.body)
+                if err_msg["error"] == "missing_authorization":
+                    cursor.execute(
+                        "SELECT rsc.resource_id "
+                        "FROM resources AS rsc "
+                        "WHERE rsc.public = '1' "
+                        f"AND rsc.resource_id IN ({real_paramstr}) ",
+                        real_resource_ids)
+                    _privileges_by_resource = {
+                        row["resource_id"]: ('group:resource:view-resource',)
+                        for row in cursor.fetchall()
+                    }
+                else:
+                    raise exc from None
+
+        # Temp resources are always publicly viewable
+        if temp_resource_id in _resource_ids:
+            _privileges_by_resource[temp_resource_id] = ('group:resource:view-resource',)
 
         return jsonify({
             "authorisation": [{