Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions policy/diamond/policy/blueapi/blueapi.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package diamond.policy.blueapi

import data.diamond.policy.admin
import data.diamond.policy.session
import data.diamond.policy.token

import rego.v1

_session := data.diamond.data.proposals[format_int(input.proposal, 10)].sessions[format_int(input.visit, 10)]

# Returns the session ID if the subject has write permissions for the
# specific beamline, visit and proposal requested in the input.
user_session := format_int(_session, 10) if {
session.write_to_beamline_visit
_session
}

# Check if user should be able to submit tasks only if they're on
# the same instrument as the instrument session in question.

default post_task := false

post_task if {
session.write_to_beamline_visit
}

default delete_task := false

delete_task if {
data.diamond.data.tasks[input.task_id].created_by == token.claims.fedid
}

delete_task if {
admin.is_admin(token.claims.fedid)
}

default fetch_task := false

fetch_task if {
data.diamond.data.tasks[input.task_id].created_by == token.claims.fedid
}

fetch_task if {
admin.is_admin(token.claims.fedid)
}

fetch_tasks contains task_ids if {
some task_ids
data.diamond.data.tasks[task_ids].created_by == token.claims.fedid
}

fetch_tasks contains task_ids if {
admin.is_admin(token.claims.fedid)
some task_ids, _ in data.diamond.data.tasks
}

default put_worker_state_abort := false

put_worker_state_abort if {
data.diamond.data.tasks[input.task_id].created_by == token.claims.fedid
}

put_worker_state_abort if {
admin.is_admin(token.claims.fedid)
}
184 changes: 184 additions & 0 deletions policy/diamond/policy/blueapi/blueapi_test.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package diamond.policy.blueapi_test

import data.diamond.policy.blueapi
import rego.v1

diamond_data := {
"subjects": {
"alice": {
"permissions": [],
"proposals": [1],
"sessions": [],
},
"bob": {
"permissions": ["b07_admin"],
"proposals": [],
"sessions": [11],
},
"carol": {
"permissions": ["super_admin"],
"proposals": [],
"sessions": [],
},
"oscar": {
"permissions": [],
"proposals": [],
"sessions": [],
},
},
"sessions": {
"11": {
"beamline": "i03",
"proposal_number": 1,
"visit_number": 1,
},
"12": {
"beamline": "b07",
"proposal_number": 1,
"visit_number": 2,
},
},
"proposals": {"1": {"sessions": {
"1": 11,
"2": 12,
}}},
"tasks": {
"1": {
"task_id": "1",
"created_by": "alice",
"session_id": "456",
},
"2": {
"task_id": "2",
"created_by": "bob",
"session_id": "457",
},
"3": {
"task_id": "3",
"created_by": "oscar",
"session_id": "458",
},
"4": {
"task_id": "4",
"created_by": "oscar",
"session_id": "459",
},
},
"beamlines": {"i03": {"sessions": [11]}, "b07": {"sessions": [12]}},
"admin": {"b07_admin": ["b07"]},
}

test_user_session_not_allowed if {
not blueapi.user_session with data.diamond.data as diamond_data
with input as {"proposal": 1, "visit": 1, "beamline": "i03"}
with data.diamond.policy.token.claims as {"fedid": "oscar"}
}

test_user_session_allow if {
blueapi.user_session with data.diamond.data as diamond_data
with input as {"proposal": 1, "visit": 1, "beamline": "i03"}
with data.diamond.policy.token.claims as {"fedid": "bob"}
}

# b07_admin user can access a b07 session via their role, not direct session membership
test_user_session_allow_for_beamline_admin_via_role if {
blueapi.user_session with data.diamond.data as diamond_data
with input as {"proposal": 1, "visit": 2, "beamline": "b07"}
with data.diamond.policy.token.claims as {"fedid": "bob"}
}

# Instrument session has to match instrument of blueapi instance test
test_user_session_not_allowed_if_instrument_session_doesnt_match_blueapi_instance if {
not blueapi.user_session with data.diamond.data as diamond_data
with input as {"proposal": 1, "visit": 1, "beamline": "b07"}
with data.diamond.policy.token.claims as {"fedid": "bob"}
}

# POST /tasks denied if user not on instrument session test
test_post_tasks_not_allowed_if_user_not_on_instrument_session if {
not blueapi.post_task with data.diamond.data as diamond_data
with input as {"proposal": 1, "visit": 1, "beamline": "i03"}
with data.diamond.policy.token.claims as {"fedid": "oscar"}
}

# POST /tasks allowed if user on instrument session test
test_post_tasks_allowed_if_user_on_instrument_session if {
blueapi.post_task with data.diamond.data as diamond_data
with input as {"proposal": 1, "visit": 1, "beamline": "i03"}
with data.diamond.policy.token.claims as {"fedid": "bob"}
}

# DELETE /task denied if fed_id doesn't match task owner test
test_delete_task_not_allowed_if_fed_id_doesnt_match_task_owner if {
not blueapi.delete_task with data.diamond.data as diamond_data
with input as {"task_id": "1"}
with data.diamond.policy.token.claims as {"fedid": "oscar"}
}

# DELETE /task allowed if fed_id matches task owner test
test_delete_task_allowed_if_fed_id_matches_task_owner if {
blueapi.delete_task with data.diamond.data as diamond_data
with input as {"task_id": "1"}
with data.diamond.policy.token.claims as {"fedid": "alice"}
}

# GET /tasks returns only tasks submitted by requesting user test
test_get_tasks_returns_only_tasks_submitted_by_requesting_user if {
blueapi.fetch_tasks == {"3", "4"} with data.diamond.data as diamond_data
with data.diamond.policy.token.claims as {"fedid": "oscar"}
}

# GET task/{task_id} denied if tasks not submitted by requesting user test
test_get_task_not_allowed_if_task_not_submitted_by_requesting_user if {
not blueapi.fetch_task with data.diamond.data as diamond_data
with input as {"task_id": "1"}
with data.diamond.policy.token.claims as {"fedid": "oscar"}
}

# GET task/{task_id} allowed if task submitted by requesting user test
test_get_task_allowed_if_task_submitted_by_requesting_user if {
blueapi.fetch_task with data.diamond.data as diamond_data
with input as {"task_id": "3"}
with data.diamond.policy.token.claims as {"fedid": "oscar"}
}

# PUT /worker/state abort denied if not task creator test
test_put_worker_state_abort_not_allowed_if_not_task_creator if {
not blueapi.put_worker_state_abort with data.diamond.data as diamond_data
with input as {"task_id": "1"}
with data.diamond.policy.token.claims as {"fedid": "oscar"}
}

# PUT /worker/state abort allowed if task creator test
test_put_worker_state_abort_allowed_if_task_creator if {
blueapi.put_worker_state_abort with data.diamond.data as diamond_data
with input as {"task_id": "1"}
with data.diamond.policy.token.claims as {"fedid": "alice"}
}

# DELETE /task allowed for admin regardless of task ownership
test_delete_task_allowed_for_admin if {
blueapi.delete_task with data.diamond.data as diamond_data
with input as {"task_id": "1"}
with data.diamond.policy.token.claims as {"fedid": "carol"}
}

# GET /task/{task_id} allowed for admin regardless of task ownership
test_get_task_allowed_for_admin if {
blueapi.fetch_task with data.diamond.data as diamond_data
with input as {"task_id": "1"}
with data.diamond.policy.token.claims as {"fedid": "carol"}
}

# GET /tasks returns all tasks for admin
test_get_tasks_returns_all_tasks_for_admin if {
blueapi.fetch_tasks == {"1", "2", "3", "4"} with data.diamond.data as diamond_data
with data.diamond.policy.token.claims as {"fedid": "carol"}
}

# PUT /worker/state abort allowed for admin regardless of task ownership
test_put_worker_state_abort_allowed_for_admin if {
blueapi.put_worker_state_abort with data.diamond.data as diamond_data
with input as {"task_id": "1"}
with data.diamond.policy.token.claims as {"fedid": "carol"}
}
Loading