Skip to content

Commit 7413425

Browse files
authored
clean up Polar file: minor functional changes (#1113)
1 parent de06e11 commit 7413425

File tree

6 files changed

+74
-27
lines changed

6 files changed

+74
-27
lines changed

nexus/src/authz/api_resources.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ impl ApiResourceWithRolesType for Organization {
391391
pub enum OrganizationRoles {
392392
Admin,
393393
Collaborator,
394+
Viewer,
394395
}
395396

396397
impl db::model::DatabaseString for OrganizationRoles {
@@ -400,13 +401,15 @@ impl db::model::DatabaseString for OrganizationRoles {
400401
match self {
401402
OrganizationRoles::Admin => "admin",
402403
OrganizationRoles::Collaborator => "collaborator",
404+
OrganizationRoles::Viewer => "viewer",
403405
}
404406
}
405407

406408
fn from_database_string(s: &str) -> Result<Self, Self::Error> {
407409
match s {
408410
"admin" => Ok(OrganizationRoles::Admin),
409411
"collaborator" => Ok(OrganizationRoles::Collaborator),
412+
"viewer" => Ok(OrganizationRoles::Viewer),
410413
_ => Err(anyhow!(
411414
"unsupported Organization role from database: {:?}",
412415
s

nexus/src/authz/omicron.polar

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ has_role(actor: AuthenticatedActor, role: String, resource: Resource)
6767
# - silo.viewer (can read most resources within the Silo)
6868
# - organization.admin (complete control over an organization)
6969
# - organization.collaborator (can manage Projects)
70+
# - organization.viewer (can read most resources within the Organization)
7071
# - project.admin (complete control over a Project)
7172
# - project.collaborator (can manage all resources within the Project)
7273
# - project.viewer (can read most resources within the Project)
@@ -164,22 +165,22 @@ resource Organization {
164165
"read",
165166
"create_child",
166167
];
167-
roles = [ "admin", "collaborator" ];
168+
roles = [ "admin", "collaborator", "viewer" ];
168169

169170
# Roles implied by other roles on this resource
171+
"viewer" if "collaborator";
170172
"collaborator" if "admin";
171173

172174
# Permissions granted directly by roles on this resource
173-
"list_children" if "collaborator";
174-
"read" if "collaborator";
175+
"list_children" if "viewer";
176+
"read" if "viewer";
175177
"create_child" if "collaborator";
176178
"modify" if "admin";
177179

178180
# Roles implied by roles on this resource's parent (Silo)
179181
relations = { parent_silo: Silo };
180182
"admin" if "collaborator" on "parent_silo";
181-
"read" if "viewer" on "parent_silo";
182-
"list_children" if "viewer" on "parent_silo";
183+
"viewer" if "viewer" on "parent_silo";
183184
}
184185
has_relation(silo: Silo, "parent_silo", organization: Organization)
185186
if organization.silo = silo;
@@ -206,7 +207,7 @@ resource Project {
206207
# Roles implied by roles on this resource's parent (Organization)
207208
relations = { parent_organization: Organization };
208209
"admin" if "collaborator" on "parent_organization";
209-
"viewer" if "list_children" on "parent_organization";
210+
"viewer" if "viewer" on "parent_organization";
210211
}
211212
has_relation(organization: Organization, "parent_organization", project: Project)
212213
if project.organization = organization;
@@ -253,7 +254,7 @@ has_relation(user: SiloUser, "silo_user", ssh_key: SshKey)
253254
# of the API path (e.g., "/images") or as an implementation detail of the system
254255
# (in the case of console sessions and "Database"). The policies are
255256
# either statically-defined in this file or driven by role assignments on the
256-
# Fleet.
257+
# Fleet. None of these resources defines their own roles.
257258
#
258259

259260
# Describes the policy for accessing "/images" (in the API)
@@ -320,25 +321,11 @@ resource Database {
320321
# other general functions.
321322
"modify"
322323
];
323-
roles = [
324-
# All authenticated users get the "user" role, which grants the
325-
# "query" permission. See above.
326-
"user",
327-
328-
# The special "db-init" user gets the "init" role, which grants the
329-
# additional "modify" permission.
330-
"init"
331-
];
332-
333-
# See above.
334-
"query" if "user";
335-
336-
"user" if "init";
337-
"modify" if "init";
338324
}
339325

340-
# All authenticated users have the "user" role on the database.
341-
has_role(_actor: AuthenticatedActor, "user", _resource: Database);
326+
# All authenticated users have the "query" permission on the database.
327+
has_permission(_actor: AuthenticatedActor, "query", _resource: Database);
328+
342329
# The "db-init" user is the only one with the "init" role.
343-
has_role(actor: AuthenticatedActor, "init", _resource: Database)
330+
has_permission(actor: AuthenticatedActor, "modify", _resource: Database)
344331
if actor = USER_DB_INIT;

nexus/src/db/fixed_data/role_builtin.rs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
use lazy_static::lazy_static;
77
use omicron_common::api;
88

9-
#[derive(Clone)]
9+
#[derive(Clone, Debug)]
1010
pub struct RoleBuiltinConfig {
1111
pub resource_type: api::external::ResourceType,
1212
pub role_name: &'static str,
@@ -67,6 +67,11 @@ lazy_static! {
6767
},
6868
ORGANIZATION_ADMINISTRATOR.clone(),
6969
ORGANIZATION_COLLABORATOR.clone(),
70+
RoleBuiltinConfig {
71+
resource_type: api::external::ResourceType::Organization,
72+
role_name: "viewer",
73+
description: "Organization Viewer",
74+
},
7075
RoleBuiltinConfig {
7176
resource_type: api::external::ResourceType::Project,
7277
role_name: "admin",
@@ -84,3 +89,52 @@ lazy_static! {
8489
},
8590
];
8691
}
92+
93+
#[cfg(test)]
94+
mod test {
95+
use super::BUILTIN_ROLES;
96+
use crate::authz;
97+
use crate::db::model::DatabaseString;
98+
use omicron_common::api::external::ResourceType;
99+
use strum::IntoEnumIterator;
100+
101+
#[test]
102+
fn test_fixed_role_data() {
103+
// Every role that's defined in the public API as assignable on a
104+
// resource must have a corresponding entry in BUILTIN_ROLES above.
105+
// The reverse is not necessarily true because we have some internal
106+
// roles that are not exposed to end users.
107+
check_public_roles::<authz::FleetRoles>(ResourceType::Fleet);
108+
check_public_roles::<authz::SiloRoles>(ResourceType::Silo);
109+
check_public_roles::<authz::OrganizationRoles>(
110+
ResourceType::Organization,
111+
);
112+
check_public_roles::<authz::ProjectRoles>(ResourceType::Project);
113+
}
114+
115+
fn check_public_roles<T>(resource_type: ResourceType)
116+
where
117+
T: std::fmt::Debug + DatabaseString + IntoEnumIterator,
118+
{
119+
for variant in T::iter() {
120+
let role_name = variant.to_database_string();
121+
122+
let found = BUILTIN_ROLES.iter().find(|role_config| {
123+
role_config.resource_type == resource_type
124+
&& role_config.role_name == role_name
125+
});
126+
if let Some(found_config) = found {
127+
println!(
128+
"variant: {:?} found fixed data {:?}",
129+
variant, found_config
130+
);
131+
} else {
132+
panic!(
133+
"found public role {:?} on {:?} with no corresponding \
134+
built-in role",
135+
role_name, resource_type
136+
);
137+
}
138+
}
139+
}
140+
}

nexus/tests/integration_tests/roles_builtin.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ async fn test_roles_builtin(cptestctx: &ControlPlaneTestContext) {
3434
("fleet.viewer", "Fleet Viewer"),
3535
("organization.admin", "Organization Administrator"),
3636
("organization.collaborator", "Organization Collaborator"),
37+
("organization.viewer", "Organization Viewer"),
3738
("project.admin", "Project Administrator"),
3839
("project.collaborator", "Project Collaborator"),
3940
("project.viewer", "Project Viewer"),
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
variant Admin: serialized form = admin
22
variant Collaborator: serialized form = collaborator
3+
variant Viewer: serialized form = viewer

openapi/nexus.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6643,7 +6643,8 @@
66436643
"type": "string",
66446644
"enum": [
66456645
"admin",
6646-
"collaborator"
6646+
"collaborator",
6647+
"viewer"
66476648
]
66486649
},
66496650
"OrganizationRolesPolicy": {

0 commit comments

Comments
 (0)