From daa0f522825a7a4932242579adb8ac337ad34e5f Mon Sep 17 00:00:00 2001 From: Zoheb Shaikh <26975142+ZohebShaikh@users.noreply.github.com> Date: Tue, 3 Feb 2026 10:53:55 +0000 Subject: [PATCH] feat: update tiled policy --- policy/diamond/policy/tiled/tiled.rego | 64 ++++++++++++++++++--- policy/diamond/policy/tiled/tiled_test.rego | 53 +++++++++-------- 2 files changed, 86 insertions(+), 31 deletions(-) diff --git a/policy/diamond/policy/tiled/tiled.rego b/policy/diamond/policy/tiled/tiled.rego index 3c94495..be7574d 100644 --- a/policy/diamond/policy/tiled/tiled.rego +++ b/policy/diamond/policy/tiled/tiled.rego @@ -1,5 +1,6 @@ package diamond.policy.tiled +import data.diamond.policy.admin import data.diamond.policy.session import data.diamond.policy.token import rego.v1 @@ -30,15 +31,64 @@ scopes_for(claims) := read_scopes if { not "azp" in object.keys(claims) } +# Assign read & write scopes to blueapi clients +# defaults to read-only scopes default scopes := set() scopes := scopes_for(token.claims) -user_sessions contains user_session if { - some i in data.diamond.data.sessions - session.access_session(token.claims.fedid, i.proposal_number, i.visit_number) - user_session := sprintf( - `{"proposal": %d, "visit": %d, "beamline": "%s"}`, - [i.proposal_number, i.visit_number, i.beamline], - ) +# Returns the session ID if the subject has write permissions for the +# specific beamline, visit and proposal requested in the input. +user_session := to_number(value) if { + session.write_to_beamline_visit + value := data.diamond.data.proposals[format_int(input.proposal, 10)].sessions[format_int(input.visit, 10)] +} + +# Validates if the subject has permission to modify +# the specific session in the input. +default modify_session := false + +modify_session := session.access_session( + token.claims.fedid, + data.diamond.data.sessions[input.session].proposal_number, + data.diamond.data.sessions[input.session].visit_number, +) + +subject := data.diamond.data.subjects[token.claims.fedid] + +# Identifies all beamlines the subject is authorized to access +# based on their assigned permissions. +beamlines contains beamline if { + not admin.is_admin(token.claims.fedid) + some p in subject.permissions + some beamline in object.get(data.diamond.data.admin, p, []) +} + +# Aggregates all session IDs the subject is authorized to view. +# Admins receive a wildcard "*" granting access to all sessions. + +# Regular users gain session access through three pathways: +# 1. Direct session membership +# 2. Access via beamline-level permissions +# 3. Access via proposal-level permissions +user_sessions contains "*" if { + admin.is_admin(token.claims.fedid) +} + +user_sessions contains to_number(session) if { + not admin.is_admin(token.claims.fedid) + some session in subject.sessions +} + +user_sessions contains to_number(session) if { + not admin.is_admin(token.claims.fedid) + some beamline in beamlines + some session in data.diamond.data.beamlines[beamline].sessions +} + +user_sessions contains to_number(session) if { + not admin.is_admin(token.claims.fedid) + some p in subject.proposals + some i in data.diamond.data.proposals[format_int(p, 10)] + some session in i } diff --git a/policy/diamond/policy/tiled/tiled_test.rego b/policy/diamond/policy/tiled/tiled_test.rego index 14a4666..d7188ec 100644 --- a/policy/diamond/policy/tiled/tiled_test.rego +++ b/policy/diamond/policy/tiled/tiled_test.rego @@ -96,33 +96,38 @@ diamond_data := { test_user_session_tags if { tiled.user_sessions == set() with data.diamond.data as diamond_data with data.diamond.policy.token.claims as {"fedid": "oscar"} - tiled.user_sessions == { - `{"proposal": 1, "visit": 2, "beamline": "b07"}`, - `{"proposal": 1, "visit": 1, "beamline": "i03"}`, - } with data.diamond.data as diamond_data + tiled.user_sessions == {11, 12} with data.diamond.data as diamond_data with data.diamond.policy.token.claims as {"fedid": "alice"} - tiled.user_sessions == { - `{"proposal": 1, "visit": 2, "beamline": "b07"}`, - `{"proposal": 1, "visit": 1, "beamline": "i03"}`, - `{"proposal": 2, "visit": 1, "beamline": "b07"}`, - `{"proposal": 2, "visit": 2, "beamline": "b07"}`, - } with data.diamond.data as diamond_data + tiled.user_sessions == {11, 12, 13, 14} with data.diamond.data as diamond_data with data.diamond.policy.token.claims as {"fedid": "bob"} - tiled.user_sessions == { - `{"proposal": 1, "visit": 2, "beamline": "b07"}`, - `{"proposal": 1, "visit": 1, "beamline": "i03"}`, - `{"proposal": 2, "visit": 1, "beamline": "b07"}`, - `{"proposal": 2, "visit": 2, "beamline": "b07"}`, - } with data.diamond.data as diamond_data + tiled.user_sessions == {"*"} with data.diamond.data as diamond_data with data.diamond.policy.token.claims as {"fedid": "carol"} - tiled.user_sessions == { - `{"proposal": 2, "visit": 1, "beamline": "b07"}`, - `{"proposal": 2, "visit": 2, "beamline": "b07"}`, - } with data.diamond.data as diamond_data + tiled.user_sessions == {13, 14} with data.diamond.data as diamond_data with data.diamond.policy.token.claims as {"fedid": "desmond"} - tiled.user_sessions == { - `{"proposal": 2, "visit": 1, "beamline": "b07"}`, - `{"proposal": 2, "visit": 2, "beamline": "b07"}`, - } with data.diamond.data as diamond_data + tiled.user_sessions == {13, 14} with data.diamond.data as diamond_data with data.diamond.policy.token.claims as {"fedid": "edna"} } + +test_user_session_allow if { + tiled.user_session == 11 with data.diamond.data as diamond_data + with input as {"beamline": "i03", "proposal": 1, "visit": 1} + with data.diamond.policy.token.claims as {"fedid": "carol"} +} + +test_user_session_not_allowed if { + not tiled.user_session with data.diamond.data as diamond_data + with input as {"beamline": "i03", "proposal": 1, "visit": 1} + with data.diamond.policy.token.claims as {"fedid": "oscar"} +} + +test_not_modify_session if { + not tiled.modify_session with data.diamond.data as diamond_data + with input as {"session": "13"} + with data.diamond.policy.token.claims as {"fedid": "alice"} +} + +test_modify_session if { + tiled.modify_session with data.diamond.data as diamond_data + with input as {"session": "11"} + with data.diamond.policy.token.claims as {"fedid": "alice"} +}