diff --git a/extensions/idp/pkg/backends/cs3/bootstrap/cs3.go b/extensions/idp/pkg/backends/cs3/bootstrap/cs3.go new file mode 100644 index 00000000000..964332d5a77 --- /dev/null +++ b/extensions/idp/pkg/backends/cs3/bootstrap/cs3.go @@ -0,0 +1,129 @@ +/* + * Copyright 2021 Kopano and its licensors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package bootstrap + +import ( + "fmt" + "os" + + "github.com/libregraph/lico/bootstrap" + "github.com/libregraph/lico/identifier" + "github.com/libregraph/lico/identity" + "github.com/libregraph/lico/identity/managers" + cs3 "github.com/owncloud/ocis/v2/extensions/idp/pkg/backends/cs3/identifier" +) + +// Identity managers. +const ( + identityManagerName = "cs3" +) + +// Register adds the CS3 identity manager to the lico bootstrap +func Register() error { + return bootstrap.RegisterIdentityManager(identityManagerName, NewIdentityManager) +} + +// MustRegister adds the CS3 identity manager to the lico bootstrap or panics +func MustRegister() { + if err := Register(); err != nil { + panic(err) + } +} + +// NewIdentityManager produces a CS3 backed identity manager instance for the idp +func NewIdentityManager(bs bootstrap.Bootstrap) (identity.Manager, error) { + config := bs.Config() + + logger := config.Config.Logger + + if config.AuthorizationEndpointURI.String() != "" { + return nil, fmt.Errorf("cs3 backend is incompatible with authorization-endpoint-uri parameter") + } + config.AuthorizationEndpointURI.Path = bs.MakeURIPath(bootstrap.APITypeSignin, "/identifier/_/authorize") + + if config.EndSessionEndpointURI.String() != "" { + return nil, fmt.Errorf("cs3 backend is incompatible with endsession-endpoint-uri parameter") + } + config.EndSessionEndpointURI.Path = bs.MakeURIPath(bootstrap.APITypeSignin, "/identifier/_/endsession") + + if config.SignInFormURI.EscapedPath() == "" { + config.SignInFormURI.Path = bs.MakeURIPath(bootstrap.APITypeSignin, "/identifier") + } + + if config.SignedOutURI.EscapedPath() == "" { + config.SignedOutURI.Path = bs.MakeURIPath(bootstrap.APITypeSignin, "/goodbye") + } + + identifierBackend, identifierErr := cs3.NewCS3Backend( + config.Config, + config.TLSClientConfig, + // FIXME add a map[string]interface{} property to the lico config.Config so backends can pass custom config parameters through the bootstrap process + os.Getenv("CS3_GATEWAY"), + os.Getenv("CS3_MACHINE_AUTH_API_KEY"), + config.Settings.Insecure, + ) + if identifierErr != nil { + return nil, fmt.Errorf("failed to create identifier backend: %v", identifierErr) + } + + fullAuthorizationEndpointURL := bootstrap.WithSchemeAndHost(config.AuthorizationEndpointURI, config.IssuerIdentifierURI) + fullSignInFormURL := bootstrap.WithSchemeAndHost(config.SignInFormURI, config.IssuerIdentifierURI) + fullSignedOutEndpointURL := bootstrap.WithSchemeAndHost(config.SignedOutURI, config.IssuerIdentifierURI) + + activeIdentifier, err := identifier.NewIdentifier(&identifier.Config{ + Config: config.Config, + + BaseURI: config.IssuerIdentifierURI, + PathPrefix: bs.MakeURIPath(bootstrap.APITypeSignin, ""), + StaticFolder: config.IdentifierClientPath, + LogonCookieName: "__Secure-KKT", // Kopano-Konnect-Token + ScopesConf: config.IdentifierScopesConf, + WebAppDisabled: config.IdentifierClientDisabled, + + AuthorizationEndpointURI: fullAuthorizationEndpointURL, + SignedOutEndpointURI: fullSignedOutEndpointURL, + + DefaultBannerLogo: config.IdentifierDefaultBannerLogo, + DefaultSignInPageText: config.IdentifierDefaultSignInPageText, + DefaultUsernameHintText: config.IdentifierDefaultUsernameHintText, + UILocales: config.IdentifierUILocales, + + Backend: identifierBackend, + }) + if err != nil { + return nil, fmt.Errorf("failed to create identifier: %v", err) + } + err = activeIdentifier.SetKey(config.EncryptionSecret) + if err != nil { + return nil, fmt.Errorf("invalid --encryption-secret parameter value for identifier: %v", err) + } + + identityManagerConfig := &identity.Config{ + SignInFormURI: fullSignInFormURL, + SignedOutURI: fullSignedOutEndpointURL, + + Logger: logger, + + ScopesSupported: config.Config.AllowedScopes, + } + + identifierIdentityManager := managers.NewIdentifierIdentityManager(identityManagerConfig, activeIdentifier) + logger.Infoln("using identifier backed identity manager") + + return identifierIdentityManager, nil +} diff --git a/extensions/idp/pkg/backends/cs3/identifier/cs3.go b/extensions/idp/pkg/backends/cs3/identifier/cs3.go new file mode 100644 index 00000000000..2370a0734cf --- /dev/null +++ b/extensions/idp/pkg/backends/cs3/identifier/cs3.go @@ -0,0 +1,238 @@ +package cs3 + +import ( + "context" + "crypto/tls" + "fmt" + + cs3gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" + cs3rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" + "github.com/libregraph/lico" + "github.com/libregraph/lico/config" + "github.com/libregraph/lico/identifier/backends" + "github.com/libregraph/lico/identifier/meta/scopes" + "github.com/libregraph/lico/identity" + cmap "github.com/orcaman/concurrent-map" + "github.com/sirupsen/logrus" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + ins "google.golang.org/grpc/credentials/insecure" + "stash.kopano.io/kgol/oidc-go" +) + +const cs3BackendName = "identifier-cs3" + +var cs3SpportedScopes = []string{ + oidc.ScopeProfile, + oidc.ScopeEmail, + lico.ScopeUniqueUserID, + lico.ScopeRawSubject, +} + +// CS3 Backend holds the data for the CS3 identifier backend +type CS3Backend struct { + supportedScopes []string + + logger logrus.FieldLogger + tlsConfig *tls.Config + gatewayURI string + machineAuthAPIKey string + insecure bool + + sessions cmap.ConcurrentMap + + gateway cs3gateway.GatewayAPIClient +} + +// NewCS3Backend creates a new CS3 backend identifier backend +func NewCS3Backend( + c *config.Config, + tlsConfig *tls.Config, + gatewayURI string, + machineAuthAPIKey string, + insecure bool, +) (*CS3Backend, error) { + + // Build supported scopes based on default scopes. + supportedScopes := make([]string, len(cs3SpportedScopes)) + copy(supportedScopes, cs3SpportedScopes) + + b := &CS3Backend{ + supportedScopes: supportedScopes, + + logger: c.Logger, + tlsConfig: tlsConfig, + gatewayURI: gatewayURI, + machineAuthAPIKey: machineAuthAPIKey, + insecure: insecure, + + sessions: cmap.New(), + } + + b.logger.Infoln("cs3 backend connection set up") + + return b, nil +} + +// RunWithContext implements the Backend interface. +func (b *CS3Backend) RunWithContext(ctx context.Context) error { + return nil +} + +// Logon implements the Backend interface, enabling Logon with user name and +// password as provided. Requests are bound to the provided context. +func (b *CS3Backend) Logon(ctx context.Context, audience, username, password string) (bool, *string, *string, backends.UserFromBackend, error) { + + l, err := b.connect(ctx) + if err != nil { + return false, nil, nil, nil, fmt.Errorf("cs3 backend logon connect error: %v", err) + } + defer l.Close() + + client := cs3gateway.NewGatewayAPIClient(l) + + res, err := client.Authenticate(ctx, &cs3gateway.AuthenticateRequest{ + Type: "basic", + ClientId: username, + ClientSecret: password, + }) + if err != nil { + return false, nil, nil, nil, fmt.Errorf("cs3 backend basic authenticate rpc error: %v", err) + } + if res.Status.Code != cs3rpc.Code_CODE_OK { + return false, nil, nil, nil, fmt.Errorf("cs3 backend basic authenticate failed with code %s: %s", res.Status.Code.String(), res.Status.Message) + } + + session := createSession(ctx, res.User) + + user, err := newCS3User(res.User) + if err != nil { + return false, nil, nil, nil, fmt.Errorf("cs3 backend resolve entry data error: %v", err) + } + + // Use the users subject as user id. + userID := user.Subject() + + sessionRef := identity.GetSessionRef(b.Name(), audience, userID) + b.sessions.Set(*sessionRef, session) + b.logger.WithFields(logrus.Fields{ + "session": session, + "ref": *sessionRef, + "username": user.Username(), + "id": userID, + }).Debugln("cs3 backend logon") + + return true, &userID, sessionRef, user, nil +} + +// GetUser implements the Backend interface, providing user meta data retrieval +// for the user specified by the userID. Requests are bound to the provided +// context. +func (b *CS3Backend) GetUser(ctx context.Context, userEntryID string, sessionRef *string, requestedScopes map[string]bool) (backends.UserFromBackend, error) { + + session, err := b.getSessionForUser(ctx, userEntryID, sessionRef, true, true, false) + if err != nil { + return nil, fmt.Errorf("cs3 backend resolve session error: %v", err) + } + + user, err := newCS3User(session.User()) + if err != nil { + return nil, fmt.Errorf("cs3 backend get user failed to process user: %v", err) + } + // TODO double check userEntryID matches session? + + return user, nil +} + +// ResolveUserByUsername implements the Backend interface, providing lookup for +// user by providing the username. Requests are bound to the provided context. +func (b *CS3Backend) ResolveUserByUsername(ctx context.Context, username string) (backends.UserFromBackend, error) { + + l, err := b.connect(ctx) + if err != nil { + return nil, fmt.Errorf("cs3 backend resolve username connect error: %v", err) + } + defer l.Close() + + client := cs3gateway.NewGatewayAPIClient(l) + + res, err := client.Authenticate(ctx, &cs3gateway.AuthenticateRequest{ + Type: "machine", + ClientId: "username:" + username, + ClientSecret: b.machineAuthAPIKey, + }) + if err != nil { + return nil, fmt.Errorf("cs3 backend machine authenticate rpc error: %v", err) + } + if res.Status.Code != cs3rpc.Code_CODE_OK { + return nil, fmt.Errorf("cs3 backend machine authenticate failed with code %s: %s", res.Status.Code.String(), res.Status.Message) + } + + user, err := newCS3User(res.User) + if err != nil { + return nil, fmt.Errorf("cs3 backend resolve username data error: %v", err) + } + + return user, nil +} + +// RefreshSession implements the Backend interface. +func (b *CS3Backend) RefreshSession(ctx context.Context, userID string, sessionRef *string, claims map[string]interface{}) error { + return nil +} + +// DestroySession implements the Backend interface providing destroy CS3 session. +func (b *CS3Backend) DestroySession(ctx context.Context, sessionRef *string) error { + b.sessions.Remove(*sessionRef) + return nil +} + +// UserClaims implements the Backend interface, providing user specific claims +// for the user specified by the userID. +func (b *CS3Backend) UserClaims(userID string, authorizedScopes map[string]bool) map[string]interface{} { + return nil + // TODO should we return the "ownclouduuid" as a claim? there is also "LibgreGraph.UUID" / lico.ScopeUniqueUserID +} + +// ScopesSupported implements the Backend interface, providing supported scopes +// when running this backend. +func (b *CS3Backend) ScopesSupported() []string { + return b.supportedScopes +} + +// ScopesMeta implements the Backend interface, providing meta data for +// supported scopes. +func (b *CS3Backend) ScopesMeta() *scopes.Scopes { + return nil +} + +// Name implements the Backend interface. +func (b *CS3Backend) Name() string { + return cs3BackendName +} + +func (b *CS3Backend) connect(ctx context.Context) (*grpc.ClientConn, error) { + if b.insecure { + return grpc.Dial(b.gatewayURI, grpc.WithTransportCredentials(ins.NewCredentials())) + } + + creds := credentials.NewTLS(b.tlsConfig) + return grpc.Dial(b.gatewayURI, grpc.WithTransportCredentials(creds)) +} + +func (b *CS3Backend) getSessionForUser(ctx context.Context, userEntryID string, sessionRef *string, register bool, refresh bool, removeIfRegistered bool) (*cs3Session, error) { + if sessionRef == nil { + return nil, nil + } + + var session *cs3Session + if s, ok := b.sessions.Get(*sessionRef); ok { + // Existing session. + session = s.(*cs3Session) + if session != nil { + return session, nil + } + } + + return session, nil +} diff --git a/extensions/idp/pkg/backends/cs3/identifier/session.go b/extensions/idp/pkg/backends/cs3/identifier/session.go new file mode 100644 index 00000000000..12ec61812e8 --- /dev/null +++ b/extensions/idp/pkg/backends/cs3/identifier/session.go @@ -0,0 +1,40 @@ +package cs3 + +import ( + "context" + "time" + + cs3user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" +) + +// createSession creates a new Session without the server using the provided +// data. +func createSession(ctx context.Context, u *cs3user.User) *cs3Session { + + if ctx == nil { + ctx = context.Background() + } + + sessionCtx, cancel := context.WithCancel(ctx) + s := &cs3Session{ + ctx: sessionCtx, + u: u, + ctxCancel: cancel, + } + + s.when = time.Now() + + return s +} + +type cs3Session struct { + ctx context.Context + ctxCancel context.CancelFunc + u *cs3user.User + when time.Time +} + +// User returns the cs3 user of the session +func (s *cs3Session) User() *cs3user.User { + return s.u +} diff --git a/extensions/idp/pkg/backends/cs3/identifier/user.go b/extensions/idp/pkg/backends/cs3/identifier/user.go new file mode 100644 index 00000000000..135bb3740a2 --- /dev/null +++ b/extensions/idp/pkg/backends/cs3/identifier/user.go @@ -0,0 +1,74 @@ +package cs3 + +import ( + cs3user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" + konnect "github.com/libregraph/lico" +) + +type cs3User struct { + u *cs3user.User +} + +func newCS3User(u *cs3user.User) (*cs3User, error) { + return &cs3User{ + u: u, + }, nil +} + +// Subject returns the cs3 users opaque id as sub +func (u *cs3User) Subject() string { + return u.u.GetId().GetOpaqueId() +} + +// Email returns the cs3 users email +func (u *cs3User) Email() string { + return u.u.GetMail() +} + +// EmailVerified returns the cs3 users email verified flag +func (u *cs3User) EmailVerified() bool { + return u.u.GetMailVerified() +} + +// Name returns the cs3 users displayname +func (u *cs3User) Name() string { + return u.u.GetDisplayName() +} + +// FamilyName always returns "" to fulfill the UserWithProfile interface +func (u *cs3User) FamilyName() string { + return "" +} + +// GivenName always returns "" to fulfill the UserWithProfile interface +func (u *cs3User) GivenName() string { + return "" +} + +// Username returns the cs3 users username +func (u *cs3User) Username() string { + return u.u.GetUsername() +} + +// UniqueID returns the cs3 users opaque id +func (u *cs3User) UniqueID() string { + return u.u.GetId().GetOpaqueId() +} + +// BackendClaims returns additional claims the cs3 users provides +func (u *cs3User) BackendClaims() map[string]interface{} { + claims := make(map[string]interface{}) + claims[konnect.IdentifiedUserIDClaim] = u.u.GetId().GetOpaqueId() + + return claims +} + +// BackendScopes returns nil to fulfill the UserFromBackend interface +func (u *cs3User) BackendScopes() []string { + return nil +} + +// RequiredScopes returns nil to fulfill the UserFromBackend interface +func (u *cs3User) RequiredScopes() []string { + return nil +} diff --git a/extensions/idp/pkg/config/config.go b/extensions/idp/pkg/config/config.go index 9a6577f55b4..15a8b67ab4c 100644 --- a/extensions/idp/pkg/config/config.go +++ b/extensions/idp/pkg/config/config.go @@ -18,6 +18,9 @@ type Config struct { HTTP HTTP `yaml:"http"` + Reva *Reva `yaml:"reva"` + MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;IDP_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to impersonate users when looking up their userinfo via the 'cs3' backend."` + Asset Asset `yaml:"asset"` IDP Settings `yaml:"idp"` Clients []Client `yaml:"clients"` @@ -66,9 +69,9 @@ type Settings struct { // don't change the order of elements in this struct // it needs to match github.com/libregraph/lico/bootstrap.Settings - Iss string `yaml:"iss" env:"OCIS_URL;OCIS_OIDC_ISSUER;IDP_ISS"` + Iss string `yaml:"iss" env:"OCIS_URL;OCIS_OIDC_ISSUER;IDP_ISS" desc:"The OIDC issuer URL to use."` - IdentityManager string `yaml:"identity_manager" env:"IDP_IDENTITY_MANAGER"` + IdentityManager string `yaml:"identity_manager" env:"IDP_IDENTITY_MANAGER" desc:"The identity manager implementation to use, defaults to 'ldap', can be changed to 'cs3', 'kc', 'libregraph', 'cookie' or 'guest'."` URIBasePath string `yaml:"uri_base_path" env:"IDP_URI_BASE_PATH"` @@ -78,7 +81,7 @@ type Settings struct { AuthorizationEndpointURI string `yaml:"authorization_endpoint_uri" env:"IDP_ENDPOINT_URI"` EndsessionEndpointURI string `yaml:"end_session_endpoint_uri" env:"IDP_ENDSESSION_ENDPOINT_URI"` - Insecure bool `yaml:"insecure" env:"IDP_INSECURE"` + Insecure bool `yaml:"insecure" env:"IDP_INSECURE" desc:"Allow insecure connections to the backend."` TrustedProxy []string `yaml:"trusted_proxy"` //TODO: how to configure this via env? diff --git a/extensions/idp/pkg/config/defaults/defaultconfig.go b/extensions/idp/pkg/config/defaults/defaultconfig.go index 1e119b408fe..dd6d0929be1 100644 --- a/extensions/idp/pkg/config/defaults/defaultconfig.go +++ b/extensions/idp/pkg/config/defaults/defaultconfig.go @@ -28,6 +28,9 @@ func DefaultConfig() *config.Config { TLSKey: path.Join(defaults.BaseDataPath(), "idp", "server.key"), TLS: false, }, + Reva: &config.Reva{ + Address: "127.0.0.1:9142", + }, Service: config.Service{ Name: "idp", }, @@ -159,6 +162,18 @@ func EnsureDefaults(cfg *config.Config) { } else if cfg.Tracing == nil { cfg.Tracing = &config.Tracing{} } + + if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil { + cfg.Reva = &config.Reva{ + Address: cfg.Commons.Reva.Address, + } + } else if cfg.Reva == nil { + cfg.Reva = &config.Reva{} + } + + if cfg.MachineAuthAPIKey == "" && cfg.Commons != nil && cfg.Commons.MachineAuthAPIKey != "" { + cfg.MachineAuthAPIKey = cfg.Commons.MachineAuthAPIKey + } } func Sanitize(cfg *config.Config) { diff --git a/extensions/idp/pkg/config/parser/parse.go b/extensions/idp/pkg/config/parser/parse.go index 03b4ee59990..0a978219c58 100644 --- a/extensions/idp/pkg/config/parser/parse.go +++ b/extensions/idp/pkg/config/parser/parse.go @@ -34,8 +34,15 @@ func ParseConfig(cfg *config.Config) error { } func Validate(cfg *config.Config) error { - if cfg.Ldap.BindPassword == "" { - return shared.MissingLDAPBindPassword(cfg.Service.Name) + switch cfg.IDP.IdentityManager { + case "cs3": + if cfg.MachineAuthAPIKey == "" { + return shared.MissingMachineAuthApiKeyError(cfg.Service.Name) + } + case "ldap": + if cfg.Ldap.BindPassword == "" { + return shared.MissingLDAPBindPassword(cfg.Service.Name) + } } return nil diff --git a/extensions/idp/pkg/config/reva.go b/extensions/idp/pkg/config/reva.go new file mode 100644 index 00000000000..5b4222251d7 --- /dev/null +++ b/extensions/idp/pkg/config/reva.go @@ -0,0 +1,6 @@ +package config + +// Reva defines all available REVA configuration. +type Reva struct { + Address string `yaml:"address" env:"REVA_GATEWAY" desc:"CS3 gateway used to authenticate and look up users"` +} diff --git a/extensions/idp/pkg/service/v0/service.go b/extensions/idp/pkg/service/v0/service.go index 4d221482b27..4b140947430 100644 --- a/extensions/idp/pkg/service/v0/service.go +++ b/extensions/idp/pkg/service/v0/service.go @@ -13,13 +13,14 @@ import ( "github.com/go-chi/chi/v5" "github.com/gorilla/mux" "github.com/libregraph/lico/bootstrap" - dummyBackendSupport "github.com/libregraph/lico/bootstrap/backends/dummy" guestBackendSupport "github.com/libregraph/lico/bootstrap/backends/guest" kcBackendSupport "github.com/libregraph/lico/bootstrap/backends/kc" ldapBackendSupport "github.com/libregraph/lico/bootstrap/backends/ldap" + libreGraphBackendSupport "github.com/libregraph/lico/bootstrap/backends/libregraph" licoconfig "github.com/libregraph/lico/config" "github.com/libregraph/lico/server" "github.com/owncloud/ocis/v2/extensions/idp/pkg/assets" + cs3BackendSupport "github.com/owncloud/ocis/v2/extensions/idp/pkg/backends/cs3/bootstrap" "github.com/owncloud/ocis/v2/extensions/idp/pkg/config" "github.com/owncloud/ocis/v2/extensions/idp/pkg/middleware" "github.com/owncloud/ocis/v2/ocis-pkg/ldap" @@ -51,10 +52,6 @@ func NewService(opts ...Option) Service { options.Config.Ldap.TLSCACert = "" } - if err := initLicoInternalEnvVars(&options.Config.Ldap); err != nil { - logger.Fatal().Err(err).Msg("could not initialize env vars") - } - if err := createTemporaryClientsConfig( options.Config.IDP.IdentifierRegistrationConf, options.Config.IDP.Iss, @@ -63,10 +60,22 @@ func NewService(opts ...Option) Service { logger.Fatal().Err(err).Msg("could not create default config") } - guestBackendSupport.MustRegister() - ldapBackendSupport.MustRegister() - dummyBackendSupport.MustRegister() - kcBackendSupport.MustRegister() + switch options.Config.IDP.IdentityManager { + case "cs3": + cs3BackendSupport.MustRegister() + if err := initCS3EnvVars(options.Config.Reva.Address, options.Config.MachineAuthAPIKey); err != nil { + logger.Fatal().Err(err).Msg("could not initialize cs3 backend env vars") + } + case "ldap": + ldapBackendSupport.MustRegister() + if err := initLicoInternalLDAPEnvVars(&options.Config.Ldap); err != nil { + logger.Fatal().Err(err).Msg("could not initialize ldap env vars") + } + default: + guestBackendSupport.MustRegister() + kcBackendSupport.MustRegister() + libreGraphBackendSupport.MustRegister() + } // https://play.golang.org/p/Mh8AVJCd593 idpSettings := bootstrap.Settings(options.Config.IDP) @@ -142,8 +151,24 @@ func createTemporaryClientsConfig(filePath, ocisURL string, clients []config.Cli } -// Init vars which are currently not accessible via idp api -func initLicoInternalEnvVars(ldap *config.Ldap) error { +// Init cs3 backend vars which are currently not accessible via idp api +func initCS3EnvVars(cs3Addr, machineAuthAPIKey string) error { + var defaults = map[string]string{ + "CS3_GATEWAY": cs3Addr, + "CS3_MACHINE_AUTH_API_KEY": machineAuthAPIKey, + } + + for k, v := range defaults { + if err := os.Setenv(k, v); err != nil { + return fmt.Errorf("could not set cs3 env var %s=%s", k, v) + } + } + + return nil +} + +// Init ldap backend vars which are currently not accessible via idp api +func initLicoInternalLDAPEnvVars(ldap *config.Ldap) error { filter := fmt.Sprintf("(objectclass=%s)", ldap.ObjectClass) if ldap.Filter != "" { filter = fmt.Sprintf("(&%s%s)", ldap.Filter, filter) @@ -168,7 +193,7 @@ func initLicoInternalEnvVars(ldap *config.Ldap) error { for k, v := range defaults { if err := os.Setenv(k, v); err != nil { - return fmt.Errorf("could not set env var %s=%s", k, v) + return fmt.Errorf("could not set ldap env var %s=%s", k, v) } } diff --git a/go.mod b/go.mod index 1fe2465d88d..e3236f8337b 100644 --- a/go.mod +++ b/go.mod @@ -48,6 +48,7 @@ require ( github.com/onsi/ginkgo v1.16.5 github.com/onsi/ginkgo/v2 v2.1.4 github.com/onsi/gomega v1.19.0 + github.com/orcaman/concurrent-map v1.0.0 github.com/owncloud/libre-graph-api-go v0.14.2 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.12.1 @@ -74,6 +75,7 @@ require ( google.golang.org/protobuf v1.28.0 gopkg.in/yaml.v2 v2.4.0 gotest.tools/v3 v3.2.0 + stash.kopano.io/kgol/oidc-go v0.3.2 stash.kopano.io/kgol/rndm v1.1.1 ) @@ -115,6 +117,7 @@ require ( github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/ceph/go-ceph v0.15.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cevaris/ordered_map v0.0.0-20190319150403-3adeae072e73 // indirect github.com/coreos/go-oidc v2.2.1+incompatible // indirect github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-systemd/v22 v22.3.2 // indirect @@ -208,7 +211,6 @@ require ( github.com/nats-io/nkeys v0.3.0 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/nxadm/tail v1.4.8 // indirect - github.com/orcaman/concurrent-map v1.0.0 // indirect github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect github.com/patrickmn/go-cache v2.1.0+incompatible // indirect github.com/pkg/xattr v0.4.5 // indirect @@ -258,7 +260,6 @@ require ( gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect stash.kopano.io/kgol/kcc-go/v5 v5.0.1 // indirect - stash.kopano.io/kgol/oidc-go v0.3.2 // indirect ) // we need to use a fork to make the windows build pass diff --git a/go.sum b/go.sum index 510d61d62d4..495c4b76074 100644 --- a/go.sum +++ b/go.sum @@ -232,6 +232,7 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cevaris/ordered_map v0.0.0-20190319150403-3adeae072e73 h1:q1g9lSyo/nOIC3W5E3FK3Unrz8b9LdLXCyuC+ZcpPC0= github.com/cevaris/ordered_map v0.0.0-20190319150403-3adeae072e73/go.mod h1:507vXsotcZop7NZfBWdhPmVeOse4ko2R7AagJYrpoEg= github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuPxX30= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=