Skip to content

Commit

Permalink
tests: Authorization scriptlet
Browse files Browse the repository at this point in the history
Signed-off-by: Benjamin Somers <[email protected]>
  • Loading branch information
bensmrs committed Dec 6, 2024
1 parent 23464e9 commit 2f95677
Showing 1 changed file with 132 additions and 0 deletions.
132 changes: 132 additions & 0 deletions test/suites/authorization_scriptlet.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
test_authorization_scriptlet() {
incus config set core.https_address "${INCUS_ADDR}"
ensure_has_localhost_remote "${INCUS_ADDR}"
ensure_import_testimage

# Check only valid scriptlets are accepted.
! incus config set authorization.scriptlet=foo || false

# Prevent user1 from doing anything, except viewing the server
cat << EOF | incus config set authorization.scriptlet=-
def authorize(details, object, entitlement):
if details.UserName == 'user1':
return object == 'server:incus' and entitlement == 'can_view'
return True
EOF

# Run OIDC server.
spawn_oidc
set_oidc user1

incus config set "oidc.issuer=http://127.0.0.1:$(cat "${TEST_DIR}/oidc.port")/"
incus config set "oidc.client.id=device"

BROWSER=curl incus remote add --accept-certificate oidc-authorization-scriptlet "${INCUS_ADDR}" --auth-type oidc
[ "$(incus info oidc-authorization-scriptlet: | grep ^auth_user_name | sed "s/.*: //g")" = "user1" ]

# user1 can’t see anything yet
[ "$(incus project list oidc-authorization-scriptlet: -f csv | wc -l)" = 0 ]
[ "$(incus list oidc-authorization-scriptlet: -f csv | wc -l)" = 0 ]

# Let’s fix that
cat << EOF | incus config set authorization.scriptlet=-
def authorize(details, object, entitlement):
if details.UserName == 'user1':
return object in ['server:incus', 'project:default'] and entitlement == 'can_view'
return True
EOF

# user1 can see the project but not create an instance
[ "$(incus project list oidc-authorization-scriptlet: -f csv | wc -l)" = 1 ]
[ "$(incus list oidc-authorization-scriptlet: -f csv | wc -l)" = 0 ]
! incus init oidc-authorization-scriptlet:testimage oidc-authorization-scriptlet:c1

# Let’s fix that
cat << EOF | incus config set authorization.scriptlet=-
def authorize(details, object, entitlement):
if details.UserName == 'user1':
if (object in ['server:incus', 'image_alias:default/testimage'] or object.startswith('image:default/') or object.startswith('instance:default/')):
return entitlement == 'can_view'
elif object == 'project:default':
return entitlement in ['can_view', 'can_create_instances', 'can_view_events']
return False
return True
EOF

# user1 can create an instance, but not interact with it
incus init oidc-authorization-scriptlet:testimage oidc-authorization-scriptlet:c1
[ "$(incus list oidc-authorization-scriptlet: -f csv | wc -l)" = 1 ]
! incus exec oidc-authorization-scriptlet:c1 -- ls -al

# Let’s fix that
cat << EOF | incus config set authorization.scriptlet=-
def authorize(details, object, entitlement):
if details.UserName == 'user1':
if object == 'instance:default/c1':
return entitlement in ['can_view', 'can_update_state', 'can_exec']
elif (object in ['server:incus', 'image_alias:default/testimage'] or object.startswith('image:default/') or object.startswith('instance:default/')):
return entitlement == 'can_view'
elif object == 'project:default':
return entitlement in ['can_view', 'can_create_instances', 'can_view_events']
return False
return True
EOF

# user1 can execute commands on c1 but cannot do anything outside of the default project
incus start oidc-authorization-scriptlet:c1
incus exec oidc-authorization-scriptlet:c1 -- ls -al
! incus project create oidc-authorization-scriptlet:p1

# Let’s fix that
cat << EOF | incus config set authorization.scriptlet=-
def authorize(details, object, entitlement):
if details.UserName == 'user1':
if object == 'instance:default/c1':
return entitlement in ['can_view', 'can_update_state', 'can_exec']
elif object == 'server:incus':
return entitlement in ['can_view', 'can_create_projects']
elif (object == 'image_alias:default/testimage' or object.startswith('image:default/') or object.startswith('instance:default/')):
return entitlement == 'can_view'
elif object in ['project:default', 'project:p1']:
return entitlement in ['can_view', 'can_create_instances', 'can_view_events']
return False
return True
EOF

incus project create oidc-authorization-scriptlet:p1
[ "$(incus project list oidc-authorization-scriptlet: -f csv | wc -l)" = 2 ]

# Let’s now test the two optional scriptlet functions
cat << EOF | incus config set authorization.scriptlet=-
def authorize(details, object, entitlement):
return True
def get_project_access(project_name):
if project_name == 'default':
return ['foo', 'bar']
return ['foo']
def get_instance_access(project_name, instance_name):
if project_name == 'default' and instance_name == 'c1':
return ['foo', 'bar']
return ['foo']
EOF

[ "$(incus project info default --show-access | wc -l)" = 6 ]
[ "$(incus project info p1 --show-access | wc -l)" = 3 ]
[ "$(incus info c1 --show-access | wc -l)" = 6 ]
incus init testimage c2
[ "$(incus info c2 --show-access | wc -l)" = 3 ]

# Cleanup.
incus delete c1 --force
incus delete c2 --force
incus project delete p1

# Unset config keys.
kill_oidc
incus config unset oidc.issuer
incus config unset oidc.client.id
incus config unset authorization.scriptlet
incus remote remove oidc-authorization-scriptlet
}

0 comments on commit 2f95677

Please sign in to comment.