From cb14ff39965475942af939fa8d3c1285a6e54e2e Mon Sep 17 00:00:00 2001 From: Gianmaria Del Monte Date: Wed, 27 Oct 2021 14:42:33 +0200 Subject: [PATCH] Refactored code --- pkg/storage/registry/static/static.go | 70 +++++-------------- pkg/useragent/useragent.go | 50 ++++++++++--- .../useragent_test.go} | 4 +- 3 files changed, 58 insertions(+), 66 deletions(-) rename pkg/{storage/registry/static/static_filter_test.go => useragent/useragent_test.go} (98%) diff --git a/pkg/storage/registry/static/static.go b/pkg/storage/registry/static/static.go index 2f311d82bf4..37997299b42 100644 --- a/pkg/storage/registry/static/static.go +++ b/pkg/storage/registry/static/static.go @@ -33,7 +33,6 @@ import ( "github.com/cs3org/reva/pkg/storage/registry/registry" "github.com/cs3org/reva/pkg/storage/utils/templates" "github.com/cs3org/reva/pkg/useragent" - ua "github.com/mileusna/useragent" "github.com/mitchellh/mapstructure" "github.com/pkg/errors" ) @@ -113,23 +112,7 @@ func getProviderAddr(ctx context.Context, r rule) string { func (b *reg) ListProviders(ctx context.Context) ([]*registrypb.ProviderInfo, error) { providers := []*registrypb.ProviderInfo{} - for k, v := range b.c.Rules { - - // check if the provider is allowed to be shown according to the - // user agent that made the request - // if the list of AllowedUserAgents is empty, this means that - // every agents that made the request could see the provider - - if len(v.AllowedUserAgents) != 0 { - ua, ok := ctxpkg.ContextGetUserAgent(ctx) - if !ok { - continue - } - if !userAgentIsAllowed(ua, v.AllowedUserAgents) { - continue // skip this provider - } - } - + for k, v := range rulesFilteredByUserAgent(ctx, b.c.Rules) { if addr := getProviderAddr(ctx, v); addr != "" { combs := generateRegexCombinations(k) for _, c := range combs { @@ -157,28 +140,22 @@ func (b *reg) GetHome(ctx context.Context) (*registrypb.ProviderInfo, error) { return nil, errors.New("static: home not found") } -func userAgentIsAllowed(ua *ua.UserAgent, userAgents []string) bool { - for _, userAgent := range userAgents { - switch userAgent { - case "web": - if useragent.IsWeb(ua) { - return true - } - case "mobile": - if useragent.IsMobile(ua) { - return true - } - case "desktop": - if useragent.IsDesktop(ua) { - return true - } - case "grpc": - if useragent.IsGRPC(ua) { - return true +func rulesFilteredByUserAgent(ctx context.Context, rules map[string]rule) map[string]rule { + filtered := make(map[string]rule) + for prefix, rule := range rules { + // check if the provider is allowed to be shown according to the + // user agent that made the request + // if the list of AllowedUserAgents is empty, this means that + // every agents that made the request could see the provider + + if len(rule.AllowedUserAgents) != 0 { + if ua, ok := ctxpkg.ContextGetUserAgent(ctx); !ok || !useragent.IsUserAgentAllowed(ua, rule.AllowedUserAgents) { + continue } } + filtered[prefix] = rule } - return false + return filtered } func (b *reg) FindProviders(ctx context.Context, ref *provider.Reference) ([]*registrypb.ProviderInfo, error) { @@ -189,7 +166,7 @@ func (b *reg) FindProviders(ctx context.Context, ref *provider.Reference) ([]*re // If the reference has a resource id set, use it to route if ref.ResourceId != nil { if ref.ResourceId.StorageId != "" { - for prefix, rule := range b.c.Rules { + for prefix, rule := range rulesFilteredByUserAgent(ctx, b.c.Rules) { addr := getProviderAddr(ctx, rule) r, err := regexp.Compile("^" + prefix + "$") if err != nil { @@ -215,22 +192,7 @@ func (b *reg) FindProviders(ctx context.Context, ref *provider.Reference) ([]*re // TODO this needs to be reevaluated once all clients query the storage registry for a list of storage providers fn := path.Clean(ref.GetPath()) if fn != "" { - for prefix, rule := range b.c.Rules { - - // check if the provider is allowed to be shown according to the - // user agent that made the request - // if the list of AllowedUserAgents is empty, this means that - // every agents that made the request could see the provider - - if len(rule.AllowedUserAgents) != 0 { - ua, ok := ctxpkg.ContextGetUserAgent(ctx) - if !ok { - continue - } - if !userAgentIsAllowed(ua, rule.AllowedUserAgents) { - continue // skip this provider - } - } + for prefix, rule := range rulesFilteredByUserAgent(ctx, b.c.Rules) { addr := getProviderAddr(ctx, rule) r, err := regexp.Compile("^" + prefix) diff --git a/pkg/useragent/useragent.go b/pkg/useragent/useragent.go index a0bbf0184ea..24eb3901956 100644 --- a/pkg/useragent/useragent.go +++ b/pkg/useragent/useragent.go @@ -24,25 +24,55 @@ import ( ua "github.com/mileusna/useragent" ) -// IsWeb returns true if the useragent is generated by the web -func IsWeb(ua *ua.UserAgent) bool { +// isWeb returns true if the useragent is generated by the web +func isWeb(ua *ua.UserAgent) bool { return ua.IsChrome() || ua.IsEdge() || ua.IsFirefox() || ua.IsSafari() || ua.IsInternetExplorer() || ua.IsOpera() || ua.IsOperaMini() } -// IsWeb returns true if the useragent is generated by the mobile -func IsMobile(ua *ua.UserAgent) bool { +// isMobile returns true if the useragent is generated by the mobile +func isMobile(ua *ua.UserAgent) bool { // workaround as the library does not recognise iOS string inside the user agent isIOS := ua.IsIOS() || strings.Contains(ua.String, "iOS") - return !IsWeb(ua) && (ua.IsAndroid() || isIOS) + return !isWeb(ua) && (ua.IsAndroid() || isIOS) } -// IsWeb returns true if the useragent is generated by a desktop application -func IsDesktop(ua *ua.UserAgent) bool { - return ua.Desktop && !IsWeb(ua) +// isDesktop returns true if the useragent is generated by a desktop application +func isDesktop(ua *ua.UserAgent) bool { + return ua.Desktop && !isWeb(ua) } -// IsWeb returns true if the useragent is generated by a grpc client -func IsGRPC(ua *ua.UserAgent) bool { +// isGRPC returns true if the useragent is generated by a grpc client +func isGRPC(ua *ua.UserAgent) bool { return strings.HasPrefix(ua.Name, "grpc") } + +// IsUserAgentAllowed returns true if the user agent category is one in the user agents list +func IsUserAgentAllowed(ua *ua.UserAgent, userAgents []string) bool { + isWeb := isWeb(ua) + isMobile := isMobile(ua) + isDesktop := isDesktop(ua) + isGRPC := isGRPC(ua) + + for _, userAgent := range userAgents { + switch userAgent { + case "web": + if isWeb { + return true + } + case "mobile": + if isMobile { + return true + } + case "desktop": + if isDesktop { + return true + } + case "grpc": + if isGRPC { + return true + } + } + } + return false +} diff --git a/pkg/storage/registry/static/static_filter_test.go b/pkg/useragent/useragent_test.go similarity index 98% rename from pkg/storage/registry/static/static_filter_test.go rename to pkg/useragent/useragent_test.go index 9b8de6712fb..c37ae97508a 100644 --- a/pkg/storage/registry/static/static_filter_test.go +++ b/pkg/useragent/useragent_test.go @@ -16,7 +16,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -package static +package useragent import ( "testing" @@ -111,7 +111,7 @@ func TestUserAgentIsAllowed(t *testing.T) { ua := ua.Parse(tt.userAgent) - res := userAgentIsAllowed(&ua, tt.userAgents) + res := IsUserAgentAllowed(&ua, tt.userAgents) if res != tt.expected { t.Fatalf("result does not match with expected. got=%+v expected=%+v", res, tt.expected)