16212: Add clues/details to authentication error messages.
[arvados.git] / lib / controller / localdb / login.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package localdb
6
7 import (
8         "context"
9         "errors"
10
11         "git.arvados.org/arvados.git/sdk/go/arvados"
12 )
13
14 type loginController interface {
15         Login(ctx context.Context, opts arvados.LoginOptions) (arvados.LoginResponse, error)
16         Logout(ctx context.Context, opts arvados.LogoutOptions) (arvados.LogoutResponse, error)
17         UserAuthenticate(ctx context.Context, options arvados.UserAuthenticateOptions) (arvados.APIClientAuthorization, error)
18 }
19
20 func chooseLoginController(cluster *arvados.Cluster, railsProxy *railsProxy) loginController {
21         wantGoogle := cluster.Login.GoogleClientID != ""
22         wantSSO := cluster.Login.ProviderAppID != ""
23         wantPAM := cluster.Login.PAM
24         switch {
25         case wantGoogle && !wantSSO && !wantPAM:
26                 return &googleLoginController{Cluster: cluster, RailsProxy: railsProxy}
27         case !wantGoogle && wantSSO && !wantPAM:
28                 return railsProxy
29         case !wantGoogle && !wantSSO && wantPAM:
30                 return &pamLoginController{Cluster: cluster, RailsProxy: railsProxy}
31         default:
32                 return errorLoginController{
33                         error: errors.New("configuration problem: exactly one of Login.GoogleClientID, Login.ProviderAppID, or Login.PAM must be configured"),
34                 }
35         }
36 }
37
38 type errorLoginController struct{ error }
39
40 func (ctrl errorLoginController) Login(context.Context, arvados.LoginOptions) (arvados.LoginResponse, error) {
41         return arvados.LoginResponse{}, ctrl.error
42 }
43 func (ctrl errorLoginController) Logout(context.Context, arvados.LogoutOptions) (arvados.LogoutResponse, error) {
44         return arvados.LogoutResponse{}, ctrl.error
45 }
46 func (ctrl errorLoginController) UserAuthenticate(context.Context, arvados.UserAuthenticateOptions) (arvados.APIClientAuthorization, error) {
47         return arvados.APIClientAuthorization{}, ctrl.error
48 }
49
50 func noopLogout(cluster *arvados.Cluster, opts arvados.LogoutOptions) (arvados.LogoutResponse, error) {
51         target := opts.ReturnTo
52         if target == "" {
53                 if cluster.Services.Workbench2.ExternalURL.Host != "" {
54                         target = cluster.Services.Workbench2.ExternalURL.String()
55                 } else {
56                         target = cluster.Services.Workbench1.ExternalURL.String()
57                 }
58         }
59         return arvados.LogoutResponse{RedirectLocation: target}, nil
60 }