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-04-13 11:54:32 +00:00
254 changed files with 6882 additions and 2968 deletions
+60 -57
View File
@@ -8,49 +8,52 @@ import (
// Config combines all available configuration parts.
type Config struct {
*shared.Commons `ocisConfig:"-" yaml:"-"`
*shared.Commons `yaml:"-"`
Service Service `ocisConfig:"-" yaml:"-"`
Service Service `yaml:"-"`
Tracing *Tracing `ocisConfig:"tracing"`
Log *Log `ocisConfig:"log"`
Debug Debug `ocisConfig:"debug"`
Tracing *Tracing `yaml:"tracing"`
Log *Log `yaml:"log"`
Debug Debug `yaml:"debug"`
HTTP HTTP `ocisConfig:"http"`
HTTP HTTP `yaml:"http"`
Reva Reva `ocisConfig:"reva"`
Reva Reva `yaml:"reva"`
Policies []Policy `ocisConfig:"policies"`
OIDC OIDC `ocisConfig:"oidc"`
TokenManager TokenManager `ocisConfig:"token_manager"`
PolicySelector *PolicySelector `ocisConfig:"policy_selector"`
PreSignedURL PreSignedURL `ocisConfig:"pre_signed_url"`
AccountBackend string `ocisConfig:"account_backend" env:"PROXY_ACCOUNT_BACKEND_TYPE"`
UserOIDCClaim string `ocisConfig:"user_oidc_claim" env:"PROXY_USER_OIDC_CLAIM"`
UserCS3Claim string `ocisConfig:"user_cs3_claim" env:"PROXY_USER_CS3_CLAIM"`
MachineAuthAPIKey string `ocisConfig:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;PROXY_MACHINE_AUTH_API_KEY"`
AutoprovisionAccounts bool `ocisConfig:"auto_provision_accounts" env:"PROXY_AUTOPROVISION_ACCOUNTS"`
EnableBasicAuth bool `ocisConfig:"enable_basic_auth" env:"PROXY_ENABLE_BASIC_AUTH"`
InsecureBackends bool `ocisConfig:"insecure_backends" env:"PROXY_INSECURE_BACKENDS"`
AuthMiddleware AuthMiddleware `ocisConfig:"auth_middleware"`
Policies []Policy `yaml:"policies"`
OIDC OIDC `yaml:"oidc"`
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"`
UserOIDCClaim string `yaml:"user_oidc_claim" env:"PROXY_USER_OIDC_CLAIM"`
UserCS3Claim string `yaml:"user_cs3_claim" env:"PROXY_USER_CS3_CLAIM"`
MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;PROXY_MACHINE_AUTH_API_KEY"`
AutoprovisionAccounts bool `yaml:"auto_provision_accounts" env:"PROXY_AUTOPROVISION_ACCOUNTS"`
EnableBasicAuth bool `yaml:"enable_basic_auth" env:"PROXY_ENABLE_BASIC_AUTH"`
InsecureBackends bool `yaml:"insecure_backends" env:"PROXY_INSECURE_BACKENDS"`
AuthMiddleware AuthMiddleware `yaml:"auth_middleware"`
Context context.Context `ocisConfig:"-" yaml:"-"`
Context context.Context `yaml:"-"`
}
// Policy enables us to use multiple directors.
type Policy struct {
Name string `ocisConfig:"name"`
Routes []Route `ocisConfig:"routes"`
Name string `yaml:"name"`
Routes []Route `yaml:"routes"`
}
// Route define forwarding routes
// Route defines forwarding routes
type Route struct {
Type RouteType `ocisConfig:"type"`
Type RouteType `yaml:"type"`
// Method optionally limits the route to this HTTP method
Method string `ocisConfig:"method"`
Endpoint string `ocisConfig:"endpoint"`
Backend string `ocisConfig:"backend"`
ApacheVHost bool `ocisConfig:"apache-vhost"`
Method string `yaml:"method"`
Endpoint string `yaml:"endpoint"`
// Backend is a static URL to forward the request to
Backend string `yaml:"backend"`
// Service name to look up in the registry
Service string `yaml:"service"`
ApacheVHost bool `yaml:"apache-vhost"`
}
// RouteType defines the type of a route
@@ -74,72 +77,72 @@ var (
// AuthMiddleware configures the proxy http auth middleware.
type AuthMiddleware struct {
CredentialsByUserAgent map[string]string `ocisConfig:"credentials_by_user_agent"`
CredentialsByUserAgent map[string]string `yaml:"credentials_by_user_agent"`
}
// OIDC is the config for the OpenID-Connect middleware. If set the proxy will try to authenticate every request
// with the configured oidc-provider
type OIDC struct {
Issuer string `ocisConfig:"issuer" env:"OCIS_URL;PROXY_OIDC_ISSUER"`
Insecure bool `ocisConfig:"insecure" env:"OCIS_INSECURE;PROXY_OIDC_INSECURE"`
UserinfoCache UserinfoCache `ocisConfig:"user_info_cache"`
Issuer string `yaml:"issuer" env:"OCIS_URL;PROXY_OIDC_ISSUER"`
Insecure bool `yaml:"insecure" env:"OCIS_INSECURE;PROXY_OIDC_INSECURE"`
UserinfoCache UserinfoCache `yaml:"user_info_cache"`
}
// UserinfoCache is a TTL cache configuration.
type UserinfoCache struct {
Size int `ocisConfig:"size" env:"PROXY_OIDC_USERINFO_CACHE_SIZE"`
TTL int `ocisConfig:"ttl" env:"PROXY_OIDC_USERINFO_CACHE_TTL"`
Size int `yaml:"size" env:"PROXY_OIDC_USERINFO_CACHE_SIZE"`
TTL int `yaml:"ttl" env:"PROXY_OIDC_USERINFO_CACHE_TTL"`
}
// PolicySelector is the toplevel-configuration for different selectors
type PolicySelector struct {
Static *StaticSelectorConf `ocisConfig:"static"`
Migration *MigrationSelectorConf `ocisConfig:"migration"`
Claims *ClaimsSelectorConf `ocisConfig:"claims"`
Regex *RegexSelectorConf `ocisConfig:"regex"`
Static *StaticSelectorConf `yaml:"static"`
Migration *MigrationSelectorConf `yaml:"migration"`
Claims *ClaimsSelectorConf `yaml:"claims"`
Regex *RegexSelectorConf `yaml:"regex"`
}
// StaticSelectorConf is the config for the static-policy-selector
type StaticSelectorConf struct {
Policy string `ocisConfig:"policy"`
Policy string `yaml:"policy"`
}
// TokenManager is the config for using the reva token manager
type TokenManager struct {
JWTSecret string `ocisConfig:"jwt_secret" env:"OCIS_JWT_SECRET;PROXY_JWT_SECRET"`
JWTSecret string `yaml:"jwt_secret" env:"OCIS_JWT_SECRET;PROXY_JWT_SECRET"`
}
// PreSignedURL is the config for the presigned url middleware
type PreSignedURL struct {
AllowedHTTPMethods []string `ocisConfig:"allowed_http_methods"`
Enabled bool `ocisConfig:"enabled" env:"PROXY_ENABLE_PRESIGNEDURLS"`
AllowedHTTPMethods []string `yaml:"allowed_http_methods"`
Enabled bool `yaml:"enabled" env:"PROXY_ENABLE_PRESIGNEDURLS"`
}
// MigrationSelectorConf is the config for the migration-selector
type MigrationSelectorConf struct {
AccFoundPolicy string `ocisConfig:"acc_found_policy"`
AccNotFoundPolicy string `ocisConfig:"acc_not_found_policy"`
UnauthenticatedPolicy string `ocisConfig:"unauthenticated_policy"`
AccFoundPolicy string `yaml:"acc_found_policy"`
AccNotFoundPolicy string `yaml:"acc_not_found_policy"`
UnauthenticatedPolicy string `yaml:"unauthenticated_policy"`
}
// ClaimsSelectorConf is the config for the claims-selector
type ClaimsSelectorConf struct {
DefaultPolicy string `ocisConfig:"default_policy"`
UnauthenticatedPolicy string `ocisConfig:"unauthenticated_policy"`
SelectorCookieName string `ocisConfig:"selector_cookie_name"`
DefaultPolicy string `yaml:"default_policy"`
UnauthenticatedPolicy string `yaml:"unauthenticated_policy"`
SelectorCookieName string `yaml:"selector_cookie_name"`
}
// RegexSelectorConf is the config for the regex-selector
type RegexSelectorConf struct {
DefaultPolicy string `ocisConfig:"default_policy"`
MatchesPolicies []RegexRuleConf `ocisConfig:"matches_policies"`
UnauthenticatedPolicy string `ocisConfig:"unauthenticated_policy"`
SelectorCookieName string `ocisConfig:"selector_cookie_name"`
DefaultPolicy string `yaml:"default_policy"`
MatchesPolicies []RegexRuleConf `yaml:"matches_policies"`
UnauthenticatedPolicy string `yaml:"unauthenticated_policy"`
SelectorCookieName string `yaml:"selector_cookie_name"`
}
type RegexRuleConf struct {
Priority int `ocisConfig:"priority"`
Property string `ocisConfig:"property"`
Match string `ocisConfig:"match"`
Policy string `ocisConfig:"policy"`
Priority int `yaml:"priority"`
Property string `yaml:"property"`
Match string `yaml:"match"`
Policy string `yaml:"policy"`
}
+4 -4
View File
@@ -2,8 +2,8 @@ package config
// Debug defines the available debug configuration.
type Debug struct {
Addr string `ocisConfig:"addr" env:"PROXY_DEBUG_ADDR"`
Token string `ocisConfig:"token" env:"PROXY_DEBUG_TOKEN"`
Pprof bool `ocisConfig:"pprof" env:"PROXY_DEBUG_PPROF"`
Zpages bool `ocisConfig:"zpages" env:"PROXY_DEBUG_ZPAGES"`
Addr string `yaml:"addr" env:"PROXY_DEBUG_ADDR"`
Token string `yaml:"token" env:"PROXY_DEBUG_TOKEN"`
Pprof bool `yaml:"pprof" env:"PROXY_DEBUG_PPROF"`
Zpages bool `yaml:"zpages" env:"PROXY_DEBUG_ZPAGES"`
}
+18 -68
View File
@@ -52,8 +52,6 @@ func DefaultConfig() *config.Config {
AutoprovisionAccounts: false,
EnableBasicAuth: false,
InsecureBackends: false,
// TODO: enable
//Policies: defaultPolicies(),
}
}
@@ -107,30 +105,34 @@ func DefaultPolicies() []config.Policy {
},
{
Endpoint: "/remote.php/",
Backend: "http://localhost:9140",
Service: "ocdav",
},
{
Endpoint: "/dav/",
Backend: "http://localhost:9140",
Service: "ocdav",
},
{
Endpoint: "/webdav/",
Backend: "http://localhost:9140",
Service: "ocdav",
},
{
Endpoint: "/status.php",
Backend: "http://localhost:9140",
Service: "ocdav",
},
{
Endpoint: "/index.php/",
Backend: "http://localhost:9140",
Service: "ocdav",
},
{
Endpoint: "/apps/",
Service: "ocdav",
},
{
Endpoint: "/data",
Backend: "http://localhost:9140",
},
{
Endpoint: "/app/",
Endpoint: "/app/", // /app or /apps? ocdav only handles /apps
Backend: "http://localhost:9140",
},
{
@@ -161,66 +163,6 @@ func DefaultPolicies() []config.Policy {
},
},
},
{
Name: "oc10",
Routes: []config.Route{
{
Endpoint: "/",
Backend: "http://localhost:9100",
},
{
Endpoint: "/.well-known/",
Backend: "http://localhost:9130",
},
{
Endpoint: "/konnect/",
Backend: "http://localhost:9130",
},
{
Endpoint: "/signin/",
Backend: "http://localhost:9130",
},
{
Endpoint: "/archiver",
Backend: "http://localhost:9140",
},
{
Endpoint: "/ocs/",
Backend: "https://demo.owncloud.com",
ApacheVHost: true,
},
{
Endpoint: "/remote.php/",
Backend: "https://demo.owncloud.com",
ApacheVHost: true,
},
{
Endpoint: "/dav/",
Backend: "https://demo.owncloud.com",
ApacheVHost: true,
},
{
Endpoint: "/webdav/",
Backend: "https://demo.owncloud.com",
ApacheVHost: true,
},
{
Endpoint: "/status.php",
Backend: "https://demo.owncloud.com",
ApacheVHost: true,
},
{
Endpoint: "/index.php/",
Backend: "https://demo.owncloud.com",
ApacheVHost: true,
},
{
Endpoint: "/data",
Backend: "https://demo.owncloud.com",
ApacheVHost: true,
},
},
},
}
}
@@ -256,6 +198,14 @@ func Sanitize(cfg *config.Config) {
cfg.Policies = DefaultPolicies()
}
if cfg.PolicySelector == nil {
cfg.PolicySelector = &config.PolicySelector{
Static: &config.StaticSelectorConf{
Policy: "ocis",
},
}
}
if cfg.HTTP.Root != "/" {
cfg.HTTP.Root = strings.TrimSuffix(cfg.HTTP.Root, "/")
}
+6 -6
View File
@@ -2,10 +2,10 @@ package config
// HTTP defines the available http configuration.
type HTTP struct {
Addr string `ocisConfig:"addr" env:"PROXY_HTTP_ADDR"`
Root string `ocisConfig:"root" env:"PROXY_HTTP_ROOT"`
Namespace string `ocisConfig:"-" yaml:"-"`
TLSCert string `ocisConfig:"tls_cert" env:"PROXY_TRANSPORT_TLS_CERT"`
TLSKey string `ocisConfig:"tls_key" env:"PROXY_TRANSPORT_TLS_KEY"`
TLS bool `ocisConfig:"tls" env:"PROXY_TLS"`
Addr string `yaml:"addr" env:"PROXY_HTTP_ADDR"`
Root string `yaml:"root" env:"PROXY_HTTP_ROOT"`
Namespace string `yaml:"-"`
TLSCert string `yaml:"tls_cert" env:"PROXY_TRANSPORT_TLS_CERT"`
TLSKey string `yaml:"tls_key" env:"PROXY_TRANSPORT_TLS_KEY"`
TLS bool `yaml:"tls" env:"PROXY_TLS"`
}
+1 -1
View File
@@ -2,5 +2,5 @@ package config
// Reva defines all available REVA configuration.
type Reva struct {
Address string `ocisConfig:"address" env:"REVA_GATEWAY"`
Address string `yaml:"address" env:"REVA_GATEWAY"`
}
+1 -1
View File
@@ -2,5 +2,5 @@ package config
// Service defines the available service configuration.
type Service struct {
Name string `ocisConfig:"-" yaml:"-"`
Name string `yaml:"-"`
}
+4 -4
View File
@@ -2,8 +2,8 @@ package config
// Tracing defines the available tracing configuration.
type Tracing struct {
Enabled bool `ocisConfig:"enabled" env:"OCIS_TRACING_ENABLED;PROXY_TRACING_ENABLED"`
Type string `ocisConfig:"type" env:"OCIS_TRACING_TYPE;PROXY_TRACING_TYPE"`
Endpoint string `ocisConfig:"endpoint" env:"OCIS_TRACING_ENDPOINT;PROXY_TRACING_ENDPOINT"`
Collector string `ocisConfig:"collector" env:"OCIS_TRACING_COLLECTOR;PROXY_TRACING_COLLECTOR"`
Enabled bool `yaml:"enabled" env:"OCIS_TRACING_ENABLED;PROXY_TRACING_ENABLED"`
Type string `yaml:"type" env:"OCIS_TRACING_TYPE;PROXY_TRACING_TYPE"`
Endpoint string `yaml:"endpoint" env:"OCIS_TRACING_ENDPOINT;PROXY_TRACING_ENDPOINT"`
Collector string `yaml:"collector" env:"OCIS_TRACING_COLLECTOR;PROXY_TRACING_COLLECTOR"`
}
+1
View File
@@ -116,6 +116,7 @@ func (m basicAuth) isPublicLink(req *http.Request) bool {
publicPaths := []string{
"/remote.php/dav/public-files/",
"/remote.php/ocs/apps/files_sharing/api/v1/tokeninfo/unprotected",
"/ocs/v1.php/cloud/capabilities",
}
isPublic := false
+31 -2
View File
@@ -12,10 +12,12 @@ import (
"time"
chimiddleware "github.com/go-chi/chi/v5/middleware"
"go-micro.dev/v4/selector"
"go.opentelemetry.io/otel/attribute"
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/owncloud/ocis/ocis-pkg/registry"
pkgtrace "github.com/owncloud/ocis/ocis-pkg/tracing"
"github.com/owncloud/ocis/proxy/pkg/config"
"github.com/owncloud/ocis/proxy/pkg/proxy/policy"
@@ -87,6 +89,10 @@ func NewMultiHostReverseProxy(opts ...Option) *MultiHostReverseProxy {
for _, pol := range options.Config.Policies {
for _, route := range pol.Routes {
rp.logger.Debug().Str("fwd: ", route.Endpoint)
if route.Backend == "" && route.Service == "" {
rp.logger.Fatal().Interface("route", route).Msg("neither Backend nor Service is set")
}
uri, err2 := url.Parse(route.Backend)
if err2 != nil {
rp.logger.
@@ -96,6 +102,7 @@ func NewMultiHostReverseProxy(opts ...Option) *MultiHostReverseProxy {
Msg("malformed url")
}
// here the backend is used as a uri
rp.AddHost(pol.Name, uri, route)
}
}
@@ -200,9 +207,31 @@ func (p *MultiHostReverseProxy) AddHost(policy string, target *url.URL, rt confi
if p.Directors[policy][routeType][rt.Method] == nil {
p.Directors[policy][routeType][rt.Method] = make(map[string]func(req *http.Request))
}
reg := registry.GetRegistry()
sel := selector.NewSelector(selector.Registry(reg))
p.Directors[policy][routeType][rt.Method][rt.Endpoint] = func(req *http.Request) {
req.URL.Scheme = target.Scheme
req.URL.Host = target.Host
if rt.Service != "" {
// select next node
next, err := sel.Select(rt.Service)
if err != nil {
fmt.Println(fmt.Errorf("could not select %s service from the registry: %v", rt.Service, err))
return // TODO error? fallback to target.Host & Scheme?
}
node, err := next()
if err != nil {
fmt.Println(fmt.Errorf("could not select next node for service %s: %v", rt.Service, err))
return // TODO error? fallback to target.Host & Scheme?
}
req.URL.Host = node.Address
req.URL.Scheme = node.Metadata["protocol"] // TODO check property exists?
} else {
req.URL.Host = target.Host
req.URL.Scheme = target.Scheme
}
// Apache deployments host addresses need to match on req.Host and req.URL.Host
// see https://stackoverflow.com/questions/34745654/golang-reverseproxy-with-apache2-sni-hostname-error
if rt.ApacheVHost {