X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/2f66d4cc05e9442a9bb69969744d0750a02a1ed4..8227b8a1be943fbbf3adb23a3d549dec28efbbba:/lib/controller/localdb/conn.go diff --git a/lib/controller/localdb/conn.go b/lib/controller/localdb/conn.go index ac092382d4..a90deded59 100644 --- a/lib/controller/localdb/conn.go +++ b/lib/controller/localdb/conn.go @@ -6,7 +6,8 @@ package localdb import ( "context" - "errors" + "fmt" + "strings" "git.arvados.org/arvados.git/lib/controller/railsproxy" "git.arvados.org/arvados.git/lib/controller/rpc" @@ -18,35 +19,80 @@ type railsProxy = rpc.Conn type Conn struct { cluster *arvados.Cluster *railsProxy // handles API methods that aren't defined on Conn itself - - googleLoginController + loginController } func NewConn(cluster *arvados.Cluster) *Conn { - return &Conn{ + railsProxy := railsproxy.NewConn(cluster) + railsProxy.RedactHostInErrors = true + var conn Conn + conn = Conn{ cluster: cluster, - railsProxy: railsproxy.NewConn(cluster), + railsProxy: railsProxy, } + conn.loginController = chooseLoginController(cluster, &conn) + return &conn } +// Logout handles the logout of conn giving to the appropriate loginController func (conn *Conn) Logout(ctx context.Context, opts arvados.LogoutOptions) (arvados.LogoutResponse, error) { - if conn.cluster.Login.ProviderAppID != "" { - // Proxy to RailsAPI, which hands off to sso-provider. - return conn.railsProxy.Logout(ctx, opts) - } else { - return conn.googleLoginController.Logout(ctx, conn.cluster, conn.railsProxy, opts) - } + return conn.loginController.Logout(ctx, opts) } +// Login handles the login of conn giving to the appropriate loginController func (conn *Conn) Login(ctx context.Context, opts arvados.LoginOptions) (arvados.LoginResponse, error) { - wantGoogle := conn.cluster.Login.GoogleClientID != "" - wantSSO := conn.cluster.Login.ProviderAppID != "" - if wantGoogle == wantSSO { - return arvados.LoginResponse{}, errors.New("configuration problem: exactly one of Login.GoogleClientID and Login.ProviderAppID must be configured") - } else if wantGoogle { - return conn.googleLoginController.Login(ctx, conn.cluster, conn.railsProxy, opts) - } else { - // Proxy to RailsAPI, which hands off to sso-provider. - return conn.railsProxy.Login(ctx, opts) + return conn.loginController.Login(ctx, opts) +} + +// UserAuthenticate handles the User Authentication of conn giving to the appropriate loginController +func (conn *Conn) UserAuthenticate(ctx context.Context, opts arvados.UserAuthenticateOptions) (arvados.APIClientAuthorization, error) { + return conn.loginController.UserAuthenticate(ctx, opts) +} + +func (conn *Conn) GroupContents(ctx context.Context, options arvados.GroupContentsOptions) (arvados.ObjectList, error) { + // The requested UUID can be a user (virtual home project), which we just pass on to + // the API server. + if strings.Index(options.UUID, "-j7d0g-") != 5 { + return conn.railsProxy.GroupContents(ctx, options) } + + var resp arvados.ObjectList + + // Get the group object + respGroup, err := conn.GroupGet(ctx, arvados.GetOptions{UUID: options.UUID}) + if err != nil { + return resp, err + } + + // If the group has groupClass 'filter', apply the filters before getting the contents. + if respGroup.GroupClass == "filter" { + if filters, ok := respGroup.Properties["filters"].([]interface{}); ok { + for _, f := range filters { + // f is supposed to be a []string + tmp, ok2 := f.([]interface{}) + if !ok2 || len(tmp) < 3 { + return resp, fmt.Errorf("filter unparsable: %T, %+v, original field: %T, %+v\n", tmp, tmp, f, f) + } + var filter arvados.Filter + if attr, ok2 := tmp[0].(string); ok2 { + filter.Attr = attr + } else { + return resp, fmt.Errorf("filter unparsable: attribute must be string: %T, %+v, filter: %T, %+v\n", tmp[0], tmp[0], f, f) + } + if operator, ok2 := tmp[1].(string); ok2 { + filter.Operator = operator + } else { + return resp, fmt.Errorf("filter unparsable: operator must be string: %T, %+v, filter: %T, %+v\n", tmp[1], tmp[1], f, f) + } + filter.Operand = tmp[2] + options.Filters = append(options.Filters, filter) + } + } else { + return resp, fmt.Errorf("filter unparsable: not an array\n") + } + // Use the generic /groups/contents endpoint for filter groups + options.UUID = "" + } + + return conn.railsProxy.GroupContents(ctx, options) }