Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more config options for keycloak. #2285

Merged
merged 8 commits into from
Oct 2, 2024
Merged
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
46 changes: 33 additions & 13 deletions galaxy_ng/app/dynaconf_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,17 @@ def configure_keycloak(settings: Dynaconf) -> Dict[str, Any]:
SOCIAL_AUTH_KEYCLOAK_KEY = settings.get("SOCIAL_AUTH_KEYCLOAK_KEY", default=None)
SOCIAL_AUTH_KEYCLOAK_SECRET = settings.get("SOCIAL_AUTH_KEYCLOAK_SECRET", default=None)
SOCIAL_AUTH_KEYCLOAK_PUBLIC_KEY = settings.get("SOCIAL_AUTH_KEYCLOAK_PUBLIC_KEY", default=None)
KEYCLOAK_PROTOCOL = settings.get("KEYCLOAK_PROTOCOL", default=None)
KEYCLOAK_PROTOCOL = settings.get("KEYCLOAK_PROTOCOL", default="https")
KEYCLOAK_HOST = settings.get("KEYCLOAK_HOST", default=None)
KEYCLOAK_PORT = settings.get("KEYCLOAK_PORT", default=None)
KEYCLOAK_REALM = settings.get("KEYCLOAK_REALM", default=None)

KEYCLOAK_AUTH_PREFIX = settings.get("KEYCLOAK_AUTH_PREFIX", default="")
SOCIAL_AUTH_KEYCLOAK_AUTHORIZATION_URL = \
settings.get("SOCIAL_AUTH_KEYCLOAK_AUTHORIZATION_URL", default=None)
SOCIAL_AUTH_KEYCLOAK_ACCESS_TOKEN_URL = \
settings.get("SOCIAL_AUTH_KEYCLOAK_ACCESS_TOKEN_URL", default=None)

# Add settings if Social Auth values are provided
if all(
[
Expand All @@ -122,21 +128,35 @@ def configure_keycloak(settings: Dynaconf) -> Dict[str, Any]:
)
data["KEYCLOAK_HOST_LOOPBACK"] = settings.get("KEYCLOAK_HOST_LOOPBACK", default=None)
data["KEYCLOAK_URL"] = f"{KEYCLOAK_PROTOCOL}://{KEYCLOAK_HOST}:{KEYCLOAK_PORT}"
auth_url_str = "{keycloak}/auth/realms/{realm}/protocol/openid-connect/auth/"
data["SOCIAL_AUTH_KEYCLOAK_AUTHORIZATION_URL"] = auth_url_str.format(
keycloak=data["KEYCLOAK_URL"], realm=KEYCLOAK_REALM
)
if data["KEYCLOAK_HOST_LOOPBACK"]:
loopback_url = "{protocol}://{host}:{port}".format(
protocol=KEYCLOAK_PROTOCOL, host=data["KEYCLOAK_HOST_LOOPBACK"], port=KEYCLOAK_PORT
)

auth_url_str = "{keycloak}/{prefix}realms/{realm}/protocol/openid-connect/auth/"

if SOCIAL_AUTH_KEYCLOAK_AUTHORIZATION_URL is not None:
data["SOCIAL_AUTH_KEYCLOAK_AUTHORIZATION_URL"] = SOCIAL_AUTH_KEYCLOAK_AUTHORIZATION_URL
else:
data["SOCIAL_AUTH_KEYCLOAK_AUTHORIZATION_URL"] = auth_url_str.format(
keycloak=loopback_url, realm=KEYCLOAK_REALM
keycloak=data["KEYCLOAK_URL"], realm=KEYCLOAK_REALM, prefix=KEYCLOAK_AUTH_PREFIX
)

data[
"SOCIAL_AUTH_KEYCLOAK_ACCESS_TOKEN_URL"
] = f"{data['KEYCLOAK_URL']}/auth/realms/{KEYCLOAK_REALM}/protocol/openid-connect/token/"
if data["KEYCLOAK_HOST_LOOPBACK"]:
loopback_url = "{protocol}://{host}:{port}".format(
protocol=KEYCLOAK_PROTOCOL,
host=data["KEYCLOAK_HOST_LOOPBACK"],
port=KEYCLOAK_PORT
)
data["SOCIAL_AUTH_KEYCLOAK_AUTHORIZATION_URL"] = auth_url_str.format(
keycloak=loopback_url, realm=KEYCLOAK_REALM, prefix=KEYCLOAK_AUTH_PREFIX
)

if SOCIAL_AUTH_KEYCLOAK_ACCESS_TOKEN_URL is not None:
data['SOCIAL_AUTH_KEYCLOAK_ACCESS_TOKEN_URL'] = SOCIAL_AUTH_KEYCLOAK_ACCESS_TOKEN_URL
else:
data[
"SOCIAL_AUTH_KEYCLOAK_ACCESS_TOKEN_URL"
] = (
f"{data['KEYCLOAK_URL']}/{KEYCLOAK_AUTH_PREFIX}realms/"
f"{KEYCLOAK_REALM}/protocol/openid-connect/token/"
)

data["SOCIAL_AUTH_LOGIN_REDIRECT_URL"] = settings.get(
"SOCIAL_AUTH_LOGIN_REDIRECT_URL", default="/ui/"
Expand Down
90 changes: 87 additions & 3 deletions galaxy_ng/tests/unit/app/test_dynaconf_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import pytest

from galaxy_ng.app.dynaconf_hooks import post as post_hook
from galaxy_ng.app.dynaconf_hooks import configure_keycloak


class SuperDict(dict):
Expand Down Expand Up @@ -69,6 +70,16 @@ def validate(*args, **kwargs):
"validators": SuperValidator(),
}

BASE_KEYCLOAK_SETTINGS = {
"BASE_DIR": "templates",
"SOCIAL_AUTH_KEYCLOAK_KEY": "key123",
"SOCIAL_AUTH_KEYCLOAK_SECRET": "secret123",
"SOCIAL_AUTH_KEYCLOAK_PUBLIC_KEY": "pubkey123",
"KEYCLOAK_HOST": "mykeycloak",
"KEYCLOAK_PORT": 1337,
"KEYCLOAK_REALM": "aap",
}


@pytest.mark.parametrize(
"do_stuff, extra_settings, expected_results",
Expand Down Expand Up @@ -309,9 +320,7 @@ def validate(*args, **kwargs):
],
)
def test_dynaconf_hooks_authentication_backends_and_classes(
do_stuff,
extra_settings,
expected_results
do_stuff, extra_settings, expected_results
):

