Skip to content

Commit eadca4b

Browse files
committed
rework challenge handling to expect exactly one challenge
Signed-off-by: Ashley Davis <[email protected]>
1 parent cbb3aeb commit eadca4b

File tree

1 file changed

+24
-23
lines changed

1 file changed

+24
-23
lines changed

pkg/internal/cyberark/identity/identity.go

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,8 @@ type advanceAuthenticationResponseResult struct {
172172
// Other fields omitted as they're not needed
173173
}
174174

175-
// Client is an client for interacting with the CyberArk Identity API and performing a login
175+
// Client is an client for interacting with the CyberArk Identity API and performing a login using a username and password.
176+
// For context on the behaviour of this client, see the Pytho SDK: https://github.com/cyberark/ark-sdk-python/blob/3be12c3f2d3a2d0407025028943e584b6edc5996/ark_sdk_python/auth/identity/ark_identity.py
176177
type Client struct {
177178
client *http.Client
178179

@@ -331,41 +332,41 @@ func (c *Client) doStartAuthentication(ctx context.Context, username string) (ad
331332
klog.FromContext(ctx).Info("got an unexpected Summary from StartAuthentication response; will attempt to complete a login challenge anyway", "summary", startAuthResponse.Result.Summary)
332333
}
333334

334-
if len(startAuthResponse.Result.Challenges) == 0 {
335+
// We can only handle a UP type challenge, and if there are any other challenges, we'll have to fail because we can't handle them.
336+
// https://github.com/cyberark/ark-sdk-python/blob/3be12c3f2d3a2d0407025028943e584b6edc5996/ark_sdk_python/auth/identity/ark_identity.py#L405
337+
switch len(startAuthResponse.Result.Challenges) {
338+
case 0:
335339
return response, fmt.Errorf("got no valid challenges in response to start authentication; unable to log in")
336-
}
337340

338-
mechanismID := ""
341+
case 1:
342+
// do nothing, this is ideal
339343

340-
for i, challenge := range startAuthResponse.Result.Challenges {
341-
logger.V(logs.Debug).Info("found a challenge", "idx", i, "mechanismCount", len(challenge.Mechanisms))
344+
default:
345+
return response, fmt.Errorf("got %d challenges in response to start authentication, which means MFA may be enabled; unable to log in", len(startAuthResponse.Result.Challenges))
346+
}
342347

343-
if len(challenge.Mechanisms) == 0 {
344-
// presumably this shouldn't happen, but handle the case anyway
345-
logger.Info("got no mechanisms for challenge from Identity server; skipping this challenge")
346-
continue
347-
}
348+
challenge := startAuthResponse.Result.Challenges[0]
348349

349-
for j, mechanism := range challenge.Mechanisms {
350-
logger.V(logs.Debug).Info("found a mechanism in challenge", "idx", j, "enrolled", mechanism.Enrolled, "name", mechanism.Name)
350+
switch len(challenge.Mechanisms) {
351+
case 0:
352+
// presumably this shouldn't happen, but handle the case anyway
353+
return response, fmt.Errorf("got no mechanisms for challenge from Identity server")
351354

352-
if !mechanism.Enrolled || mechanism.Name != MechanismUsernamePassword {
353-
continue
354-
}
355+
case 1:
356+
// do nothing, this is ideal
355357

356-
// got a username/password mechanism, so use it
357-
mechanismID = mechanism.MechanismID
358-
break
359-
}
358+
default:
359+
return response, fmt.Errorf("got %d mechanisms in response to start authentication, which means MFA may be enabled; unable to log in", len(challenge.Mechanisms))
360360
}
361361

362-
if mechanismID == "" {
363-
klog.FromContext(ctx).Info("ctx", "response", startAuthResponse)
362+
mechanism := challenge.Mechanisms[0]
363+
364+
if !mechanism.Enrolled || mechanism.Name != MechanismUsernamePassword {
364365
return response, errNoUPMechanism
365366
}
366367

367368
response.Action = ActionAnswer
368-
response.MechanismID = mechanismID
369+
response.MechanismID = mechanism.MechanismID
369370
response.SessionID = startAuthResponse.Result.SessionID
370371
response.TenantID = c.subdomain
371372
response.PersistantLogin = true

0 commit comments

Comments
 (0)