mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-07 21:00:30 -06:00
IDP: directly use CS3 API to authenticate users
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
Enhancement: Directly authenticate users via CS3
|
||||
|
||||
The IDP now directly authenticates users using the CS3 API instead of LDAP.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/3825
|
||||
125
extensions/idp/pkg/backends/cs3/bootstrap/cs3.go
Normal file
125
extensions/idp/pkg/backends/cs3/bootstrap/cs3.go
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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"
|
||||
)
|
||||
|
||||
func Register() error {
|
||||
return bootstrap.RegisterIdentityManager(identityManagerName, NewIdentityManager)
|
||||
}
|
||||
|
||||
func MustRegister() {
|
||||
if err := Register(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
os.Getenv("CS3_GATEWAY"), // FIXME how do we pass custom config to backends?
|
||||
os.Getenv("CS3_MACHINE_AUTH_API_KEY"), // FIXME how do we pass custom config to backends?
|
||||
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
|
||||
}
|
||||
242
extensions/idp/pkg/backends/cs3/identifier/cs3.go
Normal file
242
extensions/idp/pkg/backends/cs3/identifier/cs3.go
Normal file
@@ -0,0 +1,242 @@
|
||||
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,
|
||||
}
|
||||
|
||||
type CS3Backend struct {
|
||||
supportedScopes []string
|
||||
|
||||
logger logrus.FieldLogger
|
||||
tlsConfig *tls.Config
|
||||
gatewayURI string
|
||||
machineAuthAPIKey string
|
||||
insecure bool
|
||||
|
||||
sessions cmap.ConcurrentMap
|
||||
|
||||
gateway cs3gateway.GatewayAPIClient
|
||||
}
|
||||
|
||||
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 || res.Status.Code != cs3rpc.Code_CODE_OK {
|
||||
return false, nil, nil, nil, nil
|
||||
}
|
||||
res2, err := client.WhoAmI(ctx, &cs3gateway.WhoAmIRequest{
|
||||
Token: res.Token,
|
||||
})
|
||||
if err != nil || res2.Status.Code != cs3rpc.Code_CODE_OK {
|
||||
return false, nil, nil, nil, nil
|
||||
}
|
||||
|
||||
session, _ := createSession(ctx, res2.User)
|
||||
|
||||
user, err := newCS3User(res2.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 || res.Status.Code != cs3rpc.Code_CODE_OK {
|
||||
return nil, nil
|
||||
}
|
||||
res2, err := client.WhoAmI(ctx, &cs3gateway.WhoAmIRequest{
|
||||
Token: res.Token,
|
||||
})
|
||||
if err != nil || res2.Status.Code != cs3rpc.Code_CODE_OK {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
user, err := newCS3User(res2.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
|
||||
}
|
||||
39
extensions/idp/pkg/backends/cs3/identifier/session.go
Normal file
39
extensions/idp/pkg/backends/cs3/identifier/session.go
Normal file
@@ -0,0 +1,39 @@
|
||||
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, error) {
|
||||
|
||||
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, nil
|
||||
}
|
||||
|
||||
type cs3Session struct {
|
||||
ctx context.Context
|
||||
ctxCancel context.CancelFunc
|
||||
u *cs3user.User
|
||||
when time.Time
|
||||
}
|
||||
|
||||
func (s *cs3Session) User() *cs3user.User {
|
||||
return s.u
|
||||
}
|
||||
67
extensions/idp/pkg/backends/cs3/identifier/user.go
Normal file
67
extensions/idp/pkg/backends/cs3/identifier/user.go
Normal file
@@ -0,0 +1,67 @@
|
||||
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
|
||||
}
|
||||
|
||||
func (u *cs3User) Subject() string {
|
||||
return u.u.GetId().GetOpaqueId()
|
||||
}
|
||||
|
||||
func (u *cs3User) Email() string {
|
||||
return u.u.GetMail()
|
||||
}
|
||||
|
||||
func (u *cs3User) EmailVerified() bool {
|
||||
return u.u.GetMailVerified()
|
||||
}
|
||||
|
||||
func (u *cs3User) Name() string {
|
||||
return u.u.GetDisplayName()
|
||||
}
|
||||
|
||||
func (u *cs3User) FamilyName() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (u *cs3User) GivenName() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (u *cs3User) Username() string {
|
||||
return u.u.GetUsername()
|
||||
}
|
||||
|
||||
func (u *cs3User) ID() int64 {
|
||||
return u.u.GetUidNumber()
|
||||
}
|
||||
|
||||
func (u *cs3User) UniqueID() string {
|
||||
return u.u.GetId().GetOpaqueId()
|
||||
}
|
||||
|
||||
func (u *cs3User) BackendClaims() map[string]interface{} {
|
||||
claims := make(map[string]interface{})
|
||||
claims[konnect.IdentifiedUserIDClaim] = u.u.GetId().GetOpaqueId()
|
||||
|
||||
return claims
|
||||
}
|
||||
|
||||
func (u *cs3User) BackendScopes() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *cs3User) RequiredScopes() []string {
|
||||
return nil
|
||||
}
|
||||
@@ -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"`
|
||||
|
||||
Asset Asset `yaml:"asset"`
|
||||
IDP Settings `yaml:"idp"`
|
||||
Clients []Client `yaml:"clients"`
|
||||
|
||||
@@ -28,18 +28,21 @@ 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",
|
||||
},
|
||||
IDP: config.Settings{
|
||||
Iss: "https://localhost:9200",
|
||||
IdentityManager: "ldap",
|
||||
IdentityManager: "cs3",
|
||||
URIBasePath: "",
|
||||
SignInURI: "",
|
||||
SignedOutURI: "",
|
||||
AuthorizationEndpointURI: "",
|
||||
EndsessionEndpointURI: "",
|
||||
Insecure: false,
|
||||
Insecure: true, // TODO grpc requires service certificates
|
||||
TrustedProxy: nil,
|
||||
AllowScope: nil,
|
||||
AllowClientGuests: false,
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
6
extensions/idp/pkg/config/reva.go
Normal file
6
extensions/idp/pkg/config/reva.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package config
|
||||
|
||||
// Reva defines all available REVA configuration.
|
||||
type Reva struct {
|
||||
Address string `yaml:"address" env:"REVA_GATEWAY"`
|
||||
}
|
||||
@@ -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,23 @@ 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 +152,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 +194,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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
5
go.mod
5
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
|
||||
|
||||
1
go.sum
1
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=
|
||||
|
||||
Reference in New Issue
Block a user