# skip test this way ...
Expand All @@ -337,3 +346,78 @@ def test_dynaconf_hooks_authentication_backends_and_classes(
print(e)
"""
assert new_settings.get(key) == val


@pytest.mark.parametrize(
"do_stuff, extra_settings, expected_results",
[
(
True,
{},
{
"INSTALLED_APPS": ["social_django", "dynaconf_merge_unique"],
"KEYCLOAK_URL": "https://mykeycloak:1337",
"SOCIAL_AUTH_KEYCLOAK_AUTHORIZATION_URL":
"https://mykeycloak:1337/realms/aap/protocol/openid-connect/auth/",
"SOCIAL_AUTH_KEYCLOAK_ACCESS_TOKEN_URL":
"https://mykeycloak:1337/realms/aap/protocol/openid-connect/token/",
"GALAXY_AUTH_KEYCLOAK_ENABLED": True,
"GALAXY_FEATURE_FLAGS__external_authentication": True,
"GALAXY_TOKEN_EXPIRATION": 1440,
},
),
(
True,
{
"KEYCLOAK_AUTH_PREFIX": "auth/",
"KEYCLOAK_PROTOCOL": "http",
"GALAXY_TOKEN_EXPIRATION": 0,
},
{
"INSTALLED_APPS": ["social_django", "dynaconf_merge_unique"],
"KEYCLOAK_URL": "http://mykeycloak:1337",
"SOCIAL_AUTH_KEYCLOAK_AUTHORIZATION_URL":
"http://mykeycloak:1337/auth/realms/aap/protocol/openid-connect/auth/",
"SOCIAL_AUTH_KEYCLOAK_ACCESS_TOKEN_URL":
"http://mykeycloak:1337/auth/realms/aap/protocol/openid-connect/token/",
"GALAXY_AUTH_KEYCLOAK_ENABLED": True,
"GALAXY_FEATURE_FLAGS__external_authentication": True,
"GALAXY_TOKEN_EXPIRATION": 0,
},
),
(
True,
{
"SOCIAL_AUTH_KEYCLOAK_AUTHORIZATION_URL":
"httpZ://mykeycloAk:1339/auth__/realms/aap/protocol/openid-connect/auth/",
"SOCIAL_AUTH_KEYCLOAK_ACCESS_TOKEN_URL":
"httpZ://mykeycloAk:1339/auth__/realms/aap/protocol/openid-connect/token/",
},
{
"SOCIAL_AUTH_KEYCLOAK_AUTHORIZATION_URL":
"httpZ://mykeycloAk:1339/auth__/realms/aap/protocol/openid-connect/auth/",
"SOCIAL_AUTH_KEYCLOAK_ACCESS_TOKEN_URL":
"httpZ://mykeycloAk:1339/auth__/realms/aap/protocol/openid-connect/token/",
},
),

],
)
def test_dynaconf_hook_configure_keycloak(do_stuff, extra_settings, expected_results):
# skip test this way ...
if not do_stuff:
return

xsettings = SuperDict()
xsettings.update(copy.deepcopy(BASE_KEYCLOAK_SETTINGS))
if extra_settings:
xsettings.update(copy.deepcopy(extra_settings))

# don't allow the downstream to edit this data ...
xsettings.immutable = True

# run the function and get the result ...
new_settings = configure_keycloak(xsettings)

for key, val in expected_results.items():
assert new_settings.get(key) == val
6 changes: 5 additions & 1 deletion profiles/keycloak/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,25 @@ services:
# - "UI_EXTERNAL_LOGIN_URI={API_PROTOCOL}://{API_HOST}:{API_PORT}/login"

keycloak:
image: quay.io/keycloak/keycloak:legacy
#image: quay.io/keycloak/keycloak:legacy
image: quay.io/keycloak/keycloak:latest
environment:
- DB_VENDOR=POSTGRES
- DB_ADDR=kc-postgres
- DB_DATABASE=keycloak
- DB_USER=keycloak
- DB_SCHEMA=public
- DB_PASSWORD=keycloak
- KEYCLOAK_ADMIN=admin
- KEYCLOAK_ADMIN_PASSWORD=admin
- KEYCLOAK_USER=admin
- KEYCLOAK_PASSWORD=admin
ports:
- 8080:8080
depends_on:
- kc-postgres
- ldap
command: ['start-dev']

kc-postgres:
image: "postgres:12"
Expand Down
37 changes: 25 additions & 12 deletions profiles/keycloak/keycloak-playbook.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
- name: Create or update AAP Keycloak realm
community.general.keycloak_realm:
auth_client_id: admin-cli
auth_keycloak_url: http://keycloak:8080/auth
#auth_keycloak_url: http://keycloak:8080/auth
auth_keycloak_url: http://keycloak:8080
#auth_keycloak_url: http://localhost:8080
auth_realm: master
auth_username: admin
auth_password: admin
Expand All @@ -31,7 +33,8 @@
- name: Create or update a Keycloak client
community.general.keycloak_client:
auth_client_id: admin-cli
auth_keycloak_url: http://keycloak:8080/auth
#auth_keycloak_url: http://keycloak:8080/auth
auth_keycloak_url: http://keycloak:8080
auth_realm: master
auth_username: admin
auth_password: admin
Expand Down Expand Up @@ -158,7 +161,8 @@

- name: Create Token for service Keycloak
uri:
url: "http://keycloak:8080/auth/realms/master/protocol/openid-connect/token"
#url: "http://keycloak:8080/auth/realms/master/protocol/openid-connect/token"
url: "http://keycloak:8080/realms/master/protocol/openid-connect/token"
method: POST
body_format: form-urlencoded
body:
Expand Down Expand Up @@ -236,7 +240,8 @@

- name: Create LDAP configuration
uri:
url: "http://keycloak:8080/auth/admin/realms/aap/components"
#url: "http://keycloak:8080/auth/admin/realms/aap/components"
url: "http://keycloak:8080/admin/realms/aap/components"
method: POST
body_format: json
body: "{{ ldap_config | to_json }}"
Expand All @@ -251,7 +256,8 @@

- name: Get components
uri:
url: "http://keycloak:8080/auth/admin/realms/aap/components?parent=aap&type=org.keycloak.storage.UserStorageProvider"
#url: "http://keycloak:8080/auth/admin/realms/aap/components?parent=aap&type=org.keycloak.storage.UserStorageProvider"
url: "http://keycloak:8080/admin/realms/aap/components?parent=aap&type=org.keycloak.storage.UserStorageProvider"
method: GET
status_code:
- 200
Expand Down Expand Up @@ -302,7 +308,8 @@

- name: Create LDAP group mapping
uri:
url: "http://keycloak:8080/auth/admin/realms/aap/components"
#url: "http://keycloak:8080/auth/admin/realms/aap/components"
url: "http://keycloak:8080/admin/realms/aap/components"
method: POST
body_format: json
body: "{{ ldap_group_mapper | to_json }}"
Expand All @@ -317,7 +324,8 @@

- name: Get group mapper identifier
uri:
url: "http://keycloak:8080/auth/admin/realms/aap/components?parent={{ ldap_id }}&type=org.keycloak.storage.ldap.mappers.LDAPStorageMapper&name=group"
#url: "http://keycloak:8080/auth/admin/realms/aap/components?parent={{ ldap_id }}&type=org.keycloak.storage.ldap.mappers.LDAPStorageMapper&name=group"
url: "http://keycloak:8080/admin/realms/aap/components?parent={{ ldap_id }}&type=org.keycloak.storage.ldap.mappers.LDAPStorageMapper&name=group"
method: GET
status_code:
- 200
Expand All @@ -333,7 +341,8 @@

- name: Sync LDAP users
uri:
url: "http://keycloak:8080/auth/admin/realms/aap/user-storage/{{ ldap_id }}/sync?action=triggerFullSync"
#url: "http://keycloak:8080/auth/admin/realms/aap/user-storage/{{ ldap_id }}/sync?action=triggerFullSync"
url: "http://keycloak:8080/admin/realms/aap/user-storage/{{ ldap_id }}/sync?action=triggerFullSync"
method: POST
status_code:
- 200
Expand All @@ -345,7 +354,8 @@

- name: Sync LDAP groups
uri:
url: "http://keycloak:8080/auth/admin/realms/aap/user-storage/{{ ldap_id }}/mappers/{{ keycloak_ldap_group_mapper_id }}/sync?direction=fedToKeycloak"
#url: "http://keycloak:8080/auth/admin/realms/aap/user-storage/{{ ldap_id }}/mappers/{{ keycloak_ldap_group_mapper_id }}/sync?direction=fedToKeycloak"
url: "http://keycloak:8080/admin/realms/aap/user-storage/{{ ldap_id }}/mappers/{{ keycloak_ldap_group_mapper_id }}/sync?direction=fedToKeycloak"
method: POST
status_code:
- 200
Expand All @@ -363,7 +373,8 @@
client_id: automation-hub
state: present
auth_client_id: admin-cli
auth_keycloak_url: http://keycloak:8080/auth
#auth_keycloak_url: http://keycloak:8080/auth
auth_keycloak_url: http://keycloak:8080
auth_realm: master
auth_username: admin
auth_password: admin
Expand All @@ -379,15 +390,17 @@
client_id: automation-hub
state: present
auth_client_id: admin-cli
auth_keycloak_url: http://keycloak:8080/auth
#auth_keycloak_url: http://keycloak:8080/auth
auth_keycloak_url: http://keycloak:8080
auth_realm: master
auth_username: admin
auth_password: admin
# loop: "{{ user_list.json}}"

- name: Get realm public key
uri:
url: "http://keycloak:8080/auth/realms/aap"
#url: "http://keycloak:8080/auth/realms/aap"
url: "http://keycloak:8080/realms/aap"
method: GET
status_code:
- 200
Expand Down
1 change: 1 addition & 0 deletions profiles/keycloak/pulp_config.env
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ PULP_GALAXY_DEPLOYMENT_MODE=standalone
PULP_SOCIAL_AUTH_KEYCLOAK_KEY=automation-hub
PULP_SOCIAL_AUTH_KEYCLOAK_SECRET=REALLYWELLKEPTSECRET
PULP_SOCIAL_AUTH_LOGIN_REDIRECT_URL={API_PROTOCOL}://{API_HOST}:{API_PORT}
PULP_KEYCLOAK_AUTH_PREFIX=""
PULP_KEYCLOAK_PROTOCOL=http
PULP_KEYCLOAK_HOST=keycloak
PULP_KEYCLOAK_HOST_LOOPBACK=localhost
Expand Down
Loading