Skip to content

Instantly share code, notes, and snippets.

@exhuma
Created December 16, 2024 14:06
Show Gist options
  • Save exhuma/120dfd2cfb59f281bd4daadf0a217b0e to your computer and use it in GitHub Desktop.
Save exhuma/120dfd2cfb59f281bd4daadf0a217b0e to your computer and use it in GitHub Desktop.
Initialise keycloak realm with test user
#!/usr/bin/python3
"""
This script creates a realm, client, and user in Keycloak for local development.
"""
from os import environ
import requests
import rich
BASE_URL = "http://idp.local:8080"
REALM_NAME = "local-dev"
CLIENT_NAME = environ["ACCEPTED_AUDIENCE"]
USERNAME = "user"
PASSWORD = "pass"
ADMIN_USERNAME = "admin"
ADMIN_PASSWORD = "admin"
def get_admin_token():
response = requests.post(
f"{BASE_URL}/realms/master/protocol/openid-connect/token",
data={
"client_id": "admin-cli",
"username": ADMIN_USERNAME,
"password": ADMIN_PASSWORD,
"grant_type": "password",
},
)
response.raise_for_status()
return response.json()["access_token"]
def realm_exists(token):
url = f"{BASE_URL}/admin/realms/{REALM_NAME}"
response = requests.get(url, headers={"Authorization": f"Bearer {token}"})
return response.status_code == 200
def create_realm(token):
url = f"{BASE_URL}/admin/realms"
realm_data = {"realm": REALM_NAME, "enabled": True}
response = requests.post(
url, json=realm_data, headers={"Authorization": f"Bearer {token}"}
)
response.raise_for_status()
def client_exists(token):
url = f"{BASE_URL}/admin/realms/{REALM_NAME}/clients"
response = requests.get(url, headers={"Authorization": f"Bearer {token}"})
clients = response.json()
return any(client["clientId"] == CLIENT_NAME for client in clients)
def create_client(token):
url = f"{BASE_URL}/admin/realms/{REALM_NAME}/clients"
client_data = {
"clientId": CLIENT_NAME,
"enabled": True,
"protocol": "openid-connect",
"redirectUris": [
"http://localhost:5173/auth-callback",
"http://localhost:5173",
],
}
requests.post(
url, json=client_data, headers={"Authorization": f"Bearer {token}"}
)
def user_exists(token):
url = f"{BASE_URL}/admin/realms/{REALM_NAME}/users?username={USERNAME}"
response = requests.get(url, headers={"Authorization": f"Bearer {token}"})
return len(response.json()) > 0
def create_user(token):
url = f"{BASE_URL}/admin/realms/{REALM_NAME}/users"
user_data = {
"username": USERNAME,
"firstName": "Test",
"lastName": "User",
"email": f"{USERNAME}@example.com",
"emailVerified": True,
"enabled": True,
"credentials": [
{"type": "password", "value": PASSWORD, "temporary": False}
],
}
requests.post(
url, json=user_data, headers={"Authorization": f"Bearer {token}"}
)
def pretty_log(console, cls, message):
emojis = {
"ok": "sparkles",
"created": "white_check_mark",
}
console.print(f"[blue]keycloak:[/blue] :{emojis[cls]}: {message}")
def main():
token = get_admin_token()
console = rich.get_console()
if not realm_exists(token):
create_realm(token)
pretty_log(console, "created", f"Realm '{REALM_NAME}' created.")
else:
pretty_log(console, "ok", f"Realm '{REALM_NAME}' already exists.")
if not client_exists(token):
create_client(token)
pretty_log(console, "created", f"Client '{CLIENT_NAME}' created.")
else:
pretty_log(console, "ok", f"Client '{CLIENT_NAME}' already exists.")
if not user_exists(token):
create_user(token)
pretty_log(console, "created", f"User '{USERNAME}' created.")
else:
pretty_log(console, "ok", f"User '{USERNAME}' already exists.")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment