Skip to content

Commit

Permalink
test/suites: Add tests for fine-grained authorization.
Browse files Browse the repository at this point in the history
Signed-off-by: Mark Laing <mark.laing@canonical.com>
  • Loading branch information
markylaing committed Feb 27, 2024
1 parent 98863e3 commit f5b107d
Showing 1 changed file with 248 additions and 0 deletions.
248 changes: 248 additions & 0 deletions test/suites/auth.sh
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ test_authorization() {
list_output="$(lxc auth permission list entity_type=server --format csv)"
echo "${list_output}" | grep -Fq 'server,/1.0,"project_manager:(test-group),viewer:(test-group),admin,can_create_groups,can_create_identities,..."'

# Remove existing group permissions before testing fine-grained auth.
lxc auth group permission remove test-group server viewer
lxc auth group permission remove test-group server project_manager

# Perform access checks
fine_grained_authorization

# Cleanup
lxc auth group delete test-group
lxc auth identity-provider-group delete test-idp-group
Expand All @@ -117,3 +124,244 @@ test_authorization() {
lxc config unset oidc.issuer
lxc config unset oidc.client.id
}


fine_grained_authorization() {
echo "==> Checking permissions for member of group with no permissions..."
user_is_not_server_admin
user_is_not_server_operator
user_is_not_project_manager
user_is_not_project_operator

# Give the test-group the `admin` entitlement on entity type `server`.
lxc auth group permission add test-group server admin

echo "==> Checking permissions for member of group with admin entitlement on server..."
user_is_server_admin
user_is_server_operator
user_can_edit_projects
user_is_project_operator

# Give the test-group the `project_manager` entitlement on entity type `server`.
lxc auth group permission remove test-group server admin
lxc auth group permission add test-group server project_manager

echo "==> Checking permissions for member of group with project_manager entitlement on server..."
user_is_not_server_admin
user_is_server_operator
user_can_edit_projects
user_is_project_operator

# Give the test-group the `operator` entitlement on the default project.
lxc auth group permission remove test-group server project_manager
lxc auth group permission add test-group project default operator

echo "==> Checking permissions for member of group with operator entitlement on default project..."
user_is_not_server_admin
user_is_not_server_operator
user_is_not_project_manager
user_is_project_operator

lxc auth group permission remove test-group project default operator

# Can't create a permission for an instance that doesn't exist.
! lxc auth group permission add test-group instance user-foo user project=default || false

# Create an instance for testing the `user` entitlement on entity type `instance`.
lxc launch testimage user-foo

# Change permission to "user" for instance "user-foo"
lxc auth group permission add test-group instance user-foo user project=default

# To exec into an instance, the test-group will also need `can_view_events` for the project.
lxc auth group permission add test-group project default can_view_events

echo "==> Checking permissions for member of group with user entitlement on instance user-foo in default project..."
user_is_instance_user user-foo # Pass instance name into test as we don't have permission to create one.
lxc delete user-foo --force # Must clean this up now as subsequent tests assume a clean project.
user_is_not_server_admin
user_is_not_server_operator
user_is_not_project_manager
user_is_not_project_operator
}

user_is_not_server_admin() {
# Can always see server info (type-bound public access https://openfga.dev/docs/modeling/public-access).
lxc_remote info oidc: > /dev/null

# Cannot see any config.
! lxc_remote info oidc: | grep -Fq 'core.https_address' || false

# Cannot set any config.
! lxc_remote config set oidc: core.proxy_https=https://example.com || false

# Should still be able to list storage pools but not be able to see any storage pool config or delete.
[ "$(lxc_remote storage list oidc: -f csv | wc -l)" = 1 ]
lxc_remote storage create test-pool dir
! lxc_remote storage set oidc:test-pool rsync.compression=true || false
! lxc_remote storage show oidc:test-pool | grep -Fq 'source:' || false
! lxc_remote storage delete oidc:test-pool || false
lxc_remote storage delete test-pool

# Should not be able to create a storage pool.
! lxc_remote storage create oidc:test dir || false

# Should not be able to see certificates
[ "$(lxc_remote config trust list oidc: -f csv | wc -l)" = 0 ]

# Cannot edit certificates.
fingerprint="$(lxc config trust list -f csv | cut -d, -f4)"
! lxc config trust show "${fingerprint}" | sed -e "s/restricted: false/restricted: true/" | lxc_remote config trust edit "oidc:${fingerprint}" || false
}

user_is_not_server_operator() {
# Should not be able to create a project.
! lxc_remote project create oidc:new-project || false
}

user_is_server_admin() {
# Should be able to see server config.
lxc_remote info oidc: | grep -Fq 'core.https_address'

# Should be able to add/remove certificates.
gen_cert openfga-test
test_cert_fingerprint="$(cert_fingerprint "${LXD_CONF}/openfga-test.crt")"
certificate_add_token="$(lxc_remote config trust add oidc: --name test --quiet)"
mv "${LXD_CONF}/client.crt" "${LXD_CONF}/client.crt.bak"
mv "${LXD_CONF}/client.key" "${LXD_CONF}/client.key.bak"
mv "${LXD_CONF}/openfga-test.crt" "${LXD_CONF}/client.crt"
mv "${LXD_CONF}/openfga-test.key" "${LXD_CONF}/client.key"
lxc_remote remote add test-remote "${certificate_add_token}"
mv "${LXD_CONF}/client.crt.bak" "${LXD_CONF}/client.crt"
mv "${LXD_CONF}/client.key.bak" "${LXD_CONF}/client.key"
lxc_remote config trust remove "oidc:${test_cert_fingerprint}"
lxc_remote remote remove test-remote

# Should be able to create/edit/delete a storage pool.
lxc_remote storage create oidc:test-pool dir
lxc_remote storage set oidc:test-pool rsync.compression=true
lxc_remote storage show oidc:test-pool | grep -Fq 'rsync.compression:'
lxc_remote storage delete oidc:test-pool
}

user_is_server_operator() {
# Should be able to see projects.
lxc_remote project list oidc: -f csv | grep -Fq 'default'

# Should be able to create/edit/delete a project.
lxc_remote project create oidc:test-project
lxc_remote project show oidc:test-project | sed -e 's/description: ""/description: "Test Project"/' | lxc_remote project edit oidc:test-project
lxc_remote project delete oidc:test-project
}

user_can_edit_projects() {
lxc_remote project set oidc:default user.foo bar
lxc_remote project unset oidc:default user.foo
}

user_is_not_project_manager() {
! lxc_remote project set oidc:default user.foo bar || false
! lxc_remote project unset oidc:default user.foo || false
}

user_is_project_operator() {
# Should be able to create/edit/delete project level resources
lxc_remote profile create oidc:test-profile
lxc_remote profile device add oidc:test-profile eth0 none
lxc_remote profile delete oidc:test-profile
lxc_remote network create oidc:test-network
lxc_remote network set oidc:test-network bridge.mtu=1500
lxc_remote network delete oidc:test-network
lxc_remote network acl create oidc:test-network-acl
lxc_remote network acl delete oidc:test-network-acl
lxc_remote network zone create oidc:test-network-zone
lxc_remote network zone delete oidc:test-network-zone
pool_name="$(lxc_remote storage list oidc: -f csv | cut -d, -f1)"
lxc_remote storage volume create "oidc:${pool_name}" test-volume
lxc_remote storage volume delete "oidc:${pool_name}" test-volume
lxc_remote launch testimage oidc:operator-foo
LXC_LOCAL='' lxc_remote exec oidc:operator-foo -- echo "bar"
lxc_remote delete oidc:operator-foo --force
}

user_is_not_project_operator() {

# Project list will not fail but there will be no output.
[ "$(lxc_remote project list oidc: -f csv | wc -l)" = 0 ]
! lxc_remote project show oidc:default || false

# Should not be able to see or create any instances.
lxc_remote init testimage c1
[ "$(lxc_remote list oidc: -f csv | wc -l)" = 0 ]
[ "$(lxc_remote list oidc: -f csv --all-projects | wc -l)" = 0 ]
! lxc_remote init testimage oidc:test-instance || false
lxc_remote delete c1 -f

# Should not be able to see network allocations.
[ "$(lxc_remote network list-allocations oidc: -f csv | wc -l)" = 0 ]
[ "$(lxc_remote network list-allocations oidc: --all-projects -f csv | wc -l)" = 0 ]

# Should not be able to see or create networks.
[ "$(lxc_remote network list oidc: -f csv | wc -l)" = 0 ]
! lxc_remote network create oidc:test-network || false

# Should not be able to see or create network ACLs.
lxc_remote network acl create acl1
[ "$(lxc_remote network acl list oidc: -f csv | wc -l)" = 0 ]
! lxc_remote network acl create oidc:test-acl || false
lxc_remote network acl delete acl1

# Should not be able to see or create network zones.
lxc_remote network zone create zone1
[ "$(lxc_remote network zone list oidc: -f csv | wc -l)" = 0 ]
! lxc_remote network zone create oidc:test-zone || false
lxc_remote network zone delete zone1

# Should not be able to see or create profiles.
[ "$(lxc_remote profile list oidc: -f csv | wc -l)" = 0 ]
! lxc_remote profile create oidc:test-profile || false

# Should not be able to see or create image aliases
test_image_fingerprint="$(lxc_remote image info testimage | awk '/^Fingerprint/ {print $2}')"
[ "$(lxc_remote image alias list oidc: -f csv | wc -l)" = 0 ]
! lxc_remote image alias create oidc:testimage2 "${test_image_fingerprint}" || false

# Should not be able to see or create storage pool volumes.
pool_name="$(lxc_remote storage list oidc: -f csv | cut -d, -f1)"
lxc_remote storage volume create "${pool_name}" vol1
[ "$(lxc_remote storage volume list "oidc:${pool_name}" -f csv | wc -l)" = 0 ]
[ "$(lxc_remote storage volume list "oidc:${pool_name}" --all-projects -f csv | wc -l)" = 0 ]
! lxc_remote storage volume create "oidc:${pool_name}" test-volume || false
lxc_remote storage volume delete "${pool_name}" vol1

# Should not be able to see any operations.
[ "$(lxc_remote operation list oidc: -f csv | wc -l)" = 0 ]
[ "$(lxc_remote operation list oidc: --all-projects -f csv | wc -l)" = 0 ]

# Image list will still work but none will be shown because none are public.
[ "$(lxc_remote image list oidc: -f csv | wc -l)" = 0 ]

# Image edit will fail. Note that this fails with "not found" because we fail to resolve the alias (image is not public
# so it is not returned from the DB).
! lxc_remote image set-property oidc:testimage requirements.secureboot true || false
test_image_fingerprint_short="$(echo "${test_image_fingerprint}" | cut -c1-12)"
! lxc_remote image set-property "oidc:${test_image_fingerprint_short}" requirements.secureboot true || false

# Should be able to list public images.
lxc_remote image show testimage | sed -e "s/public: false/public: true/" | lxc_remote image edit testimage
lxc_remote image list oidc: -f csv | grep -Fq "${test_image_fingerprint_short}"
lxc_remote image show testimage | sed -e "s/public: true/public: false/" | lxc_remote image edit testimage
}

user_is_instance_user() {
instance_name="${1}"

# Check we can still interact with the instance.
touch "${TEST_DIR}/tmp"
lxc_remote file push "${TEST_DIR}/tmp" "oidc:${instance_name}/root/tmpfile.txt"
LXC_LOCAL='' lxc_remote exec "oidc:${instance_name}" -- rm /root/tmpfile.txt
rm "${TEST_DIR}/tmp"

# We can't edit the instance though
! lxc_remote config set "oidc:${instance_name}" user.fizz=buzz || false
}

0 comments on commit f5b107d

Please sign in to comment.