Skip to content

Commit

Permalink
refactor: Clean separation of auth modes supported by provider and UI
Browse files Browse the repository at this point in the history
We used the auth modes supported by the UI to define the list of auth
modes supported by provider endpoints, which was confusing.

Also, print a log message when the UI doesn't support an authentication
mode which is supported by the provider, instead of returning an error,
because that's not an error if there are other modes available.
  • Loading branch information
adombeck committed Feb 18, 2025
1 parent d595982 commit 353b666
Showing 1 changed file with 35 additions and 33 deletions.
68 changes: 35 additions & 33 deletions internal/broker/broker.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,15 +210,13 @@ func (b *Broker) connectToOIDCServer(ctx context.Context) (*oidc.Provider, error
}

// GetAuthenticationModes returns the authentication modes available for the user.
func (b *Broker) GetAuthenticationModes(sessionID string, supportedUILayouts []map[string]string) (authModes []map[string]string, err error) {
func (b *Broker) GetAuthenticationModes(sessionID string, supportedUILayouts []map[string]string) (authModesWithLabels []map[string]string, err error) {
session, err := b.getSession(sessionID)
if err != nil {
return nil, err
}

supportedAuthModes := b.supportedAuthModesFromLayout(supportedUILayouts)

// Checks if the token exists in the cache.
// Check if the token exists in the cache.
tokenExists, err := fileutils.FileExists(session.tokenPath)
if err != nil {
log.Warningf(context.Background(), "Could not check if token exists: %v", err)
Expand All @@ -231,37 +229,26 @@ func (b *Broker) GetAuthenticationModes(sessionID string, supportedUILayouts []m
}
}

endpoints := make(map[string]struct{})
if session.oidcServer != nil && session.oidcServer.Endpoint().DeviceAuthURL != "" {
authMode := authmodes.DeviceQr
if _, ok := supportedAuthModes[authMode]; ok {
endpoints[authMode] = struct{}{}
}
authMode = authmodes.Device
if _, ok := supportedAuthModes[authMode]; ok {
endpoints[authMode] = struct{}{}
}
}

availableModes, err := b.availableAuthModes(session, tokenExists, endpoints)
availableModes, err := b.availableAuthModes(session, tokenExists)
if err != nil {
return nil, err
}

modesSupportedByUI := b.authModesSupportedByUI(supportedUILayouts)

for _, mode := range availableModes {
if _, ok := supportedAuthModes[mode]; !ok {
return nil, fmt.Errorf("auth mode %q required by the provider, but is not supported locally", mode)
if _, ok := modesSupportedByUI[mode]; !ok {
log.Infof(context.Background(), "Authentication mode %q is not supported by the UI", mode)
continue
}
}

for _, id := range availableModes {
authModes = append(authModes, map[string]string{
"id": id,
"label": supportedAuthModes[id],
authModesWithLabels = append(authModesWithLabels, map[string]string{
"id": mode,
"label": modesSupportedByUI[mode],
})
}

if len(authModes) == 0 {
if len(authModesWithLabels) == 0 {
return nil, fmt.Errorf("no authentication modes available for user %q", session.username)
}

Expand All @@ -270,10 +257,10 @@ func (b *Broker) GetAuthenticationModes(sessionID string, supportedUILayouts []m
return nil, err
}

return authModes, nil
return authModesWithLabels, nil
}

func (b *Broker) availableAuthModes(session session, tokenExists bool, endpoints map[string]struct{}) (availableModes []string, err error) {
func (b *Broker) availableAuthModes(session session, tokenExists bool) (availableModes []string, err error) {
switch session.mode {
case sessionmode.ChangePassword, sessionmode.ChangePasswordOld:
// session is for changing the password
Expand All @@ -287,11 +274,7 @@ func (b *Broker) availableAuthModes(session session, tokenExists bool, endpoints

default: // session is for login
if !session.isOffline {
for _, mode := range b.provider.SupportedOIDCAuthModes() {
if _, ok := endpoints[mode]; ok {
availableModes = append(availableModes, mode)
}
}
availableModes = b.oidcAuthModes(session)
}
if tokenExists {
availableModes = append([]string{authmodes.Password}, availableModes...)
Expand All @@ -303,7 +286,26 @@ func (b *Broker) availableAuthModes(session session, tokenExists bool, endpoints
return availableModes, nil
}

func (b *Broker) supportedAuthModesFromLayout(supportedUILayouts []map[string]string) (supportedModes map[string]string) {
func (b *Broker) oidcAuthModes(session session) []string {
var modes []string
endpoints := make(map[string]struct{})
if session.oidcServer != nil && session.oidcServer.Endpoint().DeviceAuthURL != "" {
endpoints[authmodes.DeviceQr] = struct{}{}
endpoints[authmodes.Device] = struct{}{}
}

for _, mode := range b.provider.SupportedOIDCAuthModes() {
if _, ok := endpoints[mode]; ok {
modes = append(modes, mode)
} else {
log.Warningf(context.Background(), "No provider endpoint for mode %q", mode)
}
}

return modes
}

func (b *Broker) authModesSupportedByUI(supportedUILayouts []map[string]string) (supportedModes map[string]string) {
supportedModes = make(map[string]string)
for _, layout := range supportedUILayouts {
supportedEntries := strings.Split(strings.TrimPrefix(layout["entry"], "optional:"), ",")
Expand Down

0 comments on commit 353b666

Please sign in to comment.