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 Get/Update Authentication Flow #398

Merged
merged 3 commits into from
Feb 15, 2023
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
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,14 @@ type GoCloak interface {
MoveCredentialBehind(ctx context.Context, token, realm, userID, credentialID, newPreviousCredentialID string) error
MoveCredentialToFirst(ctx context.Context, token, realm, userID, credentialID string) error

// *** Identity Providers ***
// *** Authentication Flows ***
GetAuthenticationFlows(ctx context.Context, token, realm string) ([]*AuthenticationFlowRepresentation, error)
GetAuthenticationFlow(ctx context.Context, token, realm string, authenticationFlowID string) (*AuthenticationFlowRepresentation, error)
CreateAuthenticationFlow(ctx context.Context, token, realm string, flow AuthenticationFlowRepresentation) error
UpdateAuthenticationFlow(ctx context.Context, token, realm string, flow AuthenticationFlowRepresentation, authenticationFlowID string) (*AuthenticationFlowRepresentation, error)
DeleteAuthenticationFlow(ctx context.Context, token, realm, flowID string) error

// *** Identity Providers ***

CreateIdentityProvider(ctx context.Context, token, realm string, providerRep IdentityProviderRepresentation) (string, error)
GetIdentityProvider(ctx context.Context, token, realm, alias string) (*IdentityProviderRepresentation, error)
Expand Down
28 changes: 28 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2365,6 +2365,20 @@ func (g *GoCloak) GetAuthenticationFlows(ctx context.Context, token, realm strin
return result, nil
}

// GetAuthenticationFlow get an authentication flow with the given ID
func (g *GoCloak) GetAuthenticationFlow(ctx context.Context, token, realm string, authenticationFlowID string) (*AuthenticationFlowRepresentation, error) {
const errMessage = "could not retrieve authentication flows"
var result *AuthenticationFlowRepresentation
resp, err := g.getRequestWithBearerAuth(ctx, token).
SetResult(&result).
Get(g.getAdminRealmURL(realm, "authentication", "flows", authenticationFlowID))

if err := checkForError(resp, err, errMessage); err != nil {
return nil, err
}
return result, nil
}

// CreateAuthenticationFlow creates a new Authentication flow in a realm
func (g *GoCloak) CreateAuthenticationFlow(ctx context.Context, token, realm string, flow AuthenticationFlowRepresentation) error {
const errMessage = "could not create authentication flows"
Expand All @@ -2376,6 +2390,20 @@ func (g *GoCloak) CreateAuthenticationFlow(ctx context.Context, token, realm str
return checkForError(resp, err, errMessage)
}

// UpdateAuthenticationFlow a given Authentication Flow
func (g *GoCloak) UpdateAuthenticationFlow(ctx context.Context, token, realm string, flow AuthenticationFlowRepresentation, authenticationFlowID string) (*AuthenticationFlowRepresentation, error) {
const errMessage = "could not create authentication flows"
var result *AuthenticationFlowRepresentation
resp, err := g.getRequestWithBearerAuth(ctx, token).
SetResult(&result).SetBody(flow).
Put(g.getAdminRealmURL(realm, "authentication", "flows", authenticationFlowID))

if err = checkForError(resp, err, errMessage); err != nil {
return nil, err
}
return result, nil
}

// DeleteAuthenticationFlow deletes a flow in a realm with the given ID
func (g *GoCloak) DeleteAuthenticationFlow(ctx context.Context, token, realm, flowID string) error {
const errMessage = "could not delete authentication flows"
Expand Down
46 changes: 29 additions & 17 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6524,6 +6524,7 @@ func TestGocloak_CreateAuthenticationFlowsAndCreateAuthenticationExecutionAndFlo
Description: gocloak.StringP("my test description"),
TopLevel: gocloak.BoolP(true),
ProviderID: gocloak.StringP("basic-flow"),
ID: gocloak.StringP("testauthflow2id"),
}

authExecFlow := gocloak.CreateAuthenticationExecutionFlowRepresentation{
Expand Down Expand Up @@ -6622,23 +6623,34 @@ func TestGocloak_CreateAuthenticationFlowsAndCreateAuthenticationExecutionAndFlo
require.True(t, execDeleted, "Failed to delete authentication execution, no execution was deleted")
require.True(t, execFlowFound, "Failed to find authentication execution flow")

flows, err := client.GetAuthenticationFlows(context.Background(), token.AccessToken, cfg.GoCloak.Realm)
require.NoError(t, err, "Failed to get authentication flows")
deleted := false
for _, flow := range flows {
if flow.Alias != nil && *flow.Alias == "testauthflow2" {
err = client.DeleteAuthenticationFlow(
context.Background(),
token.AccessToken,
cfg.GoCloak.Realm,
*flow.ID,
)
require.NoError(t, err, "Failed to delete authentication flow")
deleted = true
break
}
}
require.True(t, deleted, "Failed to delete authentication flow, no flow was deleted")
authFlow.Description = gocloak.StringP("my-new-description")
_, err = client.UpdateAuthenticationFlow(
context.Background(),
token.AccessToken,
cfg.GoCloak.Realm,
authFlow,
*authFlow.ID,
)

require.NoError(t, err, "Failed to update authentication flow")
t.Logf("updated authentication flow: %+v", authFlow)

retrievedAuthFlow, err := client.GetAuthenticationFlow(
context.Background(),
token.AccessToken,
cfg.GoCloak.Realm,
*authFlow.ID,
)
require.NoError(t, err, "Failed to fetch authentication flow")
t.Logf("retrieved authentication flow: %+v", retrievedAuthFlow)
require.Equal(t, "my-new-description", gocloak.PString(retrievedAuthFlow.Description))
err = client.DeleteAuthenticationFlow(
context.Background(),
token.AccessToken,
cfg.GoCloak.Realm,
*retrievedAuthFlow.ID,
)
require.NoError(t, err, "Failed to delete authentication flow")
}

func TestGocloak_CreateAndGetRequiredAction(t *testing.T) {
Expand Down
6 changes: 6 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,14 @@ services:
KEYCLOAK_PASSWORD: secret
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: secret
KC_HEALTH_ENABLED: "true"
ports:
- "8080:8080"
healthcheck:
test: curl --fail --silent http://localhost:8080/health/ready 2>&1 || exit 1
interval: 10s
timeout: 10s
retries: 5
volumes:
- ./testdata/gocloak-realm.json:/opt/keycloak/data/import/gocloak-realm.json
entrypoint: ["/opt/keycloak/bin/kc.sh", "start-dev --features=preview --import-realm"]
Expand Down