Skip to content

Commit 15d7b4e

Browse files
authored
Add Get/Update Authentication Flow (Nerzal#398)
* build(docker-compose.yml): adding healthcheck * feat(client.go): adding update/get authentication flow * fix(docker-compose.yml): changing true to string
1 parent b2ed4a5 commit 15d7b4e

File tree

4 files changed

+71
-18
lines changed

4 files changed

+71
-18
lines changed

README.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,14 @@ type GoCloak interface {
342342
MoveCredentialBehind(ctx context.Context, token, realm, userID, credentialID, newPreviousCredentialID string) error
343343
MoveCredentialToFirst(ctx context.Context, token, realm, userID, credentialID string) error
344344

345-
// *** Identity Providers ***
345+
// *** Authentication Flows ***
346+
GetAuthenticationFlows(ctx context.Context, token, realm string) ([]*AuthenticationFlowRepresentation, error)
347+
GetAuthenticationFlow(ctx context.Context, token, realm string, authenticationFlowID string) (*AuthenticationFlowRepresentation, error)
348+
CreateAuthenticationFlow(ctx context.Context, token, realm string, flow AuthenticationFlowRepresentation) error
349+
UpdateAuthenticationFlow(ctx context.Context, token, realm string, flow AuthenticationFlowRepresentation, authenticationFlowID string) (*AuthenticationFlowRepresentation, error)
350+
DeleteAuthenticationFlow(ctx context.Context, token, realm, flowID string) error
351+
352+
// *** Identity Providers ***
346353

347354
CreateIdentityProvider(ctx context.Context, token, realm string, providerRep IdentityProviderRepresentation) (string, error)
348355
GetIdentityProvider(ctx context.Context, token, realm, alias string) (*IdentityProviderRepresentation, error)

client.go

+28
Original file line numberDiff line numberDiff line change
@@ -2365,6 +2365,20 @@ func (g *GoCloak) GetAuthenticationFlows(ctx context.Context, token, realm strin
23652365
return result, nil
23662366
}
23672367

2368+
// GetAuthenticationFlow get an authentication flow with the given ID
2369+
func (g *GoCloak) GetAuthenticationFlow(ctx context.Context, token, realm string, authenticationFlowID string) (*AuthenticationFlowRepresentation, error) {
2370+
const errMessage = "could not retrieve authentication flows"
2371+
var result *AuthenticationFlowRepresentation
2372+
resp, err := g.getRequestWithBearerAuth(ctx, token).
2373+
SetResult(&result).
2374+
Get(g.getAdminRealmURL(realm, "authentication", "flows", authenticationFlowID))
2375+
2376+
if err := checkForError(resp, err, errMessage); err != nil {
2377+
return nil, err
2378+
}
2379+
return result, nil
2380+
}
2381+
23682382
// CreateAuthenticationFlow creates a new Authentication flow in a realm
23692383
func (g *GoCloak) CreateAuthenticationFlow(ctx context.Context, token, realm string, flow AuthenticationFlowRepresentation) error {
23702384
const errMessage = "could not create authentication flows"
@@ -2376,6 +2390,20 @@ func (g *GoCloak) CreateAuthenticationFlow(ctx context.Context, token, realm str
23762390
return checkForError(resp, err, errMessage)
23772391
}
23782392

2393+
// UpdateAuthenticationFlow a given Authentication Flow
2394+
func (g *GoCloak) UpdateAuthenticationFlow(ctx context.Context, token, realm string, flow AuthenticationFlowRepresentation, authenticationFlowID string) (*AuthenticationFlowRepresentation, error) {
2395+
const errMessage = "could not create authentication flows"
2396+
var result *AuthenticationFlowRepresentation
2397+
resp, err := g.getRequestWithBearerAuth(ctx, token).
2398+
SetResult(&result).SetBody(flow).
2399+
Put(g.getAdminRealmURL(realm, "authentication", "flows", authenticationFlowID))
2400+
2401+
if err = checkForError(resp, err, errMessage); err != nil {
2402+
return nil, err
2403+
}
2404+
return result, nil
2405+
}
2406+
23792407
// DeleteAuthenticationFlow deletes a flow in a realm with the given ID
23802408
func (g *GoCloak) DeleteAuthenticationFlow(ctx context.Context, token, realm, flowID string) error {
23812409
const errMessage = "could not delete authentication flows"

client_test.go

+29-17
Original file line numberDiff line numberDiff line change
@@ -6534,6 +6534,7 @@ func TestGocloak_CreateAuthenticationFlowsAndCreateAuthenticationExecutionAndFlo
65346534
Description: gocloak.StringP("my test description"),
65356535
TopLevel: gocloak.BoolP(true),
65366536
ProviderID: gocloak.StringP("basic-flow"),
6537+
ID: gocloak.StringP("testauthflow2id"),
65376538
}
65386539

65396540
authExecFlow := gocloak.CreateAuthenticationExecutionFlowRepresentation{
@@ -6632,23 +6633,34 @@ func TestGocloak_CreateAuthenticationFlowsAndCreateAuthenticationExecutionAndFlo
66326633
require.True(t, execDeleted, "Failed to delete authentication execution, no execution was deleted")
66336634
require.True(t, execFlowFound, "Failed to find authentication execution flow")
66346635

6635-
flows, err := client.GetAuthenticationFlows(context.Background(), token.AccessToken, cfg.GoCloak.Realm)
6636-
require.NoError(t, err, "Failed to get authentication flows")
6637-
deleted := false
6638-
for _, flow := range flows {
6639-
if flow.Alias != nil && *flow.Alias == "testauthflow2" {
6640-
err = client.DeleteAuthenticationFlow(
6641-
context.Background(),
6642-
token.AccessToken,
6643-
cfg.GoCloak.Realm,
6644-
*flow.ID,
6645-
)
6646-
require.NoError(t, err, "Failed to delete authentication flow")
6647-
deleted = true
6648-
break
6649-
}
6650-
}
6651-
require.True(t, deleted, "Failed to delete authentication flow, no flow was deleted")
6636+
authFlow.Description = gocloak.StringP("my-new-description")
6637+
_, err = client.UpdateAuthenticationFlow(
6638+
context.Background(),
6639+
token.AccessToken,
6640+
cfg.GoCloak.Realm,
6641+
authFlow,
6642+
*authFlow.ID,
6643+
)
6644+
6645+
require.NoError(t, err, "Failed to update authentication flow")
6646+
t.Logf("updated authentication flow: %+v", authFlow)
6647+
6648+
retrievedAuthFlow, err := client.GetAuthenticationFlow(
6649+
context.Background(),
6650+
token.AccessToken,
6651+
cfg.GoCloak.Realm,
6652+
*authFlow.ID,
6653+
)
6654+
require.NoError(t, err, "Failed to fetch authentication flow")
6655+
t.Logf("retrieved authentication flow: %+v", retrievedAuthFlow)
6656+
require.Equal(t, "my-new-description", gocloak.PString(retrievedAuthFlow.Description))
6657+
err = client.DeleteAuthenticationFlow(
6658+
context.Background(),
6659+
token.AccessToken,
6660+
cfg.GoCloak.Realm,
6661+
*retrievedAuthFlow.ID,
6662+
)
6663+
require.NoError(t, err, "Failed to delete authentication flow")
66526664
}
66536665

66546666
func TestGocloak_CreateAndGetRequiredAction(t *testing.T) {

docker-compose.yml

+6
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@ services:
99
KEYCLOAK_PASSWORD: secret
1010
KEYCLOAK_ADMIN: admin
1111
KEYCLOAK_ADMIN_PASSWORD: secret
12+
KC_HEALTH_ENABLED: "true"
1213
ports:
1314
- "8080:8080"
15+
healthcheck:
16+
test: curl --fail --silent http://localhost:8080/health/ready 2>&1 || exit 1
17+
interval: 10s
18+
timeout: 10s
19+
retries: 5
1420
volumes:
1521
- ./testdata/gocloak-realm.json:/opt/keycloak/data/import/gocloak-realm.json
1622
entrypoint: ["/opt/keycloak/bin/kc.sh", "start-dev --features=preview --import-realm"]

0 commit comments

Comments
 (0)