mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-05-02 16:59:56 -05:00
chore: code cleanup services/web (#9034)
* chore: code cleanup services/web * fix: export private member to keep the test external * chore: backport changes --------- Co-authored-by: Florian Schade <f.schade@icloud.com>
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
package apps
|
||||
|
||||
var Build = build
|
||||
@@ -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)}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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("")
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
|
||||
@@ -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"`
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user