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
27 changes: 27 additions & 0 deletions policy/project/user/role/revoke.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package identity.project.user.role.revoke

import data.identity
import data.identity.assignment

# Revoke user a role on a project

default allow := false

allow if {
"admin" in input.credentials.roles
}

allow if {
"manager" in input.credentials.roles
assignment.project_role_domain_matches
}


violation contains {"field": "domain_id", "msg": "revoking a role from a user on a project requires admin or manager role in the domain scope."} if {
not "admin" in input.credentials.roles
not "manager" in input.credentials.roles
}

violation contains {"field": "domain_id", "msg": "revoking a role from a user on a project requires domain scope matching the domain_id of the target project and role (or a global role)."} if {
assignment.project_role_domain_matches
}
20 changes: 20 additions & 0 deletions policy/project/user/role/revoke_test.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package test_project_user_role_revoke

import data.identity.project.user.role.revoke

test_allowed if {
revoke.allow with input as {"credentials": {"roles": ["admin"]}}
revoke.allow with input as {"credentials": {"roles": ["manager"], "domain_id": "foo"}, "target": {"user": {"domain_id": "foo"}, "project": {"domain_id": "foo"}, "role": {"domain_id": null}}}
revoke.allow with input as {"credentials": {"roles": ["manager"], "domain_id": "foo"}, "target": {"user": {"domain_id": "foo"}, "project": {"domain_id": "foo"}, "role": {"domain_id": "foo"}}}
}

test_forbidden if {
not revoke.allow with input as {"credentials": {"roles": []}}
not revoke.allow with input as {"credentials": {"roles": ["reader"], "system": "foo"}}
not revoke.allow with input as {"credentials": {"roles": ["reader"], "domain_id": "foo"}, "target": {"user": {"domain_id": "foo1"}, "project": {"domain_id": "foo"}, "role": {"domain_id": "foo"}}}
not revoke.allow with input as {"credentials": {"roles": ["reader"], "domain_id": "foo"}, "target": {"user": {"domain_id": "foo1"}, "project": {"domain_id": "foo1"}, "role": {"domain_id": "foo1"}}}
not revoke.allow with input as {"credentials": {"roles": ["reader"], "domain_id": "foo"}, "target": {"user": {"domain_id": "foo"}, "project": {"domain_id": "foo1"}, "role": {"domain_id": "foo1"}}}
not revoke.allow with input as {"credentials": {"roles": ["reader"], "domain_id": "foo"}, "target": {"user": {"domain_id": "foo1"}, "project": {"domain_id": "foo1"}, "role": {"domain_id": "foo1"}}}
not revoke.allow with input as {"credentials": {"roles": ["reader"], "domain_id": "foo"}, "target": {"project": {"domain_id": "foo"}, "role": {"domain_id": "foo"}}}
not revoke.allow with input as {"credentials": {"roles": ["member"], "domain_id": "foo"}, "target": {"project": {"domain_id": "foo"}, "role": {"domain_id": "foo"}, "user": {"domain_id": "foo"}}}
}
3 changes: 2 additions & 1 deletion src/api/v3/role_assignment/project/user/role.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ use crate::keystone::ServiceState;

mod check;
mod grant;
mod revoke;

pub(crate) fn openapi_router() -> OpenApiRouter<ServiceState> {
OpenApiRouter::new().routes(routes!(check::check, grant::grant))
OpenApiRouter::new().routes(routes!(check::check, grant::grant, revoke::revoke))
}
6 changes: 3 additions & 3 deletions src/api/v3/role_assignment/project/user/role/grant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ use crate::{
resource::ResourceApi,
};

/// Assign role to group on project
/// Assign role to user on project
///
/// Assigns a role to a group on a project.
/// Assigns a role to a user on a project.
#[utoipa::path(
put,
path = "/projects/{project_id}/users/{user_id}/roles/{role_id}",
operation_id = "/project/user/role:put",
params(
("role_id" = String, Path, description = "The user ID."),
("role_id" = String, Path, description = "The role ID."),
("project_id" = String, Path, description = "The project ID."),
("user_id" = String, Path, description = "The user ID.")
),
Expand Down
Loading
Loading