X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/dfeee281597cef5539f8c78bc249a6c9bfc19c18..22fcc610c13c817c415cff26f2c94c17f271e4d3:/lib/controller/localdb/login_oidc.go?ds=sidebyside diff --git a/lib/controller/localdb/login_oidc.go b/lib/controller/localdb/login_oidc.go index 2da7ca5ccf..a5fe45181b 100644 --- a/lib/controller/localdb/login_oidc.go +++ b/lib/controller/localdb/login_oidc.go @@ -22,7 +22,6 @@ import ( "time" "git.arvados.org/arvados.git/lib/controller/api" - "git.arvados.org/arvados.git/lib/controller/railsproxy" "git.arvados.org/arvados.git/lib/controller/rpc" "git.arvados.org/arvados.git/lib/ctrlctx" "git.arvados.org/arvados.git/sdk/go/arvados" @@ -38,15 +37,16 @@ import ( "google.golang.org/api/people/v1" ) -const ( +var ( tokenCacheSize = 1000 tokenCacheNegativeTTL = time.Minute * 5 tokenCacheTTL = time.Minute * 10 + tokenCacheRaceWindow = time.Minute ) type oidcLoginController struct { Cluster *arvados.Cluster - RailsProxy *railsProxy + Parent *Conn Issuer string // OIDC issuer URL, e.g., "https://accounts.google.com" ClientID string ClientSecret string @@ -143,7 +143,7 @@ func (ctrl *oidcLoginController) Login(ctx context.Context, opts arvados.LoginOp return loginError(err) } ctxRoot := auth.NewContext(ctx, &auth.Credentials{Tokens: []string{ctrl.Cluster.SystemRootToken}}) - return ctrl.RailsProxy.UserSessionCreate(ctxRoot, rpc.UserSessionCreateOptions{ + return ctrl.Parent.UserSessionCreate(ctxRoot, rpc.UserSessionCreateOptions{ ReturnTo: state.Remote + "," + state.ReturnTo, AuthInfo: *authinfo, }) @@ -322,7 +322,7 @@ func OIDCAccessTokenAuthorizer(cluster *arvados.Cluster, getdb func(context.Cont // We want ctrl to be nil if the chosen controller is not a // *oidcLoginController, so we can ignore the 2nd return value // of this type cast. - ctrl, _ := chooseLoginController(cluster, railsproxy.NewConn(cluster)).(*oidcLoginController) + ctrl, _ := NewConn(cluster).loginController.(*oidcLoginController) cache, err := lru.New2Q(tokenCacheSize) if err != nil { panic(err) @@ -364,8 +364,9 @@ func (ta *oidcTokenAuthorizer) WrapCalls(origFunc api.RoutableFunc) api.Routable return origFunc(ctx, opts) } // Check each token in the incoming request. If any - // are OAuth2 access tokens, swap them out for Arvados - // tokens. + // are valid OAuth2 access tokens, insert/update them + // in the database so RailsAPI's auth code accepts + // them. for _, tok := range creds.Tokens { err = ta.registerToken(ctx, tok) if err != nil { @@ -390,9 +391,8 @@ func (ta *oidcTokenAuthorizer) registerToken(ctx context.Context, tok string) er // cached negative result (value is expiry time) if time.Now().Before(exp) { return nil - } else { - ta.cache.Remove(tok) } + ta.cache.Remove(tok) } else { // cached positive result aca := cached.(arvados.APIClientAuthorization) @@ -465,7 +465,7 @@ func (ta *oidcTokenAuthorizer) registerToken(ctx context.Context, tok string) er // Expiry time for our token is one minute longer than our // cache TTL, so we don't pass it through to RailsAPI just as // it's expiring. - exp := time.Now().UTC().Add(tokenCacheTTL + time.Minute) + exp := time.Now().UTC().Add(tokenCacheTTL + tokenCacheRaceWindow) var aca arvados.APIClientAuthorization if updating { @@ -475,7 +475,7 @@ func (ta *oidcTokenAuthorizer) registerToken(ctx context.Context, tok string) er } ctxlog.FromContext(ctx).WithField("HMAC", hmac).Debug("(*oidcTokenAuthorizer)registerToken: updated api_client_authorizations row") } else { - aca, err = createAPIClientAuthorization(ctx, ta.ctrl.RailsProxy, ta.ctrl.Cluster.SystemRootToken, *authinfo) + aca, err = ta.ctrl.Parent.CreateAPIClientAuthorization(ctx, ta.ctrl.Cluster.SystemRootToken, *authinfo) if err != nil { return err } @@ -490,6 +490,7 @@ func (ta *oidcTokenAuthorizer) registerToken(ctx context.Context, tok string) er if err != nil { return err } + aca.ExpiresAt = exp.Format(time.RFC3339Nano) ta.cache.Add(tok, aca) return nil }