Merge branch 'master' into search

Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
This commit is contained in:
Jörn Friedrich Dreyer
2022-05-02 13:43:24 +00:00
237 changed files with 3394 additions and 1014 deletions
@@ -1,27 +0,0 @@
package main
import (
"fmt"
accountsdefaults "github.com/owncloud/ocis/extensions/accounts/pkg/config/defaults"
idpdefaults "github.com/owncloud/ocis/extensions/idp/pkg/config/defaults"
"gopkg.in/yaml.v2"
)
func main() {
fn1 := accountsdefaults.FullDefaultConfig
fn2 := idpdefaults.FullDefaultConfig
b, err := yaml.Marshal(fn1())
if err != nil {
return
}
fmt.Println(string(b))
b, err = yaml.Marshal(fn2())
if err != nil {
return
}
fmt.Println(string(b))
}
+5 -1
View File
@@ -17,7 +17,11 @@ func Health(cfg *config.Config) *cli.Command {
Usage: "check health status",
Category: "info",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
+5 -1
View File
@@ -25,7 +25,11 @@ func Server(cfg *config.Config) *cli.Command {
Usage: fmt.Sprintf("start %s extension without runtime (unsupervised mode)", cfg.Service.Name),
Category: "server",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
+1 -6
View File
@@ -19,7 +19,7 @@ type Config struct {
HTTP HTTP `yaml:"http"`
GRPC GRPC `yaml:"grpc"`
TokenManager TokenManager `yaml:"token_manager"`
TokenManager *TokenManager `yaml:"token_manager"`
Asset Asset `yaml:"asset"`
Repo Repo `yaml:"repo"`
@@ -36,11 +36,6 @@ type Asset struct {
Path string `yaml:"path" env:"ACCOUNTS_ASSET_PATH" desc:"The path to the ui assets."`
}
// TokenManager is the config for using the reva token manager
type TokenManager struct {
JWTSecret string `yaml:"jwt_secret" env:"OCIS_JWT_SECRET;ACCOUNTS_JWT_SECRET" desc:"The secret to mint jwt tokens."`
}
// Repo defines which storage implementation is to be used.
type Repo struct {
Backend string `yaml:"backend" env:"ACCOUNTS_STORAGE_BACKEND" desc:"Defines which storage implementation is to be used"`
@@ -10,10 +10,8 @@ import (
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
@@ -44,10 +42,7 @@ func DefaultConfig() *config.Config {
Service: config.Service{
Name: "accounts",
},
Asset: config.Asset{},
TokenManager: config.TokenManager{
JWTSecret: "Pive-Fumkiu4",
},
Asset: config.Asset{},
HashDifficulty: 11,
DemoUsersAndGroups: false,
Repo: config.Repo{
@@ -101,6 +96,14 @@ func EnsureDefaults(cfg *config.Config) {
} else if cfg.Tracing == nil {
cfg.Tracing = &config.Tracing{}
}
if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
cfg.TokenManager = &config.TokenManager{
JWTSecret: cfg.Commons.TokenManager.JWTSecret,
}
} else if cfg.TokenManager == nil {
cfg.TokenManager = &config.TokenManager{}
}
}
func Sanitize(cfg *config.Config) {
@@ -6,11 +6,12 @@ import (
"github.com/owncloud/ocis/extensions/accounts/pkg/config"
defaults "github.com/owncloud/ocis/extensions/accounts/pkg/config/defaults"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/shared"
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
)
// ParseConfig loads accounts configuration from known paths.
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
@@ -29,5 +30,12 @@ func ParseConfig(cfg *config.Config) error {
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
if cfg.TokenManager.JWTSecret == "" {
return shared.MissingJWTTokenError(cfg.Service.Name)
}
return nil
}
+6
View File
@@ -0,0 +1,6 @@
package config
// TokenManager is the config for using the reva token manager
type TokenManager struct {
JWTSecret string `yaml:"jwt_secret" env:"OCIS_JWT_SECRET;ACCOUNTS_JWT_SECRET"`
}
+12 -3
View File
@@ -3,6 +3,7 @@ package command
import (
"context"
"flag"
"fmt"
"os"
"path"
@@ -10,6 +11,7 @@ import (
"github.com/gofrs/uuid"
"github.com/oklog/run"
"github.com/owncloud/ocis/extensions/appprovider/pkg/config"
"github.com/owncloud/ocis/extensions/appprovider/pkg/config/parser"
"github.com/owncloud/ocis/extensions/storage/pkg/server/debug"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/log"
@@ -24,6 +26,13 @@ func AppProvider(cfg *config.Config) *cli.Command {
return &cli.Command{
Name: "app-provider",
Usage: "start appprovider for providing apps",
Before: func(ctx *cli.Context) error {
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logCfg := cfg.Logging
logger := log.NewLogger(
@@ -92,8 +101,8 @@ func appProviderConfigFromStruct(c *cli.Context, cfg *config.Config) map[string]
"tracing_service_name": c.Command.Name,
},
"shared": map[string]interface{}{
"jwt_secret": cfg.JWTSecret,
"gatewaysvc": cfg.GatewayEndpoint,
"jwt_secret": cfg.TokenManager.JWTSecret,
"gatewaysvc": cfg.Reva.Address,
"skip_user_groups_in_token": cfg.SkipUserGroupsInToken,
},
"grpc": map[string]interface{}{
@@ -114,7 +123,7 @@ func appProviderConfigFromStruct(c *cli.Context, cfg *config.Config) map[string]
"app_url": cfg.Drivers.WOPI.AppURL,
"insecure_connections": cfg.Drivers.WOPI.Insecure,
"iop_secret": cfg.Drivers.WOPI.IopSecret,
"jwt_secret": cfg.JWTSecret,
"jwt_secret": cfg.TokenManager.JWTSecret,
"wopi_url": cfg.Drivers.WOPI.WopiURL,
},
},
+8 -7
View File
@@ -8,16 +8,17 @@ type Config struct {
Tracing *Tracing `yaml:"tracing"`
Logging *Logging `yaml:"log"`
Debug Debug `yaml:"debug"`
Supervised bool
Supervised bool `yaml:"-"`
GRPC GRPCConfig `yaml:"grpc"`
JWTSecret string
GatewayEndpoint string
SkipUserGroupsInToken bool
ExternalAddr string
Driver string
Drivers Drivers
TokenManager *TokenManager `yaml:"token_manager"`
Reva *Reva `yaml:"reva"`
SkipUserGroupsInToken bool `yaml:"skip_user_groups_in_token"`
ExternalAddr string `yaml:"external_addr"`
Driver string `yaml:"driver"`
Drivers Drivers `yaml:"drivers"`
}
type Tracing struct {
@@ -2,13 +2,13 @@ package defaults
import (
"github.com/owncloud/ocis/extensions/appprovider/pkg/config"
"github.com/owncloud/ocis/ocis-pkg/shared"
)
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
@@ -27,9 +27,10 @@ func DefaultConfig() *config.Config {
Service: config.Service{
Name: "appprovider",
},
GatewayEndpoint: "127.0.0.1:9142",
JWTSecret: "Pive-Fumkiu4",
Driver: "",
Reva: &config.Reva{
Address: "127.0.0.1:9142",
},
Driver: "",
Drivers: config.Drivers{
WOPI: config.WOPIDriver{},
},
@@ -59,8 +60,32 @@ 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.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
cfg.TokenManager = &config.TokenManager{
JWTSecret: cfg.Commons.TokenManager.JWTSecret,
}
} else if cfg.TokenManager == nil {
cfg.TokenManager = &config.TokenManager{}
}
}
func Sanitize(cfg *config.Config) {
// nothing to sanitize here atm
}
func Validate(cfg *config.Config) error {
if cfg.TokenManager.JWTSecret == "" {
return shared.MissingJWTTokenError(cfg.Service.Name)
}
return nil
}
@@ -0,0 +1,42 @@
package parser
import (
"errors"
"github.com/owncloud/ocis/extensions/appprovider/pkg/config"
"github.com/owncloud/ocis/extensions/appprovider/pkg/config/defaults"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/shared"
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
)
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
return err
}
defaults.EnsureDefaults(cfg)
// load all env variables relevant to the config in the current context.
if err := envdecode.Decode(cfg); err != nil {
// no environment variable set for this config is an expected "error"
if !errors.Is(err, envdecode.ErrNoTargetFieldsAreSet) {
return err
}
}
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
if cfg.TokenManager.JWTSecret == "" {
return shared.MissingJWTTokenError(cfg.Service.Name)
}
return nil
}
+11
View File
@@ -0,0 +1,11 @@
package config
// Reva defines all available REVA configuration.
type Reva struct {
Address string `yaml:"address" env:"REVA_GATEWAY"`
}
// TokenManager is the config for using the reva token manager
type TokenManager struct {
JWTSecret string `yaml:"jwt_secret" env:"OCIS_JWT_SECRET;APP_PROVIDER_JWT_SECRET"`
}
+5 -1
View File
@@ -22,7 +22,11 @@ func Server(cfg *config.Config) *cli.Command {
Usage: fmt.Sprintf("start %s extension without runtime (unsupervised mode)", cfg.Service.Name),
Category: "server",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
@@ -6,10 +6,8 @@ import (
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
+5 -1
View File
@@ -10,7 +10,7 @@ import (
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
)
// ParseConfig loads accounts configuration from known paths.
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
@@ -29,5 +29,9 @@ func ParseConfig(cfg *config.Config) error {
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
return nil
}
+13 -13
View File
@@ -297,8 +297,8 @@ var testCases = []struct {
}, {
Alias: "File created",
SystemEvent: events.FileUploaded{
FileID: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
Ref: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
},
CheckAuditEvent: func(t *testing.T, b []byte) {
ev := types.AuditEventFileCreated{}
@@ -312,8 +312,8 @@ var testCases = []struct {
}, {
Alias: "File read",
SystemEvent: events.FileDownloaded{
FileID: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
Ref: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
},
CheckAuditEvent: func(t *testing.T, b []byte) {
ev := types.AuditEventFileRead{}
@@ -327,8 +327,8 @@ var testCases = []struct {
}, {
Alias: "File trashed",
SystemEvent: events.ItemTrashed{
FileID: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
Ref: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
},
CheckAuditEvent: func(t *testing.T, b []byte) {
ev := types.AuditEventFileDeleted{}
@@ -342,7 +342,7 @@ var testCases = []struct {
}, {
Alias: "File renamed",
SystemEvent: events.ItemMoved{
FileID: reference("sto-123", "iid-123", "./item"),
Ref: reference("sto-123", "iid-123", "./item"),
OldReference: reference("sto-123", "iid-123", "./anotheritem"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
},
@@ -361,8 +361,8 @@ var testCases = []struct {
}, {
Alias: "File purged",
SystemEvent: events.ItemPurged{
FileID: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
Ref: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
},
CheckAuditEvent: func(t *testing.T, b []byte) {
ev := types.AuditEventFilePurged{}
@@ -376,7 +376,7 @@ var testCases = []struct {
}, {
Alias: "File restored",
SystemEvent: events.ItemRestored{
FileID: reference("sto-123", "iid-123", "./item"),
Ref: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
OldReference: reference("sto-123", "sto-123!iid-123/item", "./oldpath"),
Key: "",
@@ -396,9 +396,9 @@ var testCases = []struct {
}, {
Alias: "File version restored",
SystemEvent: events.FileVersionRestored{
FileID: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
Key: "v1",
Ref: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
Key: "v1",
},
CheckAuditEvent: func(t *testing.T, b []byte) {
ev := types.AuditEventFileVersionRestored{}
+11 -2
View File
@@ -3,6 +3,7 @@ package command
import (
"context"
"flag"
"fmt"
"os"
"path"
"path/filepath"
@@ -11,6 +12,7 @@ import (
"github.com/gofrs/uuid"
"github.com/oklog/run"
"github.com/owncloud/ocis/extensions/auth-basic/pkg/config"
"github.com/owncloud/ocis/extensions/auth-basic/pkg/config/parser"
"github.com/owncloud/ocis/extensions/storage/pkg/server/debug"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/ldap"
@@ -26,6 +28,13 @@ func AuthBasic(cfg *config.Config) *cli.Command {
return &cli.Command{
Name: "auth-basic",
Usage: "start authprovider for basic auth",
Before: func(ctx *cli.Context) error {
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logCfg := cfg.Logging
logger := log.NewLogger(
@@ -113,8 +122,8 @@ func authBasicConfigFromStruct(c *cli.Context, cfg *config.Config) map[string]in
"tracing_service_name": c.Command.Name,
},
"shared": map[string]interface{}{
"jwt_secret": cfg.JWTSecret,
"gatewaysvc": cfg.GatewayEndpoint,
"jwt_secret": cfg.TokenManager.JWTSecret,
"gatewaysvc": cfg.Reva.Address,
"skip_user_groups_in_token": cfg.SkipUserGroupsInToken,
},
"grpc": map[string]interface{}{
+6 -5
View File
@@ -8,13 +8,14 @@ type Config struct {
Tracing *Tracing `yaml:"tracing"`
Logging *Logging `yaml:"log"`
Debug Debug `yaml:"debug"`
Supervised bool
Supervised bool `yaml:"-"`
GRPC GRPCConfig `yaml:"grpc"`
JWTSecret string
GatewayEndpoint string
SkipUserGroupsInToken bool
TokenManager *TokenManager `yaml:"token_manager"`
Reva *Reva `yaml:"reva"`
SkipUserGroupsInToken bool `yaml:"skip_user_groups_in_token"`
AuthProvider string `yaml:"auth_provider" env:"AUTH_BASIC_AUTH_PROVIDER" desc:"The auth provider which should be used by the service"`
AuthProviders AuthProviders `yaml:"auth_providers"`
}
@@ -63,7 +64,7 @@ type LDAPProvider struct {
CACert string `env:"LDAP_CACERT;AUTH_BASIC_LDAP_CACERT"`
Insecure bool `env:"LDAP_INSECURE;AUTH_BASIC_LDAP_INSECURE"`
BindDN string `env:"LDAP_BIND_DN;AUTH_BASIC_LDAP_BIND_DN"`
BindPassword string `env:"LDAP_BIND_PASSWORD;AUTH_BASIC_LDAP_BIND_PASSWORD"`
BindPassword string `yaml:"bind_password" env:"LDAP_BIND_PASSWORD;AUTH_BASIC_LDAP_BIND_PASSWORD"`
UserBaseDN string `env:"LDAP_USER_BASE_DN;AUTH_BASIC_LDAP_USER_BASE_DN"`
GroupBaseDN string `env:"LDAP_GROUP_BASE_DN;AUTH_BASIC_LDAP_GROUP_BASE_DN"`
UserScope string `env:"LDAP_USER_SCOPE;AUTH_BASIC_LDAP_USER_SCOPE"`
@@ -9,9 +9,8 @@ import (
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
@@ -30,9 +29,10 @@ func DefaultConfig() *config.Config {
Service: config.Service{
Name: "auth-basic",
},
GatewayEndpoint: "127.0.0.1:9142",
JWTSecret: "Pive-Fumkiu4",
AuthProvider: "ldap",
Reva: &config.Reva{
Address: "127.0.0.1:9142",
},
AuthProvider: "ldap",
AuthProviders: config.AuthProviders{
LDAP: config.LDAPProvider{
URI: "ldaps://localhost:9235",
@@ -48,7 +48,6 @@ func DefaultConfig() *config.Config {
UserObjectClass: "inetOrgPerson",
GroupObjectClass: "groupOfNames",
BindDN: "uid=reva,ou=sysusers,o=libregraph-idm",
BindPassword: "reva",
IDP: "https://localhost:9200",
UserSchema: config.LDAPUserSchema{
ID: "ownclouduuid",
@@ -67,7 +66,6 @@ func DefaultConfig() *config.Config {
JSON: config.JSONProvider{},
OwnCloudSQL: config.OwnCloudSQLProvider{
DBUsername: "owncloud",
DBPassword: "secret",
DBHost: "mysql",
DBPort: 3306,
DBName: "owncloud",
@@ -103,6 +101,23 @@ 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.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
cfg.TokenManager = &config.TokenManager{
JWTSecret: cfg.Commons.TokenManager.JWTSecret,
}
} else if cfg.TokenManager == nil {
cfg.TokenManager = &config.TokenManager{}
}
}
func Sanitize(cfg *config.Config) {
@@ -0,0 +1,46 @@
package parser
import (
"errors"
"github.com/owncloud/ocis/extensions/auth-basic/pkg/config"
"github.com/owncloud/ocis/extensions/auth-basic/pkg/config/defaults"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/shared"
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
)
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
return err
}
defaults.EnsureDefaults(cfg)
// load all env variables relevant to the config in the current context.
if err := envdecode.Decode(cfg); err != nil {
// no environment variable set for this config is an expected "error"
if !errors.Is(err, envdecode.ErrNoTargetFieldsAreSet) {
return err
}
}
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
if cfg.TokenManager.JWTSecret == "" {
return shared.MissingJWTTokenError(cfg.Service.Name)
}
if cfg.AuthProviders.LDAP.BindPassword == "" && cfg.AuthProvider == "ldap" {
return shared.MissingLDAPBindPassword(cfg.Service.Name)
}
return nil
}
+11
View File
@@ -0,0 +1,11 @@
package config
// Reva defines all available REVA configuration.
type Reva struct {
Address string `yaml:"address" env:"REVA_GATEWAY"`
}
// TokenManager is the config for using the reva token manager
type TokenManager struct {
JWTSecret string `yaml:"jwt_secret" env:"OCIS_JWT_SECRET;AUTH_BASIC_JWT_SECRET"`
}
+11 -2
View File
@@ -3,6 +3,7 @@ package command
import (
"context"
"flag"
"fmt"
"os"
"path"
@@ -10,6 +11,7 @@ import (
"github.com/gofrs/uuid"
"github.com/oklog/run"
"github.com/owncloud/ocis/extensions/auth-bearer/pkg/config"
"github.com/owncloud/ocis/extensions/auth-bearer/pkg/config/parser"
"github.com/owncloud/ocis/extensions/storage/pkg/server/debug"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/log"
@@ -24,6 +26,13 @@ func AuthBearer(cfg *config.Config) *cli.Command {
return &cli.Command{
Name: "auth-bearer",
Usage: "start authprovider for bearer auth",
Before: func(ctx *cli.Context) error {
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logCfg := cfg.Logging
logger := log.NewLogger(
@@ -94,8 +103,8 @@ func authBearerConfigFromStruct(c *cli.Context, cfg *config.Config) map[string]i
"tracing_service_name": c.Command.Name,
},
"shared": map[string]interface{}{
"jwt_secret": cfg.JWTSecret,
"gatewaysvc": cfg.GatewayEndpoint,
"jwt_secret": cfg.TokenManager.JWTSecret,
"gatewaysvc": cfg.Reva.Address,
"skip_user_groups_in_token": cfg.SkipUserGroupsInToken,
},
"grpc": map[string]interface{}{
+5 -4
View File
@@ -8,13 +8,14 @@ type Config struct {
Tracing *Tracing `yaml:"tracing"`
Logging *Logging `yaml:"log"`
Debug Debug `yaml:"debug"`
Supervised bool
Supervised bool `yaml:"-"`
GRPC GRPCConfig `yaml:"grpc"`
JWTSecret string
GatewayEndpoint string
SkipUserGroupsInToken bool
TokenManager *TokenManager `yaml:"token_manager"`
Reva *Reva `yaml:"reva"`
SkipUserGroupsInToken bool `yaml:"skip_user_groups_in_token"`
AuthProvider string `yaml:"auth_provider" env:"AUTH_BEARER_AUTH_PROVIDER" desc:"The auth provider which should be used by the service"`
AuthProviders AuthProviders `yaml:"auth_providers"`
}
@@ -6,9 +6,8 @@ import (
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
@@ -27,9 +26,10 @@ func DefaultConfig() *config.Config {
Service: config.Service{
Name: "auth-bearer",
},
GatewayEndpoint: "127.0.0.1:9142",
JWTSecret: "Pive-Fumkiu4",
AuthProvider: "ldap",
Reva: &config.Reva{
Address: "127.0.0.1:9142",
},
AuthProvider: "ldap",
AuthProviders: config.AuthProviders{
OIDC: config.OIDCProvider{
Issuer: "https://localhost:9200",
@@ -63,6 +63,22 @@ 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.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
cfg.TokenManager = &config.TokenManager{
JWTSecret: cfg.Commons.TokenManager.JWTSecret,
}
} else if cfg.TokenManager == nil {
cfg.TokenManager = &config.TokenManager{}
}
}
func Sanitize(cfg *config.Config) {
@@ -0,0 +1,42 @@
package parser
import (
"errors"
"github.com/owncloud/ocis/extensions/auth-bearer/pkg/config"
"github.com/owncloud/ocis/extensions/auth-bearer/pkg/config/defaults"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/shared"
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
)
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
return err
}
defaults.EnsureDefaults(cfg)
// load all env variables relevant to the config in the current context.
if err := envdecode.Decode(cfg); err != nil {
// no environment variable set for this config is an expected "error"
if !errors.Is(err, envdecode.ErrNoTargetFieldsAreSet) {
return err
}
}
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
if cfg.TokenManager.JWTSecret == "" {
return shared.MissingJWTTokenError(cfg.Service.Name)
}
return nil
}
+11
View File
@@ -0,0 +1,11 @@
package config
// Reva defines all available REVA configuration.
type Reva struct {
Address string `yaml:"address" env:"REVA_GATEWAY"`
}
// TokenManager is the config for using the reva token manager
type TokenManager struct {
JWTSecret string `yaml:"jwt_secret" env:"OCIS_JWT_SECRET;AUTH_BEARER_JWT_SECRET"`
}
+12 -3
View File
@@ -3,6 +3,7 @@ package command
import (
"context"
"flag"
"fmt"
"os"
"path"
@@ -10,6 +11,7 @@ import (
"github.com/gofrs/uuid"
"github.com/oklog/run"
"github.com/owncloud/ocis/extensions/auth-machine/pkg/config"
"github.com/owncloud/ocis/extensions/auth-machine/pkg/config/parser"
"github.com/owncloud/ocis/extensions/storage/pkg/server/debug"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/log"
@@ -24,6 +26,13 @@ func AuthMachine(cfg *config.Config) *cli.Command {
return &cli.Command{
Name: "auth-machine",
Usage: "start authprovider for machine auth",
Before: func(ctx *cli.Context) error {
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logCfg := cfg.Logging
logger := log.NewLogger(
@@ -94,8 +103,8 @@ func authMachineConfigFromStruct(c *cli.Context, cfg *config.Config) map[string]
"tracing_service_name": c.Command.Name,
},
"shared": map[string]interface{}{
"jwt_secret": cfg.JWTSecret,
"gatewaysvc": cfg.GatewayEndpoint,
"jwt_secret": cfg.TokenManager.JWTSecret,
"gatewaysvc": cfg.Reva.Address,
"skip_user_groups_in_token": cfg.SkipUserGroupsInToken,
},
"grpc": map[string]interface{}{
@@ -108,7 +117,7 @@ func authMachineConfigFromStruct(c *cli.Context, cfg *config.Config) map[string]
"auth_managers": map[string]interface{}{
"machine": map[string]interface{}{
"api_key": cfg.AuthProviders.Machine.APIKey,
"gateway_addr": cfg.GatewayEndpoint,
"gateway_addr": cfg.Reva.Address,
},
},
},
+5 -4
View File
@@ -8,13 +8,14 @@ type Config struct {
Tracing *Tracing `yaml:"tracing"`
Logging *Logging `yaml:"log"`
Debug Debug `yaml:"debug"`
Supervised bool
Supervised bool `yaml:"-"`
GRPC GRPCConfig `yaml:"grpc"`
JWTSecret string
GatewayEndpoint string
SkipUserGroupsInToken bool
TokenManager *TokenManager `yaml:"token_manager"`
Reva *Reva `yaml:"reva"`
SkipUserGroupsInToken bool `yaml:"skip_user_groups_in_token"`
AuthProvider string `yaml:"auth_provider" env:"AUTH_MACHINE_AUTH_PROVIDER" desc:"The auth provider which should be used by the service"`
AuthProviders AuthProviders `yaml:"auth_providers"`
}
@@ -6,9 +6,8 @@ import (
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
@@ -27,14 +26,10 @@ func DefaultConfig() *config.Config {
Service: config.Service{
Name: "auth-machine",
},
GatewayEndpoint: "127.0.0.1:9142",
JWTSecret: "Pive-Fumkiu4",
AuthProvider: "ldap",
AuthProviders: config.AuthProviders{
Machine: config.MachineProvider{
APIKey: "change-me-please",
},
Reva: &config.Reva{
Address: "127.0.0.1:9142",
},
AuthProvider: "ldap",
}
}
@@ -61,6 +56,26 @@ 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.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
cfg.TokenManager = &config.TokenManager{
JWTSecret: cfg.Commons.TokenManager.JWTSecret,
}
} else if cfg.TokenManager == nil {
cfg.TokenManager = &config.TokenManager{}
}
if cfg.AuthProviders.Machine.APIKey == "" && cfg.Commons != nil && cfg.Commons.MachineAuthAPIKey != "" {
cfg.AuthProviders.Machine.APIKey = cfg.Commons.MachineAuthAPIKey
}
}
func Sanitize(cfg *config.Config) {
@@ -0,0 +1,45 @@
package parser
import (
"errors"
"github.com/owncloud/ocis/extensions/auth-machine/pkg/config"
"github.com/owncloud/ocis/extensions/auth-machine/pkg/config/defaults"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/shared"
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
)
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
return err
}
defaults.EnsureDefaults(cfg)
// load all env variables relevant to the config in the current context.
if err := envdecode.Decode(cfg); err != nil {
// no environment variable set for this config is an expected "error"
if !errors.Is(err, envdecode.ErrNoTargetFieldsAreSet) {
return err
}
}
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
if cfg.TokenManager.JWTSecret == "" {
return shared.MissingJWTTokenError(cfg.Service.Name)
}
if cfg.AuthProviders.Machine.APIKey == "" {
return shared.MissingMachineAuthApiKeyError(cfg.Service.Name)
}
return nil
}
@@ -0,0 +1,11 @@
package config
// Reva defines all available REVA configuration.
type Reva struct {
Address string `yaml:"address" env:"REVA_GATEWAY"`
}
// TokenManager is the config for using the reva token manager
type TokenManager struct {
JWTSecret string `yaml:"jwt_secret" env:"OCIS_JWT_SECRET;AUTH_MACHINE_JWT_SECRET"`
}
+15 -45
View File
@@ -7,15 +7,14 @@ import (
"os"
"path"
"strconv"
"strings"
"github.com/cs3org/reva/v2/cmd/revad/runtime"
"github.com/gofrs/uuid"
"github.com/oklog/run"
"github.com/owncloud/ocis/extensions/frontend/pkg/config"
"github.com/owncloud/ocis/extensions/frontend/pkg/config/parser"
"github.com/owncloud/ocis/extensions/storage/pkg/server/debug"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/conversions"
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/owncloud/ocis/ocis-pkg/sync"
"github.com/owncloud/ocis/ocis-pkg/tracing"
@@ -28,11 +27,12 @@ func Frontend(cfg *config.Config) *cli.Command {
return &cli.Command{
Name: "frontend",
Usage: "start frontend service",
Before: func(c *cli.Context) error {
if err := loadUserAgent(c, cfg); err != nil {
return err
Before: func(ctx *cli.Context) error {
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return nil
return err
},
Action: func(c *cli.Context) error {
logCfg := cfg.Logging
@@ -53,13 +53,6 @@ func Frontend(cfg *config.Config) *cli.Command {
uuid := uuid.Must(uuid.NewV4())
pidFile := path.Join(os.TempDir(), "revad-"+c.Command.Name+"-"+uuid.String()+".pid")
// pregenerate list of valid localhost ports for the desktop redirect_uri
// TODO use custom scheme like "owncloud://localhost/user/callback" tracked in
var desktopRedirectURIs [65535 - 1024]string
for port := 0; port < len(desktopRedirectURIs); port++ {
desktopRedirectURIs[port] = fmt.Sprintf("http://localhost:%d", (port + 1024))
}
archivers := []map[string]interface{}{
{
"enabled": true,
@@ -156,8 +149,8 @@ func frontendConfigFromStruct(c *cli.Context, cfg *config.Config, filesCfg map[s
"tracing_service_name": c.Command.Name,
},
"shared": map[string]interface{}{
"jwt_secret": cfg.JWTSecret,
"gatewaysvc": cfg.GatewayEndpoint, // Todo or address?
"jwt_secret": cfg.TokenManager.JWTSecret,
"gatewaysvc": cfg.Reva.Address, // Todo or address?
"skip_user_groups_in_token": cfg.SkipUserGroupsInToken,
},
"http": map[string]interface{}{
@@ -194,13 +187,13 @@ func frontendConfigFromStruct(c *cli.Context, cfg *config.Config, filesCfg map[s
"insecure": true,
},
"ocs": map[string]interface{}{
"storage_registry_svc": cfg.GatewayEndpoint,
"storage_registry_svc": cfg.Reva.Address,
"share_prefix": cfg.OCS.SharePrefix,
"home_namespace": cfg.OCS.HomeNamespace,
"resource_info_cache_ttl": cfg.OCS.ResourceInfoCacheTTL,
"prefix": cfg.OCS.Prefix,
"additional_info_attribute": cfg.OCS.AdditionalInfoAttribute,
"machine_auth_apikey": cfg.AuthMachine.APIKey,
"machine_auth_apikey": cfg.MachineAuthAPIKey,
"cache_warmup_driver": cfg.OCS.CacheWarmupDriver,
"cache_warmup_drivers": map[string]interface{}{
"cbox": map[string]interface{}{
@@ -210,7 +203,7 @@ func frontendConfigFromStruct(c *cli.Context, cfg *config.Config, filesCfg map[s
"db_port": cfg.OCS.CacheWarmupDrivers.CBOX.DBPort,
"db_name": cfg.OCS.CacheWarmupDrivers.CBOX.DBName,
"namespace": cfg.OCS.CacheWarmupDrivers.CBOX.Namespace,
"gatewaysvc": cfg.GatewayEndpoint,
"gatewaysvc": cfg.Reva.Address,
},
},
"config": map[string]interface{}{
@@ -295,8 +288,10 @@ func frontendConfigFromStruct(c *cli.Context, cfg *config.Config, filesCfg map[s
},
},
"spaces": map[string]interface{}{
"version": "0.0.1",
"enabled": cfg.EnableProjectSpaces,
"version": "0.0.1",
"enabled": cfg.EnableProjectSpaces || cfg.EnableShareJail,
"projects": cfg.EnableProjectSpaces,
"share_jail": cfg.EnableShareJail,
},
},
"version": map[string]interface{}{
@@ -313,31 +308,6 @@ func frontendConfigFromStruct(c *cli.Context, cfg *config.Config, filesCfg map[s
}
}
// loadUserAgent reads the user-agent-whitelist-lock-in, since it is a string flag, and attempts to construct a map of
// "user-agent":"challenge" locks in for Reva.
// Modifies cfg. Spaces don't need to be trimmed as urfavecli takes care of it. User agents with spaces are valid. i.e:
// Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:83.0) Gecko/20100101 Firefox/83.0
// This function works by relying in our format of specifying [user-agent:challenge] and the fact that the user agent
// might contain ":" (colon), so the original string is reversed, split in two parts, by the time it is split we
// have the indexes reversed and the tuple is in the format of [challenge:user-agent], then the same process is applied
// in reverse for each individual part
func loadUserAgent(c *cli.Context, cfg *config.Config) error {
cfg.Middleware.Auth.CredentialsByUserAgent = make(map[string]string)
locks := c.StringSlice("user-agent-whitelist-lock-in")
for _, v := range locks {
vv := conversions.Reverse(v)
parts := strings.SplitN(vv, ":", 2)
if len(parts) != 2 {
return fmt.Errorf("unexpected config value for user-agent lock-in: %v, expected format is user-agent:challenge", v)
}
cfg.Middleware.Auth.CredentialsByUserAgent[conversions.Reverse(parts[1])] = conversions.Reverse(parts[0])
}
return nil
}
// FrontendSutureService allows for the storage-frontend command to be embedded and supervised by a suture supervisor tree.
type FrontendSutureService struct {
cfg *config.Config
+30 -29
View File
@@ -8,31 +8,36 @@ type Config struct {
Tracing *Tracing `yaml:"tracing"`
Logging *Logging `yaml:"log"`
Debug Debug `yaml:"debug"`
Supervised bool
Supervised bool `yaml:"-"`
HTTP HTTPConfig `yaml:"http"`
// JWTSecret used to verify reva access token
JWTSecret string `yaml:"jwt_secret"`
GatewayEndpoint string
SkipUserGroupsInToken bool
EnableFavorites bool `yaml:"favorites"`
EnableProjectSpaces bool
TransferSecret string `yaml:"transfer_secret" env:"STORAGE_TRANSFER_SECRET"`
TokenManager *TokenManager `yaml:"token_manager"`
Reva *Reva `yaml:"reva"`
MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;FRONTEND_MACHINE_AUTH_API_KEY"`
SkipUserGroupsInToken bool `yaml:"skip_users_groups_in_token"`
EnableFavorites bool `yaml:"favorites"`
EnableProjectSpaces bool `yaml:"enable_project_spaces" env:"FRONTEND_ENABLE_PROJECT_SPACES" desc:"Indicates to clients that project spaces are supposed to be made available."`
EnableShareJail bool `yaml:"enable_share_jail" env:"FRONTEND_ENABLE_SHARE_JAIL" desc:"Indicates to clients that the share jail is supposed to be used."`
UploadMaxChunkSize int `yaml:"upload_max_chunk_size"`
UploadHTTPMethodOverride string `yaml:"upload_http_method_override"`
DefaultUploadProtocol string `yaml:"default_upload_protocol"`
TransferSecret string `yaml:"transfer_secret" env:"STORAGE_TRANSFER_SECRET"`
PublicURL string `yaml:"public_url" env:"OCIS_URL;FRONTEND_PUBLIC_URL"`
Archiver Archiver
AppProvider AppProvider
DataGateway DataGateway
OCS OCS
AuthMachine AuthMachine
Checksums Checksums
PublicURL string `yaml:"public_url" env:"OCIS_URL;FRONTEND_PUBLIC_URL"`
Middleware Middleware
Archiver Archiver `yaml:"archiver"`
AppProvider AppProvider `yaml:"app_provider"`
DataGateway DataGateway `yaml:"data_gateway"`
OCS OCS `yaml:"ocs"`
Checksums Checksums `yaml:"checksums"`
Middleware Middleware `yaml:"middleware"`
}
type Tracing struct {
Enabled bool `yaml:"enabled" env:"OCIS_TRACING_ENABLED;FRONTEND_TRACING_ENABLED" desc:"Activates tracing."`
@@ -72,25 +77,25 @@ type Middleware struct {
// Auth configures reva http auth middleware.
type Auth struct {
CredentialsByUserAgent map[string]string `yaml:"credentials_by_user_agenr"`
CredentialsByUserAgent map[string]string `yaml:"credentials_by_user_agent"`
}
type Archiver struct {
MaxNumFiles int64 `yaml:"max_num_files"`
MaxSize int64 `yaml:"max_size"`
Prefix string
Insecure bool `env:"OCIS_INSECURE;FRONTEND_ARCHIVER_INSECURE"`
MaxNumFiles int64 `yaml:"max_num_files"`
MaxSize int64 `yaml:"max_size"`
Prefix string `yaml:"-"`
Insecure bool `yaml:"insecure" env:"OCIS_INSECURE;FRONTEND_ARCHIVER_INSECURE"`
}
type AppProvider struct {
ExternalAddr string `yaml:"external_addr"`
Driver string `yaml:"driver"`
// WopiDriver WopiDriver `yaml:"wopi_driver"`
AppsURL string `yaml:"apps_url"`
OpenURL string `yaml:"open_url"`
NewURL string `yaml:"new_url"`
Prefix string
Insecure bool `env:"OCIS_INSECURE;FRONTEND_APPPROVIDER_INSECURE"`
AppsURL string `yaml:"-"`
OpenURL string `yaml:"-"`
NewURL string `yaml:"-"`
Prefix string `yaml:"-"`
Insecure bool `yaml:"insecure" env:"OCIS_INSECURE;FRONTEND_APPPROVIDER_INSECURE"`
}
type DataGateway struct {
@@ -120,10 +125,6 @@ type CBOXDriver struct {
Namespace string
}
type AuthMachine struct {
APIKey string `env:"OCIS_MACHINE_AUTH_API_KEY"`
}
type Checksums struct {
SupportedTypes []string `yaml:"supported_types"`
PreferredUploadType string `yaml:"preferred_upload_type"`
@@ -6,9 +6,8 @@ import (
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
@@ -28,15 +27,16 @@ func DefaultConfig() *config.Config {
Service: config.Service{
Name: "frontend",
},
GatewayEndpoint: "127.0.0.1:9142",
JWTSecret: "Pive-Fumkiu4",
Reva: &config.Reva{
Address: "127.0.0.1:9142",
},
PublicURL: "https://localhost:9200",
EnableFavorites: false,
EnableProjectSpaces: true,
EnableShareJail: true,
UploadMaxChunkSize: 1e+8,
UploadHTTPMethodOverride: "",
DefaultUploadProtocol: "tus",
TransferSecret: "replace-me-with-a-transfer-secret",
Checksums: config.Checksums{
SupportedTypes: []string{"sha1", "md5", "adler32"},
PreferredUploadType: "",
@@ -62,9 +62,6 @@ func DefaultConfig() *config.Config {
AdditionalInfoAttribute: "{{.Mail}}",
ResourceInfoCacheTTL: 0,
},
AuthMachine: config.AuthMachine{
APIKey: "change-me-please",
},
Middleware: config.Middleware{
Auth: config.Auth{
CredentialsByUserAgent: map[string]string{},
@@ -96,6 +93,31 @@ 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.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
cfg.TokenManager = &config.TokenManager{
JWTSecret: cfg.Commons.TokenManager.JWTSecret,
}
} else if cfg.TokenManager == nil {
cfg.TokenManager = &config.TokenManager{}
}
if cfg.TransferSecret == "" && cfg.Commons != nil && cfg.Commons.TransferSecret != "" {
cfg.TransferSecret = cfg.Commons.TransferSecret
}
if cfg.MachineAuthAPIKey == "" && cfg.Commons != nil && cfg.Commons.MachineAuthAPIKey != "" {
cfg.MachineAuthAPIKey = cfg.Commons.MachineAuthAPIKey
}
}
func Sanitize(cfg *config.Config) {
@@ -0,0 +1,50 @@
package parser
import (
"errors"
"github.com/owncloud/ocis/extensions/frontend/pkg/config"
"github.com/owncloud/ocis/extensions/frontend/pkg/config/defaults"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/shared"
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
)
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
return err
}
defaults.EnsureDefaults(cfg)
// load all env variables relevant to the config in the current context.
if err := envdecode.Decode(cfg); err != nil {
// no environment variable set for this config is an expected "error"
if !errors.Is(err, envdecode.ErrNoTargetFieldsAreSet) {
return err
}
}
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
if cfg.TokenManager.JWTSecret == "" {
return shared.MissingJWTTokenError(cfg.Service.Name)
}
if cfg.TransferSecret == "" {
return shared.MissingRevaTransferSecretError(cfg.Service.Name)
}
if cfg.MachineAuthAPIKey == "" {
return shared.MissingMachineAuthApiKeyError(cfg.Service.Name)
}
return nil
}
+11
View File
@@ -0,0 +1,11 @@
package config
// Reva defines all available REVA configuration.
type Reva struct {
Address string `yaml:"address" env:"REVA_GATEWAY"`
}
// TokenManager is the config for using the reva token manager
type TokenManager struct {
JWTSecret string `yaml:"jwt_secret" env:"OCIS_JWT_SECRET;FRONTEND_JWT_SECRET"`
}
+13 -11
View File
@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"os"
"path"
@@ -15,6 +16,7 @@ import (
"github.com/mitchellh/mapstructure"
"github.com/oklog/run"
"github.com/owncloud/ocis/extensions/gateway/pkg/config"
"github.com/owncloud/ocis/extensions/gateway/pkg/config/parser"
"github.com/owncloud/ocis/extensions/storage/pkg/server/debug"
"github.com/owncloud/ocis/extensions/storage/pkg/service/external"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
@@ -31,12 +33,12 @@ func Gateway(cfg *config.Config) *cli.Command {
return &cli.Command{
Name: "gateway",
Usage: "start gateway",
Before: func(c *cli.Context) error {
if cfg.DataGatewayPublicURL == "" {
cfg.DataGatewayPublicURL = strings.TrimRight(cfg.FrontendPublicURL, "/") + "/data"
Before: func(ctx *cli.Context) error {
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return nil
return err
},
Action: func(c *cli.Context) error {
logCfg := cfg.Logging
@@ -125,8 +127,8 @@ func gatewayConfigFromStruct(c *cli.Context, cfg *config.Config, logger log.Logg
"tracing_service_name": c.Command.Name,
},
"shared": map[string]interface{}{
"jwt_secret": cfg.JWTSecret,
"gatewaysvc": cfg.GatewayEndpoint,
"jwt_secret": cfg.TokenManager.JWTSecret,
"gatewaysvc": cfg.Reva.Address,
"skip_user_groups_in_token": cfg.SkipUserGroupsInToken,
},
"grpc": map[string]interface{}{
@@ -136,9 +138,9 @@ func gatewayConfigFromStruct(c *cli.Context, cfg *config.Config, logger log.Logg
"services": map[string]interface{}{
"gateway": map[string]interface{}{
// registries is located on the gateway
"authregistrysvc": cfg.GatewayEndpoint,
"storageregistrysvc": cfg.GatewayEndpoint,
"appregistrysvc": cfg.GatewayEndpoint,
"authregistrysvc": cfg.Reva.Address,
"storageregistrysvc": cfg.Reva.Address,
"appregistrysvc": cfg.Reva.Address,
// user metadata is located on the users services
"preferencessvc": cfg.UsersEndpoint,
"userprovidersvc": cfg.UsersEndpoint,
@@ -153,7 +155,7 @@ func gatewayConfigFromStruct(c *cli.Context, cfg *config.Config, logger log.Logg
"share_folder": cfg.ShareFolder, // ShareFolder is the location where to create shares in the recipient's storage provider.
// other
"disable_home_creation_on_login": cfg.DisableHomeCreationOnLogin,
"datagateway": cfg.DataGatewayPublicURL,
"datagateway": strings.TrimRight(cfg.FrontendPublicURL, "/") + "/data",
"transfer_shared_secret": cfg.TransferSecret,
"transfer_expires": cfg.TransferExpires,
"home_mapping": cfg.HomeMapping,
+30 -29
View File
@@ -4,42 +4,43 @@ import "github.com/owncloud/ocis/ocis-pkg/shared"
type Config struct {
*shared.Commons `yaml:"-"`
Service Service `yaml:"-"`
Tracing *Tracing `yaml:"tracing"`
Logging *Logging `yaml:"log"`
Debug Debug `yaml:"debug"`
Supervised bool
Service Service `yaml:"-"`
Tracing *Tracing `yaml:"tracing"`
Logging *Logging `yaml:"log"`
Debug Debug `yaml:"debug"`
Supervised bool `yaml:"-"`
GRPC GRPCConfig `yaml:"grpc"`
JWTSecret string
GatewayEndpoint string
TokenManager *TokenManager `yaml:"token_manager"`
Reva *Reva `yaml:"reva"`
SkipUserGroupsInToken bool
CommitShareToStorageGrant bool
CommitShareToStorageRef bool
ShareFolder string
DisableHomeCreationOnLogin bool
TransferSecret string `env:"STORAGE_TRANSFER_SECRET"`
TransferExpires int
HomeMapping string
EtagCacheTTL int
CommitShareToStorageGrant bool `yaml:"commit_share_to_storage_grant"`
CommitShareToStorageRef bool `yaml:"commit_share_to_storage_ref"`
ShareFolder string `yaml:"share_folder"`
DisableHomeCreationOnLogin bool `yaml:"disable_home_creation_on_login"`
TransferSecret string `yaml:"transfer_secret" env:"STORAGE_TRANSFER_SECRET"`
TransferExpires int `yaml:"transfer_expires"`
HomeMapping string `yaml:"home_mapping"`
EtagCacheTTL int `yaml:"etag_cache_ttl"`
UsersEndpoint string
GroupsEndpoint string
PermissionsEndpoint string
SharingEndpoint string
DataGatewayPublicURL string
FrontendPublicURL string `env:"OCIS_URL;GATEWAY_FRONTEND_PUBLIC_URL"`
AuthBasicEndpoint string
AuthBearerEndpoint string
AuthMachineEndpoint string
StoragePublicLinkEndpoint string
StorageUsersEndpoint string
StorageSharesEndpoint string
UsersEndpoint string `yaml:"users_endpoint"`
GroupsEndpoint string `yaml:"groups_endpoint"`
PermissionsEndpoint string `yaml:"permissions_endpoint"`
SharingEndpoint string `yaml:"sharing_endpoint"`
FrontendPublicURL string `yaml:"frontend_public_url" env:"OCIS_URL;GATEWAY_FRONTEND_PUBLIC_URL"`
AuthBasicEndpoint string `yaml:"auth_basic_endpoint"`
AuthBearerEndpoint string `yaml:"auth_bearer_endpoint"`
AuthMachineEndpoint string `yaml:"auth_machine_endpoint"`
StoragePublicLinkEndpoint string `yaml:"storage_public_link_endpoint"`
StorageUsersEndpoint string `yaml:"storage_users_endpoint"`
StorageSharesEndpoint string `yaml:"storage_shares_endpoint"`
StorageRegistry StorageRegistry
AppRegistry AppRegistry
StorageRegistry StorageRegistry `yaml:"storage_registry"`
AppRegistry AppRegistry `yaml:"app_registry"`
}
type Tracing struct {
Enabled bool `yaml:"enabled" env:"OCIS_TRACING_ENABLED;GATEWAY_TRACING_ENABLED" desc:"Activates tracing."`
@@ -6,9 +6,8 @@ import (
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
@@ -27,14 +26,14 @@ func DefaultConfig() *config.Config {
Service: config.Service{
Name: "gateway",
},
GatewayEndpoint: "127.0.0.1:9142",
JWTSecret: "Pive-Fumkiu4",
Reva: &config.Reva{
Address: "127.0.0.1:9142",
},
CommitShareToStorageGrant: true,
CommitShareToStorageRef: true,
ShareFolder: "Shares",
DisableHomeCreationOnLogin: true,
TransferSecret: "replace-me-with-a-transfer-secret",
TransferExpires: 24 * 60 * 60,
HomeMapping: "",
EtagCacheTTL: 0,
@@ -43,7 +42,6 @@ func DefaultConfig() *config.Config {
GroupsEndpoint: "localhost:9160",
PermissionsEndpoint: "localhost:9191",
SharingEndpoint: "localhost:9150",
DataGatewayPublicURL: "",
FrontendPublicURL: "https://localhost:9200",
AuthBasicEndpoint: "localhost:9146",
AuthBearerEndpoint: "localhost:9148",
@@ -85,6 +83,26 @@ 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.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
cfg.TokenManager = &config.TokenManager{
JWTSecret: cfg.Commons.TokenManager.JWTSecret,
}
} else if cfg.TokenManager == nil {
cfg.TokenManager = &config.TokenManager{}
}
if cfg.TransferSecret == "" && cfg.Commons != nil && cfg.Commons.TransferSecret != "" {
cfg.TransferSecret = cfg.Commons.TransferSecret
}
}
func Sanitize(cfg *config.Config) {
@@ -0,0 +1,46 @@
package parser
import (
"errors"
"github.com/owncloud/ocis/extensions/gateway/pkg/config"
"github.com/owncloud/ocis/extensions/gateway/pkg/config/defaults"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/shared"
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
)
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
return err
}
defaults.EnsureDefaults(cfg)
// load all env variables relevant to the config in the current context.
if err := envdecode.Decode(cfg); err != nil {
// no environment variable set for this config is an expected "error"
if !errors.Is(err, envdecode.ErrNoTargetFieldsAreSet) {
return err
}
}
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
if cfg.TokenManager.JWTSecret == "" {
return shared.MissingJWTTokenError(cfg.Service.Name)
}
if cfg.TransferSecret == "" {
return shared.MissingRevaTransferSecretError(cfg.Service.Name)
}
return nil
}
+11
View File
@@ -0,0 +1,11 @@
package config
// Reva defines all available REVA configuration.
type Reva struct {
Address string `yaml:"address" env:"REVA_GATEWAY"`
}
// TokenManager is the config for using the reva token manager
type TokenManager struct {
JWTSecret string `yaml:"jwt_secret" env:"OCIS_JWT_SECRET;GATEWAY_JWT_SECRET"`
}
+5 -1
View File
@@ -17,7 +17,11 @@ func Health(cfg *config.Config) *cli.Command {
Usage: "check health status",
Category: "info",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
+5 -1
View File
@@ -28,7 +28,11 @@ func Server(cfg *config.Config) *cli.Command {
Usage: fmt.Sprintf("start %s extension without runtime (unsupervised mode)", cfg.Service.Name),
Category: "server",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
@@ -9,10 +9,8 @@ import (
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
+6 -1
View File
@@ -10,7 +10,7 @@ import (
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
)
// ParseConfig loads accounts configuration from known paths.
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
@@ -28,5 +28,10 @@ func ParseConfig(cfg *config.Config) error {
// sanitize config
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
return nil
}
@@ -17,7 +17,11 @@ func Health(cfg *config.Config) *cli.Command {
Usage: "check health status",
Category: "info",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
@@ -23,7 +23,11 @@ func Server(cfg *config.Config) *cli.Command {
Usage: fmt.Sprintf("start %s extension without runtime (unsupervised mode)", cfg.Service.Name),
Category: "server",
Before: func(ctx *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
@@ -8,10 +8,8 @@ import (
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
@@ -10,7 +10,7 @@ import (
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
)
// ParseConfig loads accounts configuration from known paths.
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
@@ -30,5 +30,9 @@ func ParseConfig(cfg *config.Config) error {
// sanitize config
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
return nil
}
+5 -1
View File
@@ -17,7 +17,11 @@ func Health(cfg *config.Config) *cli.Command {
Usage: "check health status",
Category: "info",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
+5 -1
View File
@@ -23,7 +23,11 @@ func Server(cfg *config.Config) *cli.Command {
Usage: fmt.Sprintf("start %s extension without runtime (unsupervised mode)", cfg.Service.Name),
Category: "server",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
+2 -2
View File
@@ -18,8 +18,8 @@ type Config struct {
HTTP HTTP `yaml:"http"`
Reva Reva `yaml:"reva"`
TokenManager TokenManager `yaml:"token_manager"`
Reva *Reva `yaml:"reva"`
TokenManager *TokenManager `yaml:"token_manager"`
Spaces Spaces `yaml:"spaces"`
Identity Identity `yaml:"identity"`
@@ -6,6 +6,13 @@ import (
"github.com/owncloud/ocis/extensions/graph/pkg/config"
)
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
func DefaultConfig() *config.Config {
return &config.Config{
Debug: config.Debug{
@@ -20,12 +27,9 @@ func DefaultConfig() *config.Config {
Service: config.Service{
Name: "graph",
},
Reva: config.Reva{
Reva: &config.Reva{
Address: "127.0.0.1:9142",
},
TokenManager: config.TokenManager{
JWTSecret: "Pive-Fumkiu4",
},
Spaces: config.Spaces{
WebDavBase: "https://localhost:9200",
WebDavPath: "/dav/spaces/",
@@ -38,7 +42,6 @@ func DefaultConfig() *config.Config {
URI: "ldaps://localhost:9235",
Insecure: true,
BindDN: "uid=libregraph,ou=sysusers,o=libregraph-idm",
BindPassword: "idm",
UseServerUUID: false,
WriteEnabled: true,
UserBaseDN: "ou=users,o=libregraph-idm",
@@ -89,6 +92,14 @@ func EnsureDefaults(cfg *config.Config) {
} else if cfg.Tracing == nil {
cfg.Tracing = &config.Tracing{}
}
if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
cfg.TokenManager = &config.TokenManager{
JWTSecret: cfg.Commons.TokenManager.JWTSecret,
}
} else if cfg.TokenManager == nil {
cfg.TokenManager = &config.TokenManager{}
}
}
func Sanitize(cfg *config.Config) {
+14 -1
View File
@@ -6,11 +6,12 @@ import (
"github.com/owncloud/ocis/extensions/graph/pkg/config"
"github.com/owncloud/ocis/extensions/graph/pkg/config/defaults"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/shared"
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
)
// ParseConfig loads accounts configuration from known paths.
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
@@ -29,5 +30,17 @@ func ParseConfig(cfg *config.Config) error {
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
if cfg.TokenManager.JWTSecret == "" {
return shared.MissingJWTTokenError(cfg.Service.Name)
}
if cfg.Identity.Backend == "ldap" && cfg.Identity.LDAP.BindPassword == "" {
return shared.MissingLDAPBindPassword(cfg.Service.Name)
}
return nil
}
+44 -14
View File
@@ -31,8 +31,19 @@ import (
merrors "go-micro.dev/v4/errors"
)
// GetDrives implements the Service interface.
// GetDrives lists all drives the current user has access to
func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) {
g.getDrives(w, r, false)
}
// GetAllDrives lists all drives, including other user's drives, if the current
// user has the permission.
func (g Graph) GetAllDrives(w http.ResponseWriter, r *http.Request) {
g.getDrives(w, r, true)
}
// getDrives implements the Service interface.
func (g Graph) getDrives(w http.ResponseWriter, r *http.Request, unrestricted bool) {
sanitizedPath := strings.TrimPrefix(r.URL.Path, "/graph/v1.0/")
// Parse the request with odata parser
odataReq, err := godata.ParseRequest(r.Context(), sanitizedPath, r.URL.Query())
@@ -41,7 +52,10 @@ func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) {
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
return
}
g.logger.Info().Interface("query", r.URL.Query()).Msg("Calling GetDrives")
g.logger.Debug().
Interface("query", r.URL.Query()).
Bool("unrestricted", unrestricted).
Msg("Calling getDrives")
ctx := r.Context()
filters, err := generateCs3Filters(odataReq)
@@ -50,7 +64,7 @@ func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) {
errorcode.NotSupported.Render(w, r, http.StatusNotImplemented, err.Error())
return
}
res, err := g.ListStorageSpacesWithFilters(ctx, filters)
res, err := g.ListStorageSpacesWithFilters(ctx, filters, unrestricted)
switch {
case err != nil:
g.logger.Error().Err(err).Msg(ListStorageSpacesTransportErr)
@@ -106,7 +120,7 @@ func (g Graph) GetSingleDrive(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
filters := []*storageprovider.ListStorageSpacesRequest_Filter{listStorageSpacesIDFilter(driveID)}
res, err := g.ListStorageSpacesWithFilters(ctx, filters)
res, err := g.ListStorageSpacesWithFilters(ctx, filters, true)
switch {
case err != nil:
g.logger.Error().Err(err).Msg(ListStorageSpacesTransportErr)
@@ -273,7 +287,8 @@ func (g Graph) UpdateDrive(w http.ResponseWriter, r *http.Request) {
identifierParts := strings.Split(driveID, "!")
switch len(identifierParts) {
case 1:
root.StorageId, root.OpaqueId = identifierParts[0], identifierParts[0]
sID, _ := resourceid.StorageIDUnwrap(identifierParts[0])
root.StorageId, root.OpaqueId = identifierParts[0], sID
case 2:
root.StorageId, root.OpaqueId = identifierParts[0], identifierParts[1]
default:
@@ -398,7 +413,7 @@ func (g Graph) formatDrives(ctx context.Context, baseURL *url.URL, storageSpaces
}
// ListStorageSpacesWithFilters List Storage Spaces using filters
func (g Graph) ListStorageSpacesWithFilters(ctx context.Context, filters []*storageprovider.ListStorageSpacesRequest_Filter) (*storageprovider.ListStorageSpacesResponse, error) {
func (g Graph) ListStorageSpacesWithFilters(ctx context.Context, filters []*storageprovider.ListStorageSpacesRequest_Filter, unrestricted bool) (*storageprovider.ListStorageSpacesResponse, error) {
client := g.GetGatewayClient()
permissions := make(map[string]struct{}, 1)
@@ -423,17 +438,35 @@ func (g Graph) ListStorageSpacesWithFilters(ctx context.Context, filters []*stor
Decoder: "json",
Value: value,
},
"unrestricted": {
Decoder: "plain",
Value: []byte(strconv.FormatBool(unrestricted)),
},
}},
Filters: filters,
})
return res, err
}
func generateSpaceId(id *storageprovider.ResourceId) (spaceID string) {
spaceID = id.GetStorageId()
// 2nd ID to compare is the opaque ID of the Space Root
spaceID2 := id.GetOpaqueId()
if strings.Contains(spaceID, "$") {
spaceID2, _ = resourceid.StorageIDUnwrap(spaceID)
}
// Append opaqueID only if it is different from the spaceID2
if id.OpaqueId != spaceID2 {
spaceID += "!" + id.OpaqueId
}
return spaceID
}
func (g Graph) cs3StorageSpaceToDrive(ctx context.Context, baseURL *url.URL, space *storageprovider.StorageSpace) (*libregraph.Drive, error) {
if space.Root == nil {
return nil, fmt.Errorf("space has no root")
}
rootID := resourceid.OwnCloudResourceIDWrap(space.Root)
spaceID := generateSpaceId(space.Root)
var permissions []libregraph.Permission
if space.Opaque != nil {
@@ -491,18 +524,14 @@ func (g Graph) cs3StorageSpaceToDrive(ctx context.Context, baseURL *url.URL, spa
}
}
spaceID := space.Root.StorageId
if space.Root.OpaqueId != space.Root.StorageId {
spaceID = rootID
}
drive := &libregraph.Drive{
Id: &spaceID,
Id: libregraph.PtrString(spaceID),
Name: &space.Name,
//"createdDateTime": "string (timestamp)", // TODO read from StorageSpace ... needs Opaque for now
//"description": "string", // TODO read from StorageSpace ... needs Opaque for now
DriveType: &space.SpaceType,
Root: &libregraph.DriveItem{
Id: &rootID,
Id: libregraph.PtrString(resourceid.OwnCloudResourceIDWrap(space.Root)),
Permissions: permissions,
},
}
@@ -735,9 +764,10 @@ func (g Graph) DeleteDrive(w http.ResponseWriter, r *http.Request) {
root := &storageprovider.ResourceId{}
identifierParts := strings.Split(driveID, "!")
sID, _ := resourceid.StorageIDUnwrap(identifierParts[0])
switch len(identifierParts) {
case 1:
root.StorageId, root.OpaqueId = identifierParts[0], identifierParts[0]
root.StorageId, root.OpaqueId = identifierParts[0], sID
case 2:
root.StorageId, root.OpaqueId = identifierParts[0], identifierParts[1]
default:
@@ -3,7 +3,7 @@ package svc_test
import (
"testing"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
+11 -6
View File
@@ -13,10 +13,11 @@ import (
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
"github.com/cs3org/reva/v2/pkg/rgrpc/status"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
libregraph "github.com/owncloud/libre-graph-api-go"
"github.com/owncloud/ocis/extensions/graph/mocks"
"github.com/owncloud/ocis/extensions/graph/pkg/config"
"github.com/owncloud/ocis/extensions/graph/pkg/config/defaults"
service "github.com/owncloud/ocis/extensions/graph/pkg/service/v0"
"github.com/owncloud/ocis/extensions/graph/pkg/service/v0/errorcode"
@@ -30,15 +31,19 @@ var _ = Describe("Graph", func() {
httpClient *mocks.HTTPClient
eventsPublisher mocks.Publisher
ctx context.Context
cfg *config.Config
)
JustBeforeEach(func() {
ctx = context.Background()
cfg = defaults.FullDefaultConfig()
cfg.TokenManager.JWTSecret = "loremipsum"
gatewayClient = &mocks.GatewayClient{}
httpClient = &mocks.HTTPClient{}
eventsPublisher = mocks.Publisher{}
svc = service.NewService(
service.Config(defaults.DefaultConfig()),
service.Config(cfg),
service.WithGatewayClient(gatewayClient),
service.WithHTTPClient(httpClient),
service.EventsPublisher(&eventsPublisher),
@@ -196,7 +201,7 @@ var _ = Describe("Graph", func() {
Id: &provider.StorageSpaceId{OpaqueId: "aID!differentID"},
SpaceType: "mountpoint",
Root: &provider.ResourceId{
StorageId: "aID",
StorageId: "prID$aID",
OpaqueId: "differentID",
},
Name: "New Folder",
@@ -241,11 +246,11 @@ var _ = Describe("Graph", func() {
value := response["value"][0]
Expect(*value.DriveAlias).To(Equal("mountpoint/new-folder"))
Expect(*value.DriveType).To(Equal("mountpoint"))
Expect(*value.Id).To(Equal("aID!differentID"))
Expect(*value.Id).To(Equal("prID$aID!differentID"))
Expect(*value.Name).To(Equal("New Folder"))
Expect(*value.Root.WebDavUrl).To(Equal("https://localhost:9200/dav/spaces/aID!differentID"))
Expect(*value.Root.WebDavUrl).To(Equal("https://localhost:9200/dav/spaces/prID$aID!differentID"))
Expect(*value.Root.ETag).To(Equal("101112131415"))
Expect(*value.Root.Id).To(Equal("aID!differentID"))
Expect(*value.Root.Id).To(Equal("prID$aID!differentID"))
Expect(*value.Root.RemoteItem.ETag).To(Equal("123456789"))
Expect(*value.Root.RemoteItem.Id).To(Equal("ownerStorageID!opaqueID"))
Expect(value.Root.RemoteItem.LastModifiedDateTime.UTC()).To(Equal(time.Unix(1648327606, 0).UTC()))
+2 -2
View File
@@ -59,7 +59,7 @@ func NewService(opts ...Option) Service {
switch options.Config.Identity.Backend {
case "cs3":
backend = &identity.CS3{
Config: &options.Config.Reva,
Config: options.Config.Reva,
Logger: &options.Logger,
}
case "ldap":
@@ -173,7 +173,7 @@ func NewService(opts ...Option) Service {
account.JWTSecret(options.Config.TokenManager.JWTSecret)),
)
r.Route("/drives", func(r chi.Router) {
r.Get("/", svc.GetDrives)
r.Get("/", svc.GetAllDrives)
r.Post("/", svc.CreateDrive)
r.Route("/{driveID}", func(r chi.Router) {
r.Patch("/", svc.UpdateDrive)
+11 -2
View File
@@ -3,6 +3,7 @@ package command
import (
"context"
"flag"
"fmt"
"os"
"path"
"path/filepath"
@@ -11,6 +12,7 @@ import (
"github.com/gofrs/uuid"
"github.com/oklog/run"
"github.com/owncloud/ocis/extensions/group/pkg/config"
"github.com/owncloud/ocis/extensions/group/pkg/config/parser"
"github.com/owncloud/ocis/extensions/storage/pkg/server/debug"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/ldap"
@@ -26,6 +28,13 @@ func Groups(cfg *config.Config) *cli.Command {
return &cli.Command{
Name: "groups",
Usage: "start groups service",
Before: func(ctx *cli.Context) error {
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logCfg := cfg.Logging
logger := log.NewLogger(
@@ -111,8 +120,8 @@ func groupsConfigFromStruct(c *cli.Context, cfg *config.Config) map[string]inter
"tracing_service_name": c.Command.Name,
},
"shared": map[string]interface{}{
"jwt_secret": cfg.JWTSecret,
"gatewaysvc": cfg.GatewayEndpoint,
"jwt_secret": cfg.TokenManager.JWTSecret,
"gatewaysvc": cfg.Reva.Address,
"skip_user_groups_in_token": cfg.SkipUserGroupsInToken,
},
"grpc": map[string]interface{}{
+9 -8
View File
@@ -8,16 +8,17 @@ type Config struct {
Tracing *Tracing `yaml:"tracing"`
Logging *Logging `yaml:"log"`
Debug Debug `yaml:"debug"`
Supervised bool
Supervised bool `yaml:"-"`
GRPC GRPCConfig `yaml:"grpc"`
JWTSecret string
GatewayEndpoint string
SkipUserGroupsInToken bool
GroupMembersCacheExpiration int
Driver string
Drivers Drivers
TokenManager *TokenManager `yaml:"token_manager"`
Reva *Reva `yaml:"reva"`
SkipUserGroupsInToken bool `yaml:"skip_user_groups_in_token"`
GroupMembersCacheExpiration int `yaml:"group_members_cache_expiration"`
Driver string `yaml:"driver"`
Drivers Drivers `yaml:"drivers"`
}
type Tracing struct {
Enabled bool `yaml:"enabled" env:"OCIS_TRACING_ENABLED;GROUPS_TRACING_ENABLED" desc:"Activates tracing."`
@@ -64,7 +65,7 @@ type LDAPDriver struct {
CACert string `env:"LDAP_CACERT;GROUPS_LDAP_CACERT"`
Insecure bool `env:"LDAP_INSECURE;GROUPS_LDAP_INSECURE"`
BindDN string `env:"LDAP_BIND_DN;GROUPS_LDAP_BIND_DN"`
BindPassword string `env:"LDAP_BIND_PASSWORD;GROUPS_LDAP_BIND_PASSWORD"`
BindPassword string `yaml:"bind_password" env:"LDAP_BIND_PASSWORD;GROUPS_LDAP_BIND_PASSWORD"`
UserBaseDN string `env:"LDAP_USER_BASE_DN;GROUPS_LDAP_USER_BASE_DN"`
GroupBaseDN string `env:"LDAP_GROUP_BASE_DN;GROUPS_LDAP_GROUP_BASE_DN"`
UserScope string `env:"LDAP_USER_SCOPE;GROUPS_LDAP_USER_SCOPE"`
@@ -9,9 +9,8 @@ import (
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
@@ -28,12 +27,13 @@ func DefaultConfig() *config.Config {
Protocol: "tcp",
},
Service: config.Service{
Name: "user",
Name: "group",
},
GroupMembersCacheExpiration: 5,
GatewayEndpoint: "127.0.0.1:9142",
JWTSecret: "Pive-Fumkiu4",
Driver: "ldap",
Reva: &config.Reva{
Address: "127.0.0.1:9142",
},
Driver: "ldap",
Drivers: config.Drivers{
LDAP: config.LDAPDriver{
URI: "ldaps://localhost:9235",
@@ -49,7 +49,6 @@ func DefaultConfig() *config.Config {
UserObjectClass: "inetOrgPerson",
GroupObjectClass: "groupOfNames",
BindDN: "uid=reva,ou=sysusers,o=libregraph-idm",
BindPassword: "reva",
IDP: "https://localhost:9200",
UserSchema: config.LDAPUserSchema{
ID: "ownclouduuid",
@@ -108,6 +107,22 @@ 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.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
cfg.TokenManager = &config.TokenManager{
JWTSecret: cfg.Commons.TokenManager.JWTSecret,
}
} else if cfg.TokenManager == nil {
cfg.TokenManager = &config.TokenManager{}
}
}
func Sanitize(cfg *config.Config) {
@@ -0,0 +1,46 @@
package parser
import (
"errors"
"github.com/owncloud/ocis/extensions/group/pkg/config"
"github.com/owncloud/ocis/extensions/group/pkg/config/defaults"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/shared"
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
)
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
return err
}
defaults.EnsureDefaults(cfg)
// load all env variables relevant to the config in the current context.
if err := envdecode.Decode(cfg); err != nil {
// no environment variable set for this config is an expected "error"
if !errors.Is(err, envdecode.ErrNoTargetFieldsAreSet) {
return err
}
}
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
if cfg.TokenManager.JWTSecret == "" {
return shared.MissingJWTTokenError(cfg.Service.Name)
}
if cfg.Drivers.LDAP.BindPassword == "" && cfg.Driver == "ldap" {
return shared.MissingLDAPBindPassword(cfg.Service.Name)
}
return nil
}
+11
View File
@@ -0,0 +1,11 @@
package config
// Reva defines all available REVA configuration.
type Reva struct {
Address string `yaml:"address" env:"REVA_GATEWAY"`
}
// TokenManager is the config for using the reva token manager
type TokenManager struct {
JWTSecret string `yaml:"jwt_secret" env:"OCIS_JWT_SECRET;GROUPS_JWT_SECRET"`
}
-13
View File
@@ -40,17 +40,4 @@ userPassword:: {{ .Password }}
{{ end -}}
## Service user for the settings service
dn: uid=95cb8724-03b2-11eb-a0a6-c33ef8ef53ad,ou=users,o=libregraph-idm
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: ownCloud
objectClass: person
objectClass: top
uid: 95cb8724-03b2-11eb-a0a6-c33ef8ef53ad
givenName: 95cb8724-03b2-11eb-a0a6-c33ef8ef53ad
sn: 95cb8724-03b2-11eb-a0a6-c33ef8ef53ad
cn: 95cb8724-03b2-11eb-a0a6-c33ef8ef53ad
displayName: 95cb8724-03b2-11eb-a0a6-c33ef8ef53ad
ownCloudUUID: 95cb8724-03b2-11eb-a0a6-c33ef8ef53ad
+5 -1
View File
@@ -17,7 +17,11 @@ func Health(cfg *config.Config) *cli.Command {
Usage: "check health status",
Category: "info",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
+5 -1
View File
@@ -29,7 +29,11 @@ func Server(cfg *config.Config) *cli.Command {
Usage: fmt.Sprintf("start %s extension without runtime (unsupervised mode)", cfg.Service.Name),
Category: "server",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
@@ -9,10 +9,8 @@ import (
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
@@ -22,12 +20,6 @@ func DefaultConfig() *config.Config {
Name: "idm",
},
CreateDemoUsers: false,
ServiceUserPasswords: config.ServiceUserPasswords{
OcisAdmin: "admin",
Idm: "idm",
Idp: "idp",
Reva: "reva",
},
IDM: config.Settings{
LDAPSAddr: "127.0.0.1:9235",
Cert: path.Join(defaults.BaseDataPath(), "idm", "ldap.crt"),
+21 -1
View File
@@ -6,11 +6,12 @@ import (
"github.com/owncloud/ocis/extensions/idm/pkg/config"
"github.com/owncloud/ocis/extensions/idm/pkg/config/defaults"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/shared"
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
)
// ParseConfig loads accounts configuration from known paths.
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
@@ -28,5 +29,24 @@ func ParseConfig(cfg *config.Config) error {
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
if cfg.ServiceUserPasswords.Idm == "" {
return shared.MissingServiceUserPassword(cfg.Service.Name, "IDM")
}
if cfg.ServiceUserPasswords.OcisAdmin == "" {
return shared.MissingServiceUserPassword(cfg.Service.Name, "admin")
}
if cfg.ServiceUserPasswords.Idp == "" {
return shared.MissingServiceUserPassword(cfg.Service.Name, "IDP")
}
if cfg.ServiceUserPasswords.Reva == "" {
return shared.MissingServiceUserPassword(cfg.Service.Name, "REVA")
}
return nil
}
+5 -1
View File
@@ -17,7 +17,11 @@ func Health(cfg *config.Config) *cli.Command {
Usage: "check health status",
Category: "info",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
+5 -1
View File
@@ -23,7 +23,11 @@ func Server(cfg *config.Config) *cli.Command {
Usage: fmt.Sprintf("start %s extension without runtime (unsupervised mode)", cfg.Service.Name),
Category: "server",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
@@ -10,10 +10,8 @@ import (
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
@@ -71,7 +69,6 @@ func DefaultConfig() *config.Config {
URI: "ldaps://localhost:9235",
TLSCACert: path.Join(defaults.BaseDataPath(), "idm", "ldap.crt"),
BindDN: "uid=idp,ou=sysusers,o=libregraph-idm",
BindPassword: "idp",
BaseDN: "ou=users,o=libregraph-idm",
Scope: "sub",
LoginAttribute: "uid",
+10 -1
View File
@@ -6,11 +6,12 @@ import (
"github.com/owncloud/ocis/extensions/idp/pkg/config"
"github.com/owncloud/ocis/extensions/idp/pkg/config/defaults"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/shared"
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
)
// ParseConfig loads accounts configuration from known paths.
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
@@ -29,5 +30,13 @@ func ParseConfig(cfg *config.Config) error {
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
if cfg.Ldap.BindPassword == "" {
return shared.MissingLDAPBindPassword(cfg.Service.Name)
}
return nil
}
+5 -1
View File
@@ -20,7 +20,11 @@ func Server(cfg *config.Config) *cli.Command {
Usage: fmt.Sprintf("start %s extension without runtime (unsupervised mode)", cfg.Service.Name),
Category: "server",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
@@ -12,10 +12,8 @@ import (
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
+5 -1
View File
@@ -10,7 +10,7 @@ import (
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
)
// ParseConfig loads accounts configuration from known paths.
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
@@ -29,5 +29,9 @@ func ParseConfig(cfg *config.Config) error {
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
return nil
}
@@ -86,7 +86,7 @@ func (m Mail) getReceiverAddresses(receivers []string) ([]string, error) {
res, err := m.gatewayClient.Authenticate(context.Background(), &gateway.AuthenticateRequest{
Type: "machine",
ClientId: "userid:" + id,
ClientSecret: m.conf.Notifications.MachineAuthSecret,
ClientSecret: m.conf.Notifications.MachineAuthAPIKey,
})
if err != nil {
return nil, err
+1 -1
View File
@@ -48,7 +48,7 @@ type SutureService struct {
// NewSutureService creates a new notifications.SutureService
func NewSutureService(cfg *ociscfg.Config) suture.Service {
cfg.Settings.Commons = cfg.Commons
cfg.Notifications.Commons = cfg.Commons
return SutureService{
cfg: cfg.Notifications,
}
@@ -21,7 +21,11 @@ func Server(cfg *config.Config) *cli.Command {
Usage: fmt.Sprintf("start %s extension without runtime (unsupervised mode)", cfg.Service.Name),
Category: "server",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
@@ -22,10 +22,11 @@ type Config struct {
// Notifications definces the config options for the notifications service.
type Notifications struct {
*shared.Commons `yaml:"-"`
SMTP SMTP `yaml:"SMTP"`
Events Events `yaml:"events"`
RevaGateway string `yaml:"reva_gateway" env:"REVA_GATEWAY;NOTIFICATIONS_REVA_GATEWAY"`
MachineAuthSecret string `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;NOTIFICATIONS_MACHINE_AUTH_API_KEY"`
MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;NOTIFICATIONS_MACHINE_AUTH_API_KEY"`
}
// SMTP combines the smtp configuration options.
@@ -1,13 +1,13 @@
package defaults
import "github.com/owncloud/ocis/extensions/notifications/pkg/config"
import (
"github.com/owncloud/ocis/extensions/notifications/pkg/config"
)
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
@@ -31,8 +31,7 @@ func DefaultConfig() *config.Config {
Cluster: "ocis-cluster",
ConsumerGroup: "notifications",
},
RevaGateway: "127.0.0.1:9142",
MachineAuthSecret: "change-me-please",
RevaGateway: "127.0.0.1:9142",
},
}
}
@@ -49,6 +48,10 @@ func EnsureDefaults(cfg *config.Config) {
} else if cfg.Log == nil {
cfg.Log = &config.Log{}
}
if cfg.Notifications.MachineAuthAPIKey == "" && cfg.Commons != nil && cfg.Commons.MachineAuthAPIKey != "" {
cfg.Notifications.MachineAuthAPIKey = cfg.Commons.MachineAuthAPIKey
}
}
func Sanitize(cfg *config.Config) {
@@ -6,11 +6,12 @@ import (
"github.com/owncloud/ocis/extensions/notifications/pkg/config"
"github.com/owncloud/ocis/extensions/notifications/pkg/config/defaults"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/shared"
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
)
// ParseConfig loads accounts configuration from known paths.
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
@@ -29,5 +30,13 @@ func ParseConfig(cfg *config.Config) error {
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
if cfg.Notifications.MachineAuthAPIKey == "" {
return shared.MissingMachineAuthApiKeyError(cfg.Service.Name)
}
return nil
}
+8 -33
View File
@@ -4,14 +4,13 @@ import (
"context"
"flag"
"fmt"
"strings"
"github.com/cs3org/reva/v2/pkg/micro/ocdav"
"github.com/oklog/run"
"github.com/owncloud/ocis/extensions/ocdav/pkg/config"
"github.com/owncloud/ocis/extensions/ocdav/pkg/config/parser"
"github.com/owncloud/ocis/extensions/storage/pkg/server/debug"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/conversions"
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/owncloud/ocis/ocis-pkg/sync"
"github.com/owncloud/ocis/ocis-pkg/tracing"
@@ -25,11 +24,12 @@ func OCDav(cfg *config.Config) *cli.Command {
return &cli.Command{
Name: "ocdav",
Usage: "start ocdav service",
Before: func(c *cli.Context) error {
if err := loadUserAgent(c, cfg); err != nil {
return err
Before: func(ctx *cli.Context) error {
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return nil
return err
},
Action: func(c *cli.Context) error {
logCfg := cfg.Logging
@@ -59,8 +59,8 @@ func OCDav(cfg *config.Config) *cli.Command {
ocdav.Insecure(cfg.Insecure),
ocdav.PublicURL(cfg.PublicURL),
ocdav.Prefix(cfg.HTTP.Prefix),
ocdav.GatewaySvc(cfg.GatewayEndpoint),
ocdav.JWTSecret(cfg.JWTSecret),
ocdav.GatewaySvc(cfg.Reva.Address),
ocdav.JWTSecret(cfg.TokenManager.JWTSecret),
// ocdav.FavoriteManager() // FIXME needs a proper persistence implementation
// ocdav.LockSystem(), // will default to the CS3 lock system
// ocdav.TLSConfig() // tls config for the http server
@@ -144,28 +144,3 @@ func (s OCDavSutureService) Serve(ctx context.Context) error {
return nil
}
// loadUserAgent reads the user-agent-whitelist-lock-in, since it is a string flag, and attempts to construct a map of
// "user-agent":"challenge" locks in for Reva.
// Modifies cfg. Spaces don't need to be trimmed as urfavecli takes care of it. User agents with spaces are valid. i.e:
// Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:83.0) Gecko/20100101 Firefox/83.0
// This function works by relying in our format of specifying [user-agent:challenge] and the fact that the user agent
// might contain ":" (colon), so the original string is reversed, split in two parts, by the time it is split we
// have the indexes reversed and the tuple is in the format of [challenge:user-agent], then the same process is applied
// in reverse for each individual part
func loadUserAgent(c *cli.Context, cfg *config.Config) error {
cfg.Middleware.Auth.CredentialsByUserAgent = make(map[string]string)
locks := c.StringSlice("user-agent-whitelist-lock-in")
for _, v := range locks {
vv := conversions.Reverse(v)
parts := strings.SplitN(vv, ":", 2)
if len(parts) != 2 {
return fmt.Errorf("unexpected config value for user-agent lock-in: %v, expected format is user-agent:challenge", v)
}
cfg.Middleware.Auth.CredentialsByUserAgent[conversions.Reverse(parts[1])] = conversions.Reverse(parts[0])
}
return nil
}
+7 -7
View File
@@ -8,14 +8,14 @@ type Config struct {
Tracing *Tracing `yaml:"tracing"`
Logging *Logging `yaml:"log"`
Debug Debug `yaml:"debug"`
Supervised bool
Supervised bool `yaml:"-"`
HTTP HTTPConfig `yaml:"http"`
// JWTSecret used to verify reva access token
JWTSecret string `yaml:"jwt_secret"`
GatewayEndpoint string
SkipUserGroupsInToken bool
TokenManager *TokenManager `yaml:"token_manager"`
Reva *Reva `yaml:"reva"`
SkipUserGroupsInToken bool `yaml:"skip_user_groups_in_token"`
WebdavNamespace string `yaml:"webdav_namespace"`
FilesNamespace string `yaml:"files_namespace"`
@@ -26,8 +26,8 @@ type Config struct {
// Insecure certificates allowed when making requests to the gateway
Insecure bool `yaml:"insecure" env:"OCIS_INSECURE;OCDAV_INSECURE"`
// Timeout in seconds when making requests to the gateway
Timeout int64 `yaml:"timeout"`
Middleware Middleware
Timeout int64 `yaml:"timeout"`
Middleware Middleware `yaml:"middleware"`
}
type Tracing struct {
Enabled bool `yaml:"enabled" env:"OCIS_TRACING_ENABLED;OCDAV_TRACING_ENABLED" desc:"Activates tracing."`
@@ -6,9 +6,8 @@ import (
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
@@ -28,8 +27,9 @@ func DefaultConfig() *config.Config {
Service: config.Service{
Name: "ocdav",
},
GatewayEndpoint: "127.0.0.1:9142",
JWTSecret: "Pive-Fumkiu4",
Reva: &config.Reva{
Address: "127.0.0.1:9142",
},
WebdavNamespace: "/users/{{.Id.OpaqueId}}",
FilesNamespace: "/users/{{.Id.OpaqueId}}",
SharesNamespace: "/Shares",
@@ -67,6 +67,22 @@ 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.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
cfg.TokenManager = &config.TokenManager{
JWTSecret: cfg.Commons.TokenManager.JWTSecret,
}
} else if cfg.TokenManager == nil {
cfg.TokenManager = &config.TokenManager{}
}
}
func Sanitize(cfg *config.Config) {
@@ -0,0 +1,42 @@
package parser
import (
"errors"
"github.com/owncloud/ocis/extensions/ocdav/pkg/config"
"github.com/owncloud/ocis/extensions/ocdav/pkg/config/defaults"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/shared"
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
)
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
return err
}
defaults.EnsureDefaults(cfg)
// load all env variables relevant to the config in the current context.
if err := envdecode.Decode(cfg); err != nil {
// no environment variable set for this config is an expected "error"
if !errors.Is(err, envdecode.ErrNoTargetFieldsAreSet) {
return err
}
}
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
if cfg.TokenManager.JWTSecret == "" {
return shared.MissingJWTTokenError(cfg.Service.Name)
}
return nil
}
+11
View File
@@ -0,0 +1,11 @@
package config
// Reva defines all available REVA configuration.
type Reva struct {
Address string `yaml:"address" env:"REVA_GATEWAY"`
}
// TokenManager is the config for using the reva token manager
type TokenManager struct {
JWTSecret string `yaml:"jwt_secret" env:"OCIS_JWT_SECRET;OCDAV_JWT_SECRET"`
}
+5 -1
View File
@@ -17,7 +17,11 @@ func Health(cfg *config.Config) *cli.Command {
Usage: "check health status",
Category: "info",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
+5 -1
View File
@@ -24,7 +24,11 @@ func Server(cfg *config.Config) *cli.Command {
Usage: fmt.Sprintf("start %s extension without runtime (unsupervised mode)", cfg.Service.Name),
Category: "server",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
+2 -2
View File
@@ -18,8 +18,8 @@ type Config struct {
HTTP HTTP `yaml:"http"`
TokenManager TokenManager `yaml:"token_manager"`
Reva Reva `yaml:"reva"`
TokenManager *TokenManager `yaml:"token_manager"`
Reva *Reva `yaml:"reva"`
IdentityManagement IdentityManagement `yaml:"identity_management"`
@@ -8,10 +8,8 @@ import (
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
@@ -37,16 +35,11 @@ func DefaultConfig() *config.Config {
Service: config.Service{
Name: "ocs",
},
TokenManager: config.TokenManager{
JWTSecret: "Pive-Fumkiu4",
},
AccountBackend: "cs3",
Reva: config.Reva{
Reva: &config.Reva{
Address: "127.0.0.1:9142",
},
StorageUsersDriver: "ocis",
MachineAuthAPIKey: "change-me-please",
IdentityManagement: config.IdentityManagement{
Address: "https://localhost:9200",
},
@@ -77,6 +70,25 @@ func EnsureDefaults(cfg *config.Config) {
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.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
cfg.TokenManager = &config.TokenManager{
JWTSecret: cfg.Commons.TokenManager.JWTSecret,
}
} else if cfg.TokenManager == nil {
cfg.TokenManager = &config.TokenManager{}
}
if cfg.MachineAuthAPIKey == "" && cfg.Commons != nil && cfg.Commons.MachineAuthAPIKey != "" {
cfg.MachineAuthAPIKey = cfg.Commons.MachineAuthAPIKey
}
}
func Sanitize(cfg *config.Config) {
+15 -1
View File
@@ -5,12 +5,14 @@ import (
"github.com/owncloud/ocis/extensions/ocs/pkg/config"
"github.com/owncloud/ocis/extensions/ocs/pkg/config/defaults"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/shared"
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
)
// ParseConfig loads accounts configuration from known paths.
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
@@ -29,5 +31,17 @@ func ParseConfig(cfg *config.Config) error {
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
if cfg.TokenManager.JWTSecret == "" {
return shared.MissingJWTTokenError(cfg.Service.Name)
}
if cfg.MachineAuthAPIKey == "" {
return shared.MissingMachineAuthApiKeyError(cfg.Service.Name)
}
return nil
}
+2 -1
View File
@@ -723,7 +723,8 @@ func getService() svc.Service {
Root: "/",
Addr: "localhost:9110",
},
TokenManager: config.TokenManager{
Reva: &config.Reva{},
TokenManager: &config.TokenManager{
JWTSecret: jwtSecret,
},
Log: &config.Log{
+5 -1
View File
@@ -17,7 +17,11 @@ func Health(cfg *config.Config) *cli.Command {
Usage: "check health status",
Category: "info",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
+7 -3
View File
@@ -43,7 +43,11 @@ func Server(cfg *config.Config) *cli.Command {
Usage: fmt.Sprintf("start %s extension without runtime (unsupervised mode)", cfg.Service.Name),
Category: "server",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
@@ -212,7 +216,7 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config)
middleware.AccountResolver(
middleware.Logger(logger),
middleware.UserProvider(userProvider),
middleware.TokenManagerConfig(cfg.TokenManager),
middleware.TokenManagerConfig(*cfg.TokenManager),
middleware.UserOIDCClaim(cfg.UserOIDCClaim),
middleware.UserCS3Claim(cfg.UserCS3Claim),
middleware.AutoprovisionAccounts(cfg.AutoprovisionAccounts),
@@ -227,7 +231,7 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config)
// finally, trigger home creation when a user logs in
middleware.CreateHome(
middleware.Logger(logger),
middleware.TokenManagerConfig(cfg.TokenManager),
middleware.TokenManagerConfig(*cfg.TokenManager),
middleware.RevaGatewayClient(revaClient),
),
middleware.PublicShareAuth(
+2 -2
View File
@@ -18,11 +18,11 @@ type Config struct {
HTTP HTTP `yaml:"http"`
Reva Reva `yaml:"reva"`
Reva *Reva `yaml:"reva"`
Policies []Policy `yaml:"policies"`
OIDC OIDC `yaml:"oidc"`
TokenManager TokenManager `yaml:"token_manager"`
TokenManager *TokenManager `yaml:"token_manager"`
PolicySelector *PolicySelector `yaml:"policy_selector"`
PreSignedURL PreSignedURL `yaml:"pre_signed_url"`
AccountBackend string `yaml:"account_backend" env:"PROXY_ACCOUNT_BACKEND_TYPE"`
@@ -8,6 +8,13 @@ import (
"github.com/owncloud/ocis/ocis-pkg/config/defaults"
)
func FullDefaultConfig() *config.Config {
cfg := DefaultConfig()
EnsureDefaults(cfg)
Sanitize(cfg)
return cfg
}
func DefaultConfig() *config.Config {
return &config.Config{
Debug: config.Debug{
@@ -34,11 +41,8 @@ func DefaultConfig() *config.Config {
TTL: 10,
},
},
TokenManager: config.TokenManager{
JWTSecret: "Pive-Fumkiu4",
},
PolicySelector: nil,
Reva: config.Reva{
Reva: &config.Reva{
Address: "127.0.0.1:9142",
},
PreSignedURL: config.PreSignedURL{
@@ -48,7 +52,6 @@ func DefaultConfig() *config.Config {
AccountBackend: "cs3",
UserOIDCClaim: "email",
UserCS3Claim: "mail",
MachineAuthAPIKey: "change-me-please",
AutoprovisionAccounts: false,
EnableBasicAuth: false,
InsecureBackends: false,
@@ -190,6 +193,25 @@ func EnsureDefaults(cfg *config.Config) {
cfg.Tracing = &config.Tracing{}
}
if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
cfg.TokenManager = &config.TokenManager{
JWTSecret: cfg.Commons.TokenManager.JWTSecret,
}
} else if cfg.TokenManager == nil {
cfg.TokenManager = &config.TokenManager{}
}
if cfg.MachineAuthAPIKey == "" && cfg.Commons != nil && cfg.Commons.MachineAuthAPIKey != "" {
cfg.MachineAuthAPIKey = cfg.Commons.MachineAuthAPIKey
}
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{}
}
}
func Sanitize(cfg *config.Config) {
+14 -1
View File
@@ -6,11 +6,12 @@ import (
"github.com/owncloud/ocis/extensions/proxy/pkg/config"
"github.com/owncloud/ocis/extensions/proxy/pkg/config/defaults"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/shared"
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
)
// ParseConfig loads accounts configuration from known paths.
// ParseConfig loads configuration from known paths.
func ParseConfig(cfg *config.Config) error {
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
if err != nil {
@@ -28,5 +29,17 @@ func ParseConfig(cfg *config.Config) error {
defaults.Sanitize(cfg)
return Validate(cfg)
}
func Validate(cfg *config.Config) error {
if cfg.TokenManager.JWTSecret == "" {
return shared.MissingJWTTokenError(cfg.Service.Name)
}
if cfg.MachineAuthAPIKey == "" {
return shared.MissingMachineAuthApiKeyError(cfg.Service.Name)
}
return nil
}
+5 -1
View File
@@ -16,7 +16,11 @@ func Health(cfg *config.Config) *cli.Command {
Name: "health",
Usage: "Check health status",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
+5 -1
View File
@@ -24,7 +24,11 @@ func Server(cfg *config.Config) *cli.Command {
Usage: fmt.Sprintf("start %s extension without runtime (unsupervised mode)", cfg.Service.Name),
Category: "server",
Before: func(c *cli.Context) error {
return parser.ParseConfig(cfg)
err := parser.ParseConfig(cfg)
if err != nil {
fmt.Printf("%v", err)
}
return err
},
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)
+3 -3
View File
@@ -23,8 +23,8 @@ type Config struct {
DataPath string `yaml:"data_path" env:"SETTINGS_DATA_PATH"`
Metadata Metadata `yaml:"metadata_config"`
Asset Asset `yaml:"asset"`
TokenManager TokenManager `yaml:"token_manager"`
Asset Asset `yaml:"asset"`
TokenManager *TokenManager `yaml:"token_manager"`
Context context.Context `yaml:"-"`
}
@@ -40,6 +40,6 @@ type Metadata struct {
StorageAddress string `yaml:"storage_addr" env:"STORAGE_GRPC_ADDR"`
ServiceUserID string `yaml:"service_user_id" env:"METADATA_SERVICE_USER_UUID"`
ServiceUserIDP string `yaml:"service_user_idp" env:"OCIS_URL;METADATA_SERVICE_USER_IDP"`
ServiceUserIDP string `yaml:"service_user_idp" env:"METADATA_SERVICE_USER_IDP"`
MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY"`
}

Some files were not shown because too many files have changed in this diff Show More