Skip to content

Commit

Permalink
on startup only add admin role if not already present (#705)
Browse files Browse the repository at this point in the history
* on startup only insert admin role if not already present

* flyby: specify fallback version so install doesn't fail if .git isn't present

this can happen when using git worktrees or tarballs

* flyby: don't hide error if correlation ID is not present in response

This can happen if for example the k8s ingress rejects the requests with 413 content too large

* Test multiple server starts with tiled_admins.

* CI: Ensure docker-compose is installed

* Adjust for backward-incompatible change in Docker 7

---------

Co-authored-by: Joseph Kleinhenz <[email protected]>
Co-authored-by: Dan Allan <[email protected]>
  • Loading branch information
3 people authored Apr 2, 2024
1 parent eda0499 commit f3f7f09
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 4 deletions.
2 changes: 1 addition & 1 deletion continuous_integration/scripts/start_LDAP.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ set -e

# Start LDAP server in docker container
docker pull bitnami/openldap:latest
docker-compose -f continuous_integration/docker-configs/ldap-docker-compose.yml up -d
docker compose -f continuous_integration/docker-configs/ldap-docker-compose.yml up -d
docker ps
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ Documentation = "https://blueskyproject.io/tiled"

[tool.hatch]
version.source = "vcs"
version.fallback-version = "0.0.0"
build.hooks.vcs.version-file = "tiled/_version.py"

# Defining this (empty) section invokes hatch_build.py
Expand Down
7 changes: 7 additions & 0 deletions tiled/_tests/test_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,13 @@ def test_admin(enter_password, config):
with fail_with_status_code(HTTP_401_UNAUTHORIZED):
context.admin.show_principal(some_principal_uuid)

# Start the server a second time. Now alice is already an admin.
with Context.from_app(build_app_from_config(config)) as context:
with enter_password("secret1"):
context.authenticate(username="alice")
admin_roles = context.whoami()["roles"]
assert "admin" in [role["name"] for role in admin_roles]


def test_api_key_activity(enter_password, config):
"""
Expand Down
6 changes: 6 additions & 0 deletions tiled/authn_database/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,12 @@ async def make_admin_by_identity(db, identity_provider, id):
principal = await create_user(db, identity_provider, id)
else:
principal = identity.principal

# check if principal already has admin role
for role in principal.roles:
if role.name == "admin":
return principal

admin_role = (await db.execute(select(Role).filter(Role.name == "admin"))).scalar()
assert admin_role is not None, "Admin role is missing from Roles table"
principal.roles.append(admin_role)
Expand Down
11 changes: 8 additions & 3 deletions tiled/client/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,21 @@ def raise_for_status(response) -> None:
if response.is_success:
return response

# correlation ID may be missing if request didn't make it to the server
correlation_id = response.headers.get("x-tiled-request-id", None)

if response.has_redirect_location:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"Redirect location: '{0.headers[location]}'\n"
"For more information, server admin can search server logs for "
"correlation ID {0.headers[x-tiled-request-id]}."
"correlation ID {correlation_id}."
)
else:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"For more information, server admin can search server logs for "
"correlation ID {0.headers[x-tiled-request-id]}."
"correlation ID {correlation_id}."
)

status_class = response.status_code // 100
Expand All @@ -53,7 +56,9 @@ def raise_for_status(response) -> None:
5: "Server error",
}
error_type = error_types.get(status_class, "Invalid status code")
message = message.format(response, error_type=error_type)
message = message.format(
response, error_type=error_type, correlation_id=correlation_id
)
raise httpx.HTTPStatusError(message, request=request, response=response)


Expand Down

0 comments on commit f3f7f09

Please sign in to comment.