diff --git a/services/web/pkg/apps/apps.go b/services/web/pkg/apps/apps.go index b00cc84f7..1c617b36c 100644 --- a/services/web/pkg/apps/apps.go +++ b/services/web/pkg/apps/apps.go @@ -16,8 +16,6 @@ import ( ) var ( - validate *validator.Validate - // ErrInvalidApp is the error when an app is invalid ErrInvalidApp = errors.New("invalid app") @@ -29,6 +27,8 @@ var ( // ErrEntrypointDoesNotExist is the error when the entrypoint does not exist or is not a file ErrEntrypointDoesNotExist = errors.New("entrypoint does not exist") + + validate = validator.New(validator.WithRequiredStructEnabled()) ) const ( @@ -36,14 +36,10 @@ const ( _manifest = "manifest.json" ) -func init() { - validate = validator.New(validator.WithRequiredStructEnabled()) -} - // Application contains the metadata of an application type Application struct { // ID is the unique identifier of the application - ID string + ID string `json:"-"` // Entrypoint is the entrypoint of the application within the bundle Entrypoint string `json:"entrypoint" validate:"required"` @@ -92,7 +88,7 @@ func List(logger log.Logger, data map[string]config.App, fSystems ...fs.FS) []Ap continue } - application, err := Build(fSystem, name, appData.Config) + application, err := build(fSystem, name, appData.Config) if err != nil { // if app creation fails, log the error and continue with the next app logger.Debug().Err(err).Str("path", entry.Name()).Msg("failed to load application") @@ -107,7 +103,7 @@ func List(logger log.Logger, data map[string]config.App, fSystems ...fs.FS) []Ap return maps.Values(registry) } -func Build(fSystem fs.FS, id string, conf map[string]any) (Application, error) { +func build(fSystem fs.FS, id string, conf map[string]any) (Application, error) { // skip non-directory listings, every app needs to be contained inside a directory entry, err := fs.Stat(fSystem, id) if err != nil || !entry.IsDir() { diff --git a/services/web/pkg/apps/export_test.go b/services/web/pkg/apps/export_test.go new file mode 100644 index 000000000..e3b34353b --- /dev/null +++ b/services/web/pkg/apps/export_test.go @@ -0,0 +1,3 @@ +package apps + +var Build = build diff --git a/services/web/pkg/assets/server.go b/services/web/pkg/assets/server.go index ab5c90fb8..ffd0bb645 100644 --- a/services/web/pkg/assets/server.go +++ b/services/web/pkg/assets/server.go @@ -16,6 +16,7 @@ type fileServer struct { fsys http.FileSystem } +// FileServer defines the http handler for the embedded files func FileServer(fsys fs.FS) http.Handler { return &fileServer{http.FS(fsys)} } diff --git a/services/web/pkg/assets/server_test.go b/services/web/pkg/assets/server_test.go index de6e42565..4239521a8 100644 --- a/services/web/pkg/assets/server_test.go +++ b/services/web/pkg/assets/server_test.go @@ -1,4 +1,4 @@ -package assets_test +package assets import ( "fmt" @@ -10,8 +10,6 @@ import ( "testing/fstest" "github.com/onsi/gomega" - - "github.com/owncloud/ocis/v2/services/web/pkg/assets" ) func TestFileServer(t *testing.T) { @@ -21,7 +19,7 @@ func TestFileServer(t *testing.T) { } { - s := assets.FileServer(fstest.MapFS{}) + s := FileServer(fstest.MapFS{}) w := httptest.NewRecorder() req := httptest.NewRequest("GET", "/foo", nil) //defer req.Body.Close() @@ -109,7 +107,7 @@ func TestFileServer(t *testing.T) { w := httptest.NewRecorder() req := httptest.NewRequest("GET", tt.url, nil) - assets.FileServer(tt.fs).ServeHTTP(w, req) + FileServer(tt.fs).ServeHTTP(w, req) res := w.Result() defer res.Body.Close() diff --git a/services/web/pkg/command/health.go b/services/web/pkg/command/health.go index db6a69240..aed82dd37 100644 --- a/services/web/pkg/command/health.go +++ b/services/web/pkg/command/health.go @@ -17,10 +17,10 @@ func Health(cfg *config.Config) *cli.Command { Name: "health", Usage: "check health status", Category: "info", - Before: func(c *cli.Context) error { + Before: func(_ *cli.Context) error { return configlog.ReturnError(parser.ParseConfig(cfg)) }, - Action: func(c *cli.Context) error { + Action: func(_ *cli.Context) error { logger := logging.Configure(cfg.Service.Name, cfg.Log) resp, err := http.Get( diff --git a/services/web/pkg/command/server.go b/services/web/pkg/command/server.go index 7f515fdf4..a4423d0fe 100644 --- a/services/web/pkg/command/server.go +++ b/services/web/pkg/command/server.go @@ -24,10 +24,10 @@ func Server(cfg *config.Config) *cli.Command { Name: "server", Usage: fmt.Sprintf("start the %s service without runtime (unsupervised mode)", cfg.Service.Name), Category: "server", - Before: func(c *cli.Context) error { + Before: func(_ *cli.Context) error { return configlog.ReturnFatal(parser.ParseConfig(cfg)) }, - Action: func(c *cli.Context) error { + Action: func(_ *cli.Context) error { logger := logging.Configure(cfg.Service.Name, cfg.Log) traceProvider, err := tracing.GetServiceTraceProvider(cfg.Tracing, cfg.Service.Name) if err != nil { @@ -55,7 +55,7 @@ func Server(cfg *config.Config) *cli.Command { } return context.WithCancel(cfg.Context) }() - metrics = metrics.New() + m = metrics.New() ) defer cancel() @@ -66,7 +66,7 @@ func Server(cfg *config.Config) *cli.Command { http.Context(ctx), http.Namespace(cfg.HTTP.Namespace), http.Config(cfg), - http.Metrics(metrics), + http.Metrics(m), http.TraceProvider(traceProvider), ) if err != nil { diff --git a/services/web/pkg/command/version.go b/services/web/pkg/command/version.go index 6b1111fca..75e93ab1e 100644 --- a/services/web/pkg/command/version.go +++ b/services/web/pkg/command/version.go @@ -18,7 +18,7 @@ func Version(cfg *config.Config) *cli.Command { Name: "version", Usage: "print the version of this binary and the running service instances", Category: "info", - Action: func(c *cli.Context) error { + Action: func(_ *cli.Context) error { fmt.Println("Version: " + version.GetString()) fmt.Printf("Compiled: %s\n", version.Compiled()) fmt.Println("") diff --git a/services/web/pkg/config/config.go b/services/web/pkg/config/config.go index bf8763670..1fdd34229 100644 --- a/services/web/pkg/config/config.go +++ b/services/web/pkg/config/config.go @@ -109,8 +109,8 @@ type ExternalAppConfig struct { // Web defines the available web configuration. type Web struct { - ThemeServer string `yaml:"theme_server" env:"OCIS_URL;WEB_UI_THEME_SERVER" desc:"Base URL to load themes from. Will be prepended to the theme path." introductionVersion:"pre5.0"` // used to build Theme in WebConfig - ThemePath string `yaml:"theme_path" env:"WEB_UI_THEME_PATH" desc:"Subpath/file to load the theme. Will be appended to the URL of the theme server." introductionVersion:"pre5.0"` // used to build Theme in WebConfig + ThemeServer string `yaml:"theme_server" env:"OCIS_URL;WEB_UI_THEME_SERVER" desc:"Base URL to load themes from. Will be prepended to the theme path." introductionVersion:"pre5.0"` // used to build Theme in WebConfig + ThemePath string `yaml:"theme_path" env:"WEB_UI_THEME_PATH" desc:"Path to the theme json file. Will be appended to the URL of the theme server." introductionVersion:"pre5.0"` // used to build Theme in WebConfig Config WebConfig `yaml:"config"` } diff --git a/services/web/pkg/config/options.go b/services/web/pkg/config/options.go index 9d011c9ed..999359619 100644 --- a/services/web/pkg/config/options.go +++ b/services/web/pkg/config/options.go @@ -7,7 +7,7 @@ type Options struct { DisablePreviews bool `json:"disablePreviews,omitempty" yaml:"disablePreviews" env:"OCIS_DISABLE_PREVIEWS;WEB_OPTION_DISABLE_PREVIEWS" desc:"Set this option to 'true' to disable previews in all the different web file listing views. This can speed up file listings in folders with many files. The only list view that is not affected by this setting is the trash bin, as it does not allow previewing at all." introductionVersion:"pre5.0"` PreviewFileMimeTypes []string `json:"previewFileMimeTypes,omitempty" yaml:"previewFileMimeTypes" env:"WEB_OPTION_PREVIEW_FILE_MIMETYPES" desc:"A list of mimeTypes to specify which ones will be previewed in the UI. For example, to only preview jpg and text files, set this option to 'image/jpeg,text/plain'. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"` AccountEditLink *AccountEditLink `json:"accountEditLink,omitempty" yaml:"accountEditLink"` - DisableFeedbackLink bool `json:"disableFeedbackLink,omitempty" yaml:"disableFeedbackLink" env:"WEB_OPTION_DISABLE_FEEDBACK_LINK" desc:"Set this option to 'true' to disable the feedback link in the topbar. Keeping it enabled by setting the value to 'false' or with the absence of the option, allows ownCloud to get feedback from your user base through a dedicated survey website." introductionVersion:"pre5.0"` + DisableFeedbackLink bool `json:"disableFeedbackLink,omitempty" yaml:"disableFeedbackLink" env:"WEB_OPTION_DISABLE_FEEDBACK_LINK" desc:"Set this option to 'true' to disable the feedback link in the top bar. Keeping it enabled by setting the value to 'false' or with the absence of the option, allows ownCloud to get feedback from your user base through a dedicated survey website." introductionVersion:"pre5.0"` FeedbackLink *FeedbackLink `json:"feedbackLink,omitempty" yaml:"feedbackLink"` SharingRecipientsPerPage int `json:"sharingRecipientsPerPage,omitempty" yaml:"sharingRecipientsPerPage" env:"WEB_OPTION_SHARING_RECIPIENTS_PER_PAGE" desc:"Sets the number of users shown as recipients in the dropdown menu when sharing resources." introductionVersion:"pre5.0"` Sidebar Sidebar `json:"sidebar" yaml:"sidebar"` diff --git a/services/web/pkg/config/parser/parse.go b/services/web/pkg/config/parser/parse.go index ee53a35e6..4789b6aaa 100644 --- a/services/web/pkg/config/parser/parse.go +++ b/services/web/pkg/config/parser/parse.go @@ -39,6 +39,7 @@ func ParseConfig(cfg *config.Config) error { return Validate(cfg) } +// Validate validates the configuration func Validate(cfg *config.Config) error { if cfg.TokenManager.JWTSecret == "" { return shared.MissingJWTTokenError(cfg.Service.Name) diff --git a/services/web/pkg/metrics/metrics.go b/services/web/pkg/metrics/metrics.go index 72a3eb202..d27bfd727 100644 --- a/services/web/pkg/metrics/metrics.go +++ b/services/web/pkg/metrics/metrics.go @@ -1,13 +1,5 @@ package metrics -var ( - // Namespace defines the namespace for the defines metrics. - Namespace = "ocis" - - // Subsystem defines the subsystem for the defines metrics. - Subsystem = "web" -) - // Metrics defines the available metrics of this service. type Metrics struct { // Counter *prometheus.CounterVec @@ -15,18 +7,7 @@ type Metrics struct { // New initializes the available metrics. func New() *Metrics { - m := &Metrics{ - // Counter: prometheus.NewCounterVec(prometheus.CounterOpts{ - // Namespace: Namespace, - // Subsystem: Subsystem, - // Name: "greet_total", - // Help: "How many greeting requests processed", - // }, []string{}), - } - - // prometheus.Register( - // m.Counter, - // ) + m := &Metrics{} return m } diff --git a/services/web/pkg/server/debug/server.go b/services/web/pkg/server/debug/server.go index 04d59e2b9..0ffe3259c 100644 --- a/services/web/pkg/server/debug/server.go +++ b/services/web/pkg/server/debug/server.go @@ -27,8 +27,8 @@ func Server(opts ...Option) (*http.Server, error) { } // health implements the health check. -func health(cfg *config.Config) func(http.ResponseWriter, *http.Request) { - return func(w http.ResponseWriter, r *http.Request) { +func health(_ *config.Config) func(http.ResponseWriter, *http.Request) { + return func(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "text/plain") w.WriteHeader(http.StatusOK) @@ -43,8 +43,8 @@ func health(cfg *config.Config) func(http.ResponseWriter, *http.Request) { } // ready implements the ready check. -func ready(cfg *config.Config) func(http.ResponseWriter, *http.Request) { - return func(w http.ResponseWriter, r *http.Request) { +func ready(_ *config.Config) func(http.ResponseWriter, *http.Request) { + return func(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "text/plain") w.WriteHeader(http.StatusOK) diff --git a/services/web/pkg/server/http/option.go b/services/web/pkg/server/http/option.go index 8eec2f047..72462b81a 100644 --- a/services/web/pkg/server/http/option.go +++ b/services/web/pkg/server/http/option.go @@ -63,13 +63,6 @@ func Metrics(val *metrics.Metrics) Option { } } -// Flags provides a function to set the flags option. -func Flags(val []cli.Flag) Option { - return func(o *Options) { - o.Flags = append(o.Flags, val...) - } -} - // Namespace provides a function to set the Namespace option. func Namespace(val string) Option { return func(o *Options) { diff --git a/services/web/pkg/service/v0/service.go b/services/web/pkg/service/v0/service.go index e8a8b9eb4..5b0ff3cd2 100644 --- a/services/web/pkg/service/v0/service.go +++ b/services/web/pkg/service/v0/service.go @@ -2,7 +2,6 @@ package svc import ( "encoding/json" - "fmt" "io/fs" "net/http" "net/url" @@ -182,7 +181,7 @@ func (p Web) Static(f fs.FS, root string, ttl int) http.HandlerFunc { return } - w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%s", strconv.Itoa(ttl))) + w.Header().Set("Cache-Control", "max-age="+strconv.Itoa(ttl)) w.Header().Set("Expires", expires) w.Header().Set("Last-Modified", lastModified) w.Header().Set("SameSite", "Strict") diff --git a/services/web/pkg/theme/service.go b/services/web/pkg/theme/service.go index b844df09a..766bf5a35 100644 --- a/services/web/pkg/theme/service.go +++ b/services/web/pkg/theme/service.go @@ -108,7 +108,7 @@ func (s Service) LogoUpload(w http.ResponseWriter, r *http.Request) { Permission: "Logo.Write", SubjectRef: &permissionsapi.SubjectReference{ Spec: &permissionsapi.SubjectReference_UserId{ - UserId: user.Id, + UserId: user.GetId(), }, }, }) @@ -116,7 +116,7 @@ func (s Service) LogoUpload(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) return } - if rsp.Status.Code != rpc.Code_CODE_OK { + if rsp.GetStatus().GetCode() != rpc.Code_CODE_OK { w.WriteHeader(http.StatusForbidden) return } @@ -170,7 +170,7 @@ func (s Service) LogoReset(w http.ResponseWriter, r *http.Request) { Permission: "Logo.Write", SubjectRef: &permissionsapi.SubjectReference{ Spec: &permissionsapi.SubjectReference_UserId{ - UserId: user.Id, + UserId: user.GetId(), }, }, }) @@ -178,7 +178,7 @@ func (s Service) LogoReset(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) return } - if rsp.Status.Code != rpc.Code_CODE_OK { + if rsp.GetStatus().GetCode() != rpc.Code_CODE_OK { w.WriteHeader(http.StatusForbidden) return }