Gå til indholdet

Kodeeksempler

Denne side viser komplette eksempler på de mest brugte operationer. Alle eksempler bruger stage-miljøet.


Hent access token

curl -X POST "https://login.vconf-stage.dk/auth/realms/broker/protocol/openid-connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=din-klient-id" \
  -d "client_secret=din-klient-secret"
import requests

token_url = "https://login.vconf-stage.dk/auth/realms/broker/protocol/openid-connect/token"

response = requests.post(token_url, data={
    "grant_type": "client_credentials",
    "client_id": "din-klient-id",
    "client_secret": "din-klient-secret",
})

access_token = response.json()["access_token"]
using var httpClient = new HttpClient();

var tokenRequest = new FormUrlEncodedContent(new Dictionary<string, string>
{
    ["grant_type"] = "client_credentials",
    ["client_id"] = "din-klient-id",
    ["client_secret"] = "din-klient-secret"
});

var tokenResponse = await httpClient.PostAsync(
    "https://login.vconf-stage.dk/auth/realms/broker/protocol/openid-connect/token",
    tokenRequest);

var tokenJson = await tokenResponse.Content.ReadFromJsonAsync<JsonDocument>();
var accessToken = tokenJson!.RootElement.GetProperty("access_token").GetString();

Hent organisation

curl -X GET "https://organisationapi.vconf-stage.dk/v1/organisation" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Accept: application/json"
headers = {
    "Authorization": f"Bearer {access_token}",
    "Accept": "application/json",
}

response = requests.get(
    "https://organisationapi.vconf-stage.dk/v1/organisation",
    headers=headers,
)

organisation = response.json()
print(f"Organisation: {organisation['name']} (rod-gruppe: {organisation['group_id']})")
httpClient.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", accessToken);

var org = await httpClient.GetFromJsonAsync<JsonDocument>(
    "https://organisationapi.vconf-stage.dk/v1/organisation");

var orgName = org!.RootElement.GetProperty("name").GetString();
var rootGroupId = org.RootElement.GetProperty("group_id").GetString();

Hent gruppetræ

curl -X GET "https://organisationapi.vconf-stage.dk/v1/groups/$GROUP_ID/tree?minimal=true" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
response = requests.get(
    f"https://organisationapi.vconf-stage.dk/v1/groups/{root_group_id}/tree",
    headers=headers,
    params={"minimal": "true"},
)

tree = response.json()
var tree = await httpClient.GetFromJsonAsync<JsonDocument>(
    $"https://organisationapi.vconf-stage.dk/v1/groups/{rootGroupId}/tree?minimal=true");

Opret undergruppe

curl -X POST "https://organisationapi.vconf-stage.dk/v1/groups" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Ny Afdeling", "parent_id": "'"$PARENT_GROUP_ID"'"}'
response = requests.post(
    "https://organisationapi.vconf-stage.dk/v1/groups",
    headers=headers,
    json={
        "name": "Ny Afdeling",
        "parent_id": parent_group_id,
    },
)

new_group = response.json()
print(f"Oprettet gruppe: {new_group['id']}")
var createGroupResponse = await httpClient.PostAsJsonAsync(
    "https://organisationapi.vconf-stage.dk/v1/groups",
    new { name = "Ny Afdeling", parent_id = parentGroupId });

var newGroup = await createGroupResponse.Content.ReadFromJsonAsync<JsonDocument>();

Opret lokal bruger

curl -X POST "https://organisationapi.vconf-stage.dk/v1/groups/$GROUP_ID/local-users" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "ny-bruger@example.dk",
    "firstname": "Anders",
    "lastname": "Andersen",
    "password": "SikkerKode123!",
    "role": "user"
  }'
response = requests.post(
    f"https://organisationapi.vconf-stage.dk/v1/groups/{group_id}/local-users",
    headers=headers,
    json={
        "email": "ny-bruger@example.dk",
        "firstname": "Anders",
        "lastname": "Andersen",
        "password": "SikkerKode123!",
        "role": "user",
    },
)

user = response.json()
print(f"Oprettet bruger: {user['id']}")
var createUserResponse = await httpClient.PostAsJsonAsync(
    $"https://organisationapi.vconf-stage.dk/v1/groups/{groupId}/local-users",
    new
    {
        email = "ny-bruger@example.dk",
        firstname = "Anders",
        lastname = "Andersen",
        password = "SikkerKode123!",
        role = "user"
    });

var newUser = await createUserResponse.Content.ReadFromJsonAsync<JsonDocument>();

List brugere med paginering

curl -X GET "https://organisationapi.vconf-stage.dk/v1/groups/$GROUP_ID/local-users?recursive=true&offset=0&limit=100&search=anders" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
all_users = []
offset = 0
limit = 100

while True:
    response = requests.get(
        f"https://organisationapi.vconf-stage.dk/v1/groups/{group_id}/local-users",
        headers=headers,
        params={"recursive": "true", "offset": offset, "limit": limit},
    )
    data = response.json()
    all_users.extend(data["items"])

    if len(data["items"]) < limit:
        break
    offset += limit

print(f"Hentet {len(all_users)} brugere (total: {data['total_count']})")
var allUsers = new List<JsonElement>();
int offset = 0;
const int limit = 100;

while (true)
{
    var page = await httpClient.GetFromJsonAsync<JsonDocument>(
        $"https://organisationapi.vconf-stage.dk/v1/groups/{groupId}/local-users" +
        $"?recursive=true&offset={offset}&limit={limit}");

    var items = page!.RootElement.GetProperty("items");
    foreach (var item in items.EnumerateArray())
        allUsers.Add(item.Clone());

    if (items.GetArrayLength() < limit)
        break;

    offset += limit;
}

Flyt bruger til anden gruppe

curl -X POST "https://organisationapi.vconf-stage.dk/v1/groups/$GROUP_ID/local-users/$USER_ID/move" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"destination_group_id": "'"$DESTINATION_GROUP_ID"'"}'
response = requests.post(
    f"https://organisationapi.vconf-stage.dk/v1/groups/{group_id}/local-users/{user_id}/move",
    headers=headers,
    json={"destination_group_id": destination_group_id},
)

if response.status_code == 204:
    print("Bruger flyttet")
var moveResponse = await httpClient.PostAsJsonAsync(
    $"https://organisationapi.vconf-stage.dk/v1/groups/{groupId}/local-users/{userId}/move",
    new { destination_group_id = destinationGroupId });

if (moveResponse.StatusCode == HttpStatusCode.NoContent)
    Console.WriteLine("Bruger flyttet");

Administrer autorisationer

# Opret autorisation
curl -X POST "https://organisationapi.vconf-stage.dk/v1/groups/$GROUP_ID/authorizations" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"user_email": "admin@example.dk", "role": "group_admin"}'

# Opdater rolle
curl -X PUT "https://organisationapi.vconf-stage.dk/v1/groups/$GROUP_ID/authorizations/$AUTH_ID" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"role": "org_admin"}'

# Slet autorisation
curl -X DELETE "https://organisationapi.vconf-stage.dk/v1/groups/$GROUP_ID/authorizations/$AUTH_ID" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
# Opret
response = requests.post(
    f"https://organisationapi.vconf-stage.dk/v1/groups/{group_id}/authorizations",
    headers=headers,
    json={"user_email": "admin@example.dk", "role": "group_admin"},
)
auth = response.json()

# Opdater
requests.put(
    f"https://organisationapi.vconf-stage.dk/v1/groups/{group_id}/authorizations/{auth['id']}",
    headers=headers,
    json={"role": "org_admin"},
)

# Slet
requests.delete(
    f"https://organisationapi.vconf-stage.dk/v1/groups/{group_id}/authorizations/{auth['id']}",
    headers=headers,
)
// Opret
var authResponse = await httpClient.PostAsJsonAsync(
    $"https://organisationapi.vconf-stage.dk/v1/groups/{groupId}/authorizations",
    new { user_email = "admin@example.dk", role = "group_admin" });
var auth = await authResponse.Content.ReadFromJsonAsync<JsonDocument>();
var authId = auth!.RootElement.GetProperty("id").GetString();

// Opdater
await httpClient.PutAsJsonAsync(
    $"https://organisationapi.vconf-stage.dk/v1/groups/{groupId}/authorizations/{authId}",
    new { role = "org_admin" });

// Slet
await httpClient.DeleteAsync(
    $"https://organisationapi.vconf-stage.dk/v1/groups/{groupId}/authorizations/{authId}");

Fejlhåndtering

response = requests.get(
    f"https://organisationapi.vconf-stage.dk/v1/groups/{group_id}",
    headers=headers,
)

if response.status_code == 200:
    group = response.json()
elif response.status_code == 401:
    # Token udløbet — hent nyt og forsøg igen
    access_token = refresh_token()
    headers["Authorization"] = f"Bearer {access_token}"
elif response.status_code == 403:
    print("Gruppen er uden for klientens scope")
elif response.status_code == 429:
    retry_after = int(response.headers.get("Retry-After", 60))
    time.sleep(retry_after)
else:
    problem = response.json()
    print(f"Fejl {problem['status']}: {problem['title']} — {problem['detail']}")
var response = await httpClient.GetAsync(
    $"https://organisationapi.vconf-stage.dk/v1/groups/{groupId}");

switch (response.StatusCode)
{
    case HttpStatusCode.OK:
        var group = await response.Content.ReadFromJsonAsync<JsonDocument>();
        break;
    case HttpStatusCode.Unauthorized:
        // Hent nyt token og forsøg igen
        break;
    case HttpStatusCode.Forbidden:
        Console.WriteLine("Gruppen er uden for scope");
        break;
    case HttpStatusCode.TooManyRequests:
        var retryAfter = response.Headers.RetryAfter?.Delta ?? TimeSpan.FromSeconds(60);
        await Task.Delay(retryAfter);
        break;
    default:
        var problem = await response.Content.ReadFromJsonAsync<JsonDocument>();
        Console.WriteLine($"Fejl: {problem!.RootElement.GetProperty("detail")}");
        break;
}