diff --git a/http/handler/api/cluster.go b/http/handler/api/cluster.go index 34444ba2..cc8fb139 100644 --- a/http/handler/api/cluster.go +++ b/http/handler/api/cluster.go @@ -196,7 +196,7 @@ func (h *ClusterHandler) GetAllNodesProcess(c echo.Context) error { domain := util.DefaultQuery(c, "domain", "") if !h.iam.Enforce(ctxuser, domain, "process:"+id, "read") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "") } procs := h.proxy.ListProcesses(proxy.ProcessListOptions{ @@ -254,7 +254,7 @@ func (h *ClusterHandler) GetNode(c echo.Context) error { peer, err := h.proxy.GetNode(id) if err != nil { - return api.Err(http.StatusNotFound, "Node not found", "%s", err) + return api.Err(http.StatusNotFound, "", "Node not found: %s", err.Error()) } about := peer.About() @@ -290,7 +290,7 @@ func (h *ClusterHandler) GetNodeVersion(c echo.Context) error { peer, err := h.proxy.GetNode(id) if err != nil { - return api.Err(http.StatusNotFound, "Node not found", "%s", err) + return api.Err(http.StatusNotFound, "", "Node not found: %s", err.Error()) } v := peer.Version() @@ -323,7 +323,7 @@ func (h *ClusterHandler) GetNodeFiles(c echo.Context) error { peer, err := h.proxy.GetNode(id) if err != nil { - return api.Err(http.StatusNotFound, "Node not found", "%s", err) + return api.Err(http.StatusNotFound, "", "Node not found: %s", err.Error()) } files := api.ClusterNodeFiles{ @@ -386,7 +386,7 @@ func (h *ClusterHandler) ListNodeProcesses(c echo.Context) error { peer, err := h.proxy.GetNode(id) if err != nil { - return api.Err(http.StatusNotFound, "Node not found", "%s", err) + return api.Err(http.StatusNotFound, "", "Node not found: %s", err.Error()) } procs, err := peer.ProcessList(proxy.ProcessListOptions{ @@ -400,7 +400,7 @@ func (h *ClusterHandler) ListNodeProcesses(c echo.Context) error { DomainPattern: domainpattern, }) if err != nil { - return api.Err(http.StatusInternalServerError, "", "Node not available: %s", err) + return api.Err(http.StatusInternalServerError, "", "Node not available: %s", err.Error()) } processes := []clientapi.Process{} @@ -485,31 +485,31 @@ func (h *ClusterHandler) AddProcess(c echo.Context) error { } if err := util.ShouldBindJSON(c, &process); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } if !h.iam.Enforce(ctxuser, process.Domain, "process:"+process.ID, "write") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "", "API user %s is not allowed to write this process", ctxuser) } if !superuser { if !h.iam.Enforce(process.Owner, process.Domain, "process:"+process.ID, "write") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "", "user %s is not allowed to write this process", process.Owner) } } if process.Type != "ffmpeg" { - return api.Err(http.StatusBadRequest, "Unsupported process type", "Supported process types are: ffmpeg") + return api.Err(http.StatusBadRequest, "", "unsupported process type: supported process types are: ffmpeg") } if len(process.Input) == 0 || len(process.Output) == 0 { - return api.Err(http.StatusBadRequest, "At least one input and one output need to be defined") + return api.Err(http.StatusBadRequest, "", "At least one input and one output need to be defined") } config, metadata := process.Marshal() if err := h.cluster.AddProcess("", config); err != nil { - return api.Err(http.StatusBadRequest, "Invalid process config", "%s", err.Error()) + return api.Err(http.StatusBadRequest, "", "invalid process config: %s", err.Error()) } for key, value := range metadata { @@ -549,30 +549,30 @@ func (h *ClusterHandler) UpdateProcess(c echo.Context) error { } if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "", "API user %s is not allowed to write the process in domain: %s", ctxuser, domain) } pid := process.ProcessID() current, err := h.cluster.GetProcess(pid) if err != nil { - return api.Err(http.StatusNotFound, "Process not found", "%s", id) + return api.Err(http.StatusNotFound, "", "Process not found: %s", id) } // Prefill the config with the current values process.Unmarshal(current.Config) if err := util.ShouldBindJSON(c, &process); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } if !h.iam.Enforce(ctxuser, process.Domain, "process:"+process.ID, "write") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "", "API user %s is not allowed to write this process", ctxuser) } if !superuser { if !h.iam.Enforce(process.Owner, process.Domain, "process:"+process.ID, "write") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "", "user %s is not allowed to write this process", process.Owner) } } @@ -580,10 +580,10 @@ func (h *ClusterHandler) UpdateProcess(c echo.Context) error { if err := h.cluster.UpdateProcess("", pid, config); err != nil { if err == restream.ErrUnknownProcess { - return api.Err(http.StatusNotFound, "Process not found", "%s", id) + return api.Err(http.StatusNotFound, "", "Process not found: %s", id) } - return api.Err(http.StatusBadRequest, "Process can't be updated", "%s", err) + return api.Err(http.StatusBadRequest, "", "Process can't be updated: %s", err.Error()) } pid = process.ProcessID() @@ -617,13 +617,13 @@ func (h *ClusterHandler) SetProcessCommand(c echo.Context) error { domain := util.DefaultQuery(c, "domain", "") if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "", "API user %s is not allowed to write the process in domain: %s", ctxuser, domain) } var command api.Command if err := util.ShouldBindJSON(c, &command); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } pid := app.ProcessID{ @@ -641,7 +641,7 @@ func (h *ClusterHandler) SetProcessCommand(c echo.Context) error { } if err := h.cluster.SetProcessCommand("", pid, command.Command); err != nil { - return api.Err(http.StatusNotFound, "", "command failed: %s", err) + return api.Err(http.StatusNotFound, "", "command failed: %s", err.Error()) } return c.JSON(http.StatusOK, "OK") @@ -670,7 +670,7 @@ func (h *ClusterHandler) SetProcessMetadata(c echo.Context) error { domain := util.DefaultQuery(c, "domain", "") if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") { - return api.Err(http.StatusForbidden, "") + return api.Err(http.StatusForbidden, "", "API user %s is not allowed to write the process in domain: %s", ctxuser, domain) } if len(key) == 0 { @@ -713,7 +713,7 @@ func (h *ClusterHandler) DeleteProcess(c echo.Context) error { id := util.PathParam(c, "id") if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") { - return api.Err(http.StatusForbidden, "", "Not allowed to delete this process") + return api.Err(http.StatusForbidden, "", "API user %s is not allowed to write the process in domain: %s", ctxuser, domain) } pid := app.ProcessID{ @@ -722,7 +722,7 @@ func (h *ClusterHandler) DeleteProcess(c echo.Context) error { } if err := h.cluster.RemoveProcess("", pid); err != nil { - return api.Err(http.StatusBadRequest, "", "%s", err) + return api.Err(http.StatusBadRequest, "", "%s", err.Error()) } return c.JSON(http.StatusOK, "OK") @@ -749,31 +749,31 @@ func (h *ClusterHandler) AddIdentity(c echo.Context) error { user := api.IAMUser{} if err := util.ShouldBindJSON(c, &user); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } iamuser, iampolicies := user.Unmarshal() if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "write") { - return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to create user '%s'", iamuser.Name) + return api.Err(http.StatusForbidden, "", "Not allowed to create user '%s'", iamuser.Name) } for _, p := range iampolicies { if !h.iam.Enforce(ctxuser, p.Domain, "iam:"+iamuser.Name, "write") { - return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to write policy: %v", p) + return api.Err(http.StatusForbidden, "", "Not allowed to write policy: %v", p) } } if !superuser && iamuser.Superuser { - return api.Err(http.StatusForbidden, "Forbidden", "Only superusers can add superusers") + return api.Err(http.StatusForbidden, "", "Only superusers can add superusers") } if err := h.cluster.AddIdentity("", iamuser); err != nil { - return api.Err(http.StatusBadRequest, "Invalid identity", "%s", err.Error()) + return api.Err(http.StatusBadRequest, "", "invalid identity: %s", err.Error()) } if err := h.cluster.SetPolicies("", iamuser.Name, iampolicies); err != nil { - return api.Err(http.StatusBadRequest, "Invalid policies", "%s", err.Error()) + return api.Err(http.StatusBadRequest, "", "Invalid policies: %s", err.Error()) } return c.JSON(http.StatusOK, user) @@ -803,7 +803,7 @@ func (h *ClusterHandler) UpdateIdentity(c echo.Context) error { name := util.PathParam(c, "name") if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") { - return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to modify this user") + return api.Err(http.StatusForbidden, "", "Not allowed to modify this user") } var iamuser identity.User @@ -812,7 +812,7 @@ func (h *ClusterHandler) UpdateIdentity(c echo.Context) error { if name != "$anon" { iamuser, err = h.iam.GetIdentity(name) if err != nil { - return api.Err(http.StatusNotFound, "Not found", "%s", err) + return api.Err(http.StatusNotFound, "", "Not found: %s", err.Error()) } } else { iamuser = identity.User{ @@ -826,35 +826,35 @@ func (h *ClusterHandler) UpdateIdentity(c echo.Context) error { user.Marshal(iamuser, iampolicies) if err := util.ShouldBindJSON(c, &user); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } iamuser, iampolicies = user.Unmarshal() if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "write") { - return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to create user '%s'", iamuser.Name) + return api.Err(http.StatusForbidden, "", "Not allowed to create user '%s'", iamuser.Name) } for _, p := range iampolicies { if !h.iam.Enforce(ctxuser, p.Domain, "iam:"+iamuser.Name, "write") { - return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to write policy: %v", p) + return api.Err(http.StatusForbidden, "", "Not allowed to write policy: %v", p) } } if !superuser && iamuser.Superuser { - return api.Err(http.StatusForbidden, "Forbidden", "Only superusers can modify superusers") + return api.Err(http.StatusForbidden, "", "Only superusers can modify superusers") } if name != "$anon" { err = h.cluster.UpdateIdentity("", name, iamuser) if err != nil { - return api.Err(http.StatusBadRequest, "Bad request", "%s", err) + return api.Err(http.StatusBadRequest, "", "%s", err.Error()) } } err = h.cluster.SetPolicies("", name, iampolicies) if err != nil { - return api.Err(http.StatusInternalServerError, "", "set policies: %w", err) + return api.Err(http.StatusInternalServerError, "", "set policies: %s", err.Error()) } return c.JSON(http.StatusOK, user) @@ -884,7 +884,7 @@ func (h *ClusterHandler) UpdateIdentityPolicies(c echo.Context) error { name := util.PathParam(c, "name") if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") { - return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to modify this user") + return api.Err(http.StatusForbidden, "", "Not allowed to modify this user") } var iamuser identity.User @@ -893,7 +893,7 @@ func (h *ClusterHandler) UpdateIdentityPolicies(c echo.Context) error { if name != "$anon" { iamuser, err = h.iam.GetIdentity(name) if err != nil { - return api.Err(http.StatusNotFound, "Not found", "%s", err) + return api.Err(http.StatusNotFound, "", "%s", err.Error()) } } else { iamuser = identity.User{ @@ -904,13 +904,13 @@ func (h *ClusterHandler) UpdateIdentityPolicies(c echo.Context) error { policies := []api.IAMPolicy{} if err := util.ShouldBindJSONValidation(c, &policies, false); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } for _, p := range policies { err := c.Validate(p) if err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } } @@ -918,7 +918,7 @@ func (h *ClusterHandler) UpdateIdentityPolicies(c echo.Context) error { for _, p := range policies { if !h.iam.Enforce(ctxuser, p.Domain, "iam:"+iamuser.Name, "write") { - return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to write policy: %v", p) + return api.Err(http.StatusForbidden, "", "Not allowed to write policy: %v", p) } accessPolicies = append(accessPolicies, access.Policy{ @@ -930,7 +930,7 @@ func (h *ClusterHandler) UpdateIdentityPolicies(c echo.Context) error { } if !superuser && iamuser.Superuser { - return api.Err(http.StatusForbidden, "Forbidden", "Only superusers can modify superusers") + return api.Err(http.StatusForbidden, "", "Only superusers can modify superusers") } err = h.cluster.SetPolicies("", name, accessPolicies) @@ -995,7 +995,7 @@ func (h *ClusterHandler) ListStoreIdentity(c echo.Context) error { name := util.PathParam(c, "name") if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "read") { - return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to access this user") + return api.Err(http.StatusForbidden, "", "Not allowed to access this user") } var updatedAt time.Time @@ -1005,7 +1005,7 @@ func (h *ClusterHandler) ListStoreIdentity(c echo.Context) error { if name != "$anon" { updatedAt, iamuser, err = h.cluster.ListIdentity(name) if err != nil { - return api.Err(http.StatusNotFound, "", "%s", err) + return api.Err(http.StatusNotFound, "", "%s", err.Error()) } if ctxuser != iamuser.Name { @@ -1047,12 +1047,12 @@ func (h *ClusterHandler) ListStoreIdentity(c echo.Context) error { func (h *ClusterHandler) ReloadIAM(c echo.Context) error { err := h.iam.ReloadIndentities() if err != nil { - return api.Err(http.StatusInternalServerError, "", "reload identities: %w", err) + return api.Err(http.StatusInternalServerError, "", "reload identities: %w", err.Error()) } err = h.iam.ReloadPolicies() if err != nil { - return api.Err(http.StatusInternalServerError, "", "reload policies: %w", err) + return api.Err(http.StatusInternalServerError, "", "reload policies: %w", err.Error()) } return c.JSON(http.StatusOK, "OK") @@ -1128,7 +1128,7 @@ func (h *ClusterHandler) ListIdentity(c echo.Context) error { if name != "$anon" { iamuser, err = h.iam.GetIdentity(name) if err != nil { - return api.Err(http.StatusNotFound, "", "%s", err) + return api.Err(http.StatusNotFound, "", "%s", err.Error()) } if ctxuser != iamuser.Name { @@ -1225,20 +1225,20 @@ func (h *ClusterHandler) RemoveIdentity(c echo.Context) error { name := util.PathParam(c, "name") if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") { - return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to delete this user") + return api.Err(http.StatusForbidden, "", "Not allowed to delete this user") } iamuser, err := h.iam.GetIdentity(name) if err != nil { - return api.Err(http.StatusNotFound, "Not found", "%s", err) + return api.Err(http.StatusNotFound, "", "%s", err.Error()) } if !superuser && iamuser.Superuser { - return api.Err(http.StatusForbidden, "Forbidden", "Only superusers can remove superusers") + return api.Err(http.StatusForbidden, "", "Only superusers can remove superusers") } if err := h.cluster.RemoveIdentity("", name); err != nil { - return api.Err(http.StatusBadRequest, "Invalid identity", "%s", err.Error()) + return api.Err(http.StatusBadRequest, "", "invalid identity: %s", err.Error()) } return c.JSON(http.StatusOK, "OK") diff --git a/http/handler/api/config.go b/http/handler/api/config.go index 9459c8f7..f231820a 100644 --- a/http/handler/api/config.go +++ b/http/handler/api/config.go @@ -64,11 +64,11 @@ func (p *ConfigHandler) Set(c echo.Context) error { body, err := io.ReadAll(req.Body) if err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } if err := json.Unmarshal(body, &version); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", json.FormatError(body, err)) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", json.FormatError(body, err)) } cfg := p.store.Get() @@ -84,11 +84,11 @@ func (p *ConfigHandler) Set(c echo.Context) error { v1SetConfig := api.NewSetConfigV1(cfg) if err := json.Unmarshal(body, &v1SetConfig); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", json.FormatError(body, err)) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", json.FormatError(body, err)) } if err := c.Validate(v1SetConfig); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } // Merge it into the current config @@ -98,11 +98,11 @@ func (p *ConfigHandler) Set(c echo.Context) error { v2SetConfig := api.NewSetConfigV2(cfg) if err := json.Unmarshal(body, &v2SetConfig); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", json.FormatError(body, err)) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", json.FormatError(body, err)) } if err := c.Validate(v2SetConfig); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } // Merge it into the current config @@ -111,17 +111,17 @@ func (p *ConfigHandler) Set(c echo.Context) error { v3SetConfig := api.NewSetConfig(cfg) if err := json.Unmarshal(body, &v3SetConfig); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", json.FormatError(body, err)) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", json.FormatError(body, err)) } if err := c.Validate(v3SetConfig); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } // Merge it into the current config v3SetConfig.MergeTo(cfg) } else { - return api.Err(http.StatusBadRequest, "Invalid config version", "version %d", version.Version) + return api.Err(http.StatusBadRequest, "", "invalid config version: %d", version.Version) } cfg.CreatedAt = time.Now() @@ -152,12 +152,12 @@ func (p *ConfigHandler) Set(c echo.Context) error { // Save the new config if err := p.store.Set(cfg); err != nil { - return api.Err(http.StatusBadRequest, "Failed to store config", "%s", err) + return api.Err(http.StatusBadRequest, "", "failed to store config: %s", err.Error()) } // Set the new and merged config as active config if err := p.store.SetActive(mergedConfig); err != nil { - return api.Err(http.StatusBadRequest, "Failed to activate config", "%s", err) + return api.Err(http.StatusBadRequest, "", "failed to activate config: %s", err.Error()) } return c.JSON(http.StatusOK, "OK") diff --git a/http/handler/api/events.go b/http/handler/api/events.go index c31e6620..f86d6729 100644 --- a/http/handler/api/events.go +++ b/http/handler/api/events.go @@ -42,7 +42,7 @@ func (h *EventsHandler) Events(c echo.Context) error { filters := api.EventFilters{} if err := util.ShouldBindJSON(c, &filters); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } filter := map[string]*api.EventFilter{} @@ -51,7 +51,7 @@ func (h *EventsHandler) Events(c echo.Context) error { f := f if err := f.Compile(); err != nil { - return api.Err(http.StatusBadRequest, "Invalid filter", "%s: %s", f.Component, err) + return api.Err(http.StatusBadRequest, "", "invalid filter: %s: %s", f.Component, err.Error()) } component := strings.ToLower(f.Component) diff --git a/http/handler/api/filesystems.go b/http/handler/api/filesystems.go index 12440b3b..eb2de22d 100644 --- a/http/handler/api/filesystems.go +++ b/http/handler/api/filesystems.go @@ -51,7 +51,7 @@ func (h *FSHandler) GetFile(c echo.Context) error { config, ok := h.filesystems[name] if !ok { - return api.Err(http.StatusNotFound, "File not found", "unknown filesystem: %s", name) + return api.Err(http.StatusNotFound, "", "file not found: unknown filesystem: %s", name) } return config.Handler.GetFile(c) @@ -78,7 +78,7 @@ func (h *FSHandler) PutFile(c echo.Context) error { config, ok := h.filesystems[name] if !ok { - return api.Err(http.StatusNotFound, "File not found", "unknown filesystem: %s", name) + return api.Err(http.StatusNotFound, "", "file not found: unknown filesystem: %s", name) } return config.Handler.PutFile(c) @@ -101,7 +101,7 @@ func (h *FSHandler) DeleteFile(c echo.Context) error { config, ok := h.filesystems[name] if !ok { - return api.Err(http.StatusNotFound, "File not found", "unknown filesystem: %s", name) + return api.Err(http.StatusNotFound, "", "file not found: unknown filesystem: %s", name) } return config.Handler.DeleteFile(c) @@ -127,7 +127,7 @@ func (h *FSHandler) DeleteFiles(c echo.Context) error { config, ok := h.filesystems[name] if !ok { - return api.Err(http.StatusNotFound, "File not found", "unknown filesystem: %s", name) + return api.Err(http.StatusNotFound, "", "file not found: unknown filesystem: %s", name) } return config.Handler.DeleteFiles(c) @@ -155,7 +155,7 @@ func (h *FSHandler) ListFiles(c echo.Context) error { config, ok := h.filesystems[name] if !ok { - return api.Err(http.StatusNotFound, "File not found", "unknown filesystem: %s", name) + return api.Err(http.StatusNotFound, "", "file not found: unknown filesystem: %s", name) } return config.Handler.ListFiles(c) @@ -201,25 +201,25 @@ func (h *FSHandler) FileOperation(c echo.Context) error { operation := api.FilesystemOperation{} if err := util.ShouldBindJSON(c, &operation); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } if operation.Operation != "copy" && operation.Operation != "move" { - return api.Err(http.StatusBadRequest, "Invalid operation", "%s", operation.Operation) + return api.Err(http.StatusBadRequest, "", "invalid operation: %s", operation.Operation) } rePrefix := regexp.MustCompile(`^(.+):`) matches := rePrefix.FindStringSubmatch(operation.Source) if matches == nil { - return api.Err(http.StatusBadRequest, "Missing source filesystem prefix") + return api.Err(http.StatusBadRequest, "", "missing source filesystem prefix") } fromFSName := matches[1] fromPath := rePrefix.ReplaceAllString(operation.Source, "") fromFS, ok := h.filesystems[fromFSName] if !ok { - return api.Err(http.StatusBadRequest, "Source filesystem not found", "%s", fromFSName) + return api.Err(http.StatusBadRequest, "", "source filesystem not found: %s", fromFSName) } if operation.Source == operation.Target { @@ -228,26 +228,26 @@ func (h *FSHandler) FileOperation(c echo.Context) error { matches = rePrefix.FindStringSubmatch(operation.Target) if matches == nil { - return api.Err(http.StatusBadRequest, "Missing target filesystem prefix") + return api.Err(http.StatusBadRequest, "", "missing target filesystem prefix") } toFSName := matches[1] toPath := rePrefix.ReplaceAllString(operation.Target, "") toFS, ok := h.filesystems[toFSName] if !ok { - return api.Err(http.StatusBadRequest, "Target filesystem not found", "%s", toFSName) + return api.Err(http.StatusBadRequest, "", "target filesystem not found: %s", toFSName) } fromFile := fromFS.Handler.FS.Filesystem.Open(fromPath) if fromFile == nil { - return api.Err(http.StatusNotFound, "File not found", "%s:%s", fromFSName, fromPath) + return api.Err(http.StatusNotFound, "", "file not found: %s:%s", fromFSName, fromPath) } defer fromFile.Close() fromFileStat, err := fromFile.Stat() if err != nil { - return api.Err(http.StatusBadRequest, "Source files with unknown size", "%s", fromFSName) + return api.Err(http.StatusBadRequest, "", "source files with unknown size: %s", fromFSName) } var reader io.Reader = fromFile @@ -266,7 +266,7 @@ func (h *FSHandler) FileOperation(c echo.Context) error { _, _, err = toFS.Handler.FS.Filesystem.WriteFileReader(toPath, sizer) if err != nil { toFS.Handler.FS.Filesystem.Remove(toPath) - return api.Err(http.StatusBadRequest, "Writing target file failed", "%s", err) + return api.Err(http.StatusBadRequest, "", "writing target file failed: %s", err) } if operation.Operation == "move" { diff --git a/http/handler/api/iam.go b/http/handler/api/iam.go index a5714056..1280a03a 100644 --- a/http/handler/api/iam.go +++ b/http/handler/api/iam.go @@ -44,28 +44,28 @@ func (h *IAMHandler) AddIdentity(c echo.Context) error { user := api.IAMUser{} if err := util.ShouldBindJSON(c, &user); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } iamuser, iampolicies := user.Unmarshal() if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "write") { - return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to create user '%s'", iamuser.Name) + return api.Err(http.StatusForbidden, "", "not allowed to create user '%s'", iamuser.Name) } for _, p := range iampolicies { if !h.iam.Enforce(ctxuser, p.Domain, "iam:"+iamuser.Name, "write") { - return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to write policy: %v", p) + return api.Err(http.StatusForbidden, "", "not allowed to write policy: %v", p) } } if !superuser && iamuser.Superuser { - return api.Err(http.StatusForbidden, "Forbidden", "Only superusers can add superusers") + return api.Err(http.StatusForbidden, "", "only superusers can add superusers") } err := h.iam.CreateIdentity(iamuser) if err != nil { - return api.Err(http.StatusBadRequest, "Bad request", "%s", err) + return api.Err(http.StatusBadRequest, "", "%s", err.Error()) } for _, p := range iampolicies { @@ -96,26 +96,26 @@ func (h *IAMHandler) RemoveIdentity(c echo.Context) error { name := util.PathParam(c, "name") if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") { - return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to delete this user") + return api.Err(http.StatusForbidden, "", "Not allowed to delete this user") } iamuser, err := h.iam.GetIdentity(name) if err != nil { - return api.Err(http.StatusNotFound, "Not found", "%s", err) + return api.Err(http.StatusNotFound, "", "%s", err.Error()) } if !superuser && iamuser.Superuser { - return api.Err(http.StatusForbidden, "Forbidden", "Only superusers can remove superusers") + return api.Err(http.StatusForbidden, "", "Only superusers can remove superusers") } // Remove the user if err := h.iam.DeleteIdentity(name); err != nil { - return api.Err(http.StatusBadRequest, "Bad request", "%s", err) + return api.Err(http.StatusBadRequest, "", "%s", err.Error()) } // Remove all policies of that user if err := h.iam.RemovePolicy(name, "", "", nil); err != nil { - return api.Err(http.StatusBadRequest, "Bad request", "%s", err) + return api.Err(http.StatusBadRequest, "", "%s", err.Error()) } return c.JSON(http.StatusOK, "OK") @@ -145,7 +145,7 @@ func (h *IAMHandler) UpdateIdentity(c echo.Context) error { name := util.PathParam(c, "name") if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") { - return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to modify this user") + return api.Err(http.StatusForbidden, "", "Not allowed to modify this user") } var iamuser identity.User @@ -154,7 +154,7 @@ func (h *IAMHandler) UpdateIdentity(c echo.Context) error { if name != "$anon" { iamuser, err = h.iam.GetIdentity(name) if err != nil { - return api.Err(http.StatusNotFound, "Not found", "%s", err) + return api.Err(http.StatusNotFound, "", "%s", err.Error()) } } else { iamuser = identity.User{ @@ -168,23 +168,23 @@ func (h *IAMHandler) UpdateIdentity(c echo.Context) error { user.Marshal(iamuser, iampolicies) if err := util.ShouldBindJSON(c, &user); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } iamuser, iampolicies = user.Unmarshal() if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "write") { - return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to create user '%s'", iamuser.Name) + return api.Err(http.StatusForbidden, "", "Not allowed to create user '%s'", iamuser.Name) } for _, p := range iampolicies { if !h.iam.Enforce(ctxuser, p.Domain, "iam:"+iamuser.Name, "write") { - return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to write policy: %v", p) + return api.Err(http.StatusForbidden, "", "Not allowed to write policy: %v", p) } } if !superuser && iamuser.Superuser { - return api.Err(http.StatusForbidden, "Forbidden", "Only superusers can modify superusers") + return api.Err(http.StatusForbidden, "", "Only superusers can modify superusers") } if name != "$anon" { @@ -249,24 +249,24 @@ func (h *IAMHandler) UpdateIdentityPolicies(c echo.Context) error { policies := []api.IAMPolicy{} if err := util.ShouldBindJSONValidation(c, &policies, false); err != nil { - return api.Err(http.StatusBadRequest, "", "Invalid JSON: %s", err.Error()) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } for _, p := range policies { err := c.Validate(p) if err != nil { - return api.Err(http.StatusBadRequest, "", "Invalid JSON: %s", err.Error()) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } } for _, p := range policies { if !h.iam.Enforce(ctxuser, p.Domain, "iam:"+iamuser.Name, "write") { - return api.Err(http.StatusForbidden, "", "Not allowed to write policy: %v", p) + return api.Err(http.StatusForbidden, "", "not allowed to write policy: %v", p) } } if !superuser && iamuser.Superuser { - return api.Err(http.StatusForbidden, "", "Only superusers can modify superusers") + return api.Err(http.StatusForbidden, "", "only superusers can modify superusers") } if err := h.iam.RemovePolicy(name, "", "", nil); err != nil { @@ -343,7 +343,7 @@ func (h *IAMHandler) GetIdentity(c echo.Context) error { name := util.PathParam(c, "name") if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "read") { - return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to access this user") + return api.Err(http.StatusForbidden, "", "not allowed to access this user") } var iamuser identity.User @@ -352,7 +352,7 @@ func (h *IAMHandler) GetIdentity(c echo.Context) error { if name != "$anon" { iamuser, err = h.iam.GetIdentity(name) if err != nil { - return api.Err(http.StatusNotFound, "Not found", "%s", err) + return api.Err(http.StatusNotFound, "", "%s", err.Error()) } if ctxuser != iamuser.Name { diff --git a/http/handler/api/jwt.go b/http/handler/api/jwt.go index 95f798ff..b7565470 100644 --- a/http/handler/api/jwt.go +++ b/http/handler/api/jwt.go @@ -27,7 +27,7 @@ func (j *JWTHandler) Login(c echo.Context) error { at, rt, err := j.iam.CreateJWT(subject) if err != nil { - return api.Err(http.StatusForbidden, "Failed to create JWT", "%s", err) + return api.Err(http.StatusForbidden, "", "failed to create JWT: %s", err) } return c.JSON(http.StatusOK, api.JWT{ @@ -39,12 +39,12 @@ func (j *JWTHandler) Login(c echo.Context) error { func (j *JWTHandler) Refresh(c echo.Context) error { subject, ok := c.Get("user").(string) if !ok { - return api.Err(http.StatusForbidden, "Invalid token") + return api.Err(http.StatusForbidden, "", "invalid token") } at, _, err := j.iam.CreateJWT(subject) if err != nil { - return api.Err(http.StatusForbidden, "Failed to create JWT", "%s", err) + return api.Err(http.StatusForbidden, "", "failed to create JWT: %s", err.Error()) } return c.JSON(http.StatusOK, api.JWTRefresh{ diff --git a/http/handler/api/metrics.go b/http/handler/api/metrics.go index 06bd80f7..f15b2de3 100644 --- a/http/handler/api/metrics.go +++ b/http/handler/api/metrics.go @@ -74,7 +74,7 @@ func (r *MetricsHandler) Metrics(c echo.Context) error { var query api.MetricsQuery if err := util.ShouldBindJSON(c, &query); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } patterns := []metric.Pattern{} diff --git a/http/handler/api/playout.go b/http/handler/api/playout.go index 0d15724d..99d513bb 100644 --- a/http/handler/api/playout.go +++ b/http/handler/api/playout.go @@ -36,7 +36,7 @@ func (h *RestreamHandler) PlayoutStatus(c echo.Context) error { domain := util.DefaultQuery(c, "domain", "") if !h.iam.Enforce(user, domain, "process:"+id, "read") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "") } tid := app.ProcessID{ @@ -46,14 +46,14 @@ func (h *RestreamHandler) PlayoutStatus(c echo.Context) error { addr, err := h.restream.GetPlayout(tid, inputid) if err != nil { - return api.Err(http.StatusNotFound, "Unknown process or input", "%s", err) + return api.Err(http.StatusNotFound, "", "unknown process or input: %s", err.Error()) } path := "/v1/status" response, err := h.request(http.MethodGet, addr, path, "", nil) if err != nil { - return api.Err(http.StatusInternalServerError, "", "%s", err) + return api.Err(http.StatusInternalServerError, "", "%s", err.Error()) } defer response.Body.Close() @@ -61,7 +61,7 @@ func (h *RestreamHandler) PlayoutStatus(c echo.Context) error { // Read the whole response data, err := io.ReadAll(response.Body) if err != nil { - return api.Err(http.StatusInternalServerError, "", "%s", err) + return api.Err(http.StatusInternalServerError, "", "%s", err.Error()) } if response.StatusCode == http.StatusOK { @@ -69,7 +69,7 @@ func (h *RestreamHandler) PlayoutStatus(c echo.Context) error { err := json.Unmarshal(data, &status) if err != nil { - return api.Err(http.StatusInternalServerError, "", "%s", err) + return api.Err(http.StatusInternalServerError, "", "%s", err.Error()) } apistatus := api.PlayoutStatus{} @@ -105,7 +105,7 @@ func (h *RestreamHandler) PlayoutKeyframe(c echo.Context) error { domain := util.DefaultQuery(c, "domain", "") if !h.iam.Enforce(user, domain, "process:"+id, "read") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "") } tid := app.ProcessID{ @@ -115,7 +115,7 @@ func (h *RestreamHandler) PlayoutKeyframe(c echo.Context) error { addr, err := h.restream.GetPlayout(tid, inputid) if err != nil { - return api.Err(http.StatusNotFound, "Unknown process or input", "%s", err) + return api.Err(http.StatusNotFound, "", "unknown process or input: %s", err.Error()) } path := "/v1/keyframe/last." @@ -128,7 +128,7 @@ func (h *RestreamHandler) PlayoutKeyframe(c echo.Context) error { response, err := h.request(http.MethodGet, addr, path, "", nil) if err != nil { - return api.Err(http.StatusInternalServerError, "", "%s", err) + return api.Err(http.StatusInternalServerError, "", "%s", err.Error()) } defer response.Body.Close() @@ -136,7 +136,7 @@ func (h *RestreamHandler) PlayoutKeyframe(c echo.Context) error { // Read the whole response data, err := io.ReadAll(response.Body) if err != nil { - return api.Err(http.StatusInternalServerError, "", "%s", err) + return api.Err(http.StatusInternalServerError, "", "%s", err.Error()) } return c.Blob(response.StatusCode, response.Header.Get("content-type"), data) @@ -163,7 +163,7 @@ func (h *RestreamHandler) PlayoutEncodeErrorframe(c echo.Context) error { domain := util.DefaultQuery(c, "domain", "") if !h.iam.Enforce(user, domain, "process:"+id, "write") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "") } tid := app.ProcessID{ @@ -173,14 +173,14 @@ func (h *RestreamHandler) PlayoutEncodeErrorframe(c echo.Context) error { addr, err := h.restream.GetPlayout(tid, inputid) if err != nil { - return api.Err(http.StatusNotFound, "Unknown process or input", "%s", err) + return api.Err(http.StatusNotFound, "", "unknown process or input: %s", err.Error()) } path := "/v1/errorframe/encode" response, err := h.request(http.MethodGet, addr, path, "", nil) if err != nil { - return api.Err(http.StatusInternalServerError, "", "%s", err) + return api.Err(http.StatusInternalServerError, "", "%s", err.Error()) } defer response.Body.Close() @@ -188,7 +188,7 @@ func (h *RestreamHandler) PlayoutEncodeErrorframe(c echo.Context) error { // Read the whole response data, err := io.ReadAll(response.Body) if err != nil { - return api.Err(http.StatusInternalServerError, "", "%s", err) + return api.Err(http.StatusInternalServerError, "", "%s", err.Error()) } return c.Blob(response.StatusCode, response.Header.Get("content-type"), data) @@ -218,7 +218,7 @@ func (h *RestreamHandler) PlayoutSetErrorframe(c echo.Context) error { domain := util.DefaultQuery(c, "domain", "") if !h.iam.Enforce(user, domain, "process:"+id, "write") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "") } tid := app.ProcessID{ @@ -228,19 +228,19 @@ func (h *RestreamHandler) PlayoutSetErrorframe(c echo.Context) error { addr, err := h.restream.GetPlayout(tid, inputid) if err != nil { - return api.Err(http.StatusNotFound, "Unknown process or input", "%s", err) + return api.Err(http.StatusNotFound, "", "unknown process or input: %s", err.Error()) } data, err := io.ReadAll(c.Request().Body) if err != nil { - return api.Err(http.StatusBadRequest, "Failed to read request body", "%s", err) + return api.Err(http.StatusBadRequest, "", "failed to read request body: %s", err.Error()) } path := "/v1/errorframe.jpg" response, err := h.request(http.MethodPut, addr, path, "application/octet-stream", data) if err != nil { - return api.Err(http.StatusInternalServerError, "", "%s", err) + return api.Err(http.StatusInternalServerError, "", "%s", err.Error()) } defer response.Body.Close() @@ -248,7 +248,7 @@ func (h *RestreamHandler) PlayoutSetErrorframe(c echo.Context) error { // Read the whole response data, err = io.ReadAll(response.Body) if err != nil { - return api.Err(http.StatusInternalServerError, "", "%s", err) + return api.Err(http.StatusInternalServerError, "", "%s", err.Error()) } return c.Blob(response.StatusCode, response.Header.Get("content-type"), data) @@ -284,14 +284,14 @@ func (h *RestreamHandler) PlayoutReopenInput(c echo.Context) error { addr, err := h.restream.GetPlayout(tid, inputid) if err != nil { - return api.Err(http.StatusNotFound, "Unknown process or input", "%s", err) + return api.Err(http.StatusNotFound, "", "unknown process or input: %s", err.Error()) } path := "/v1/reopen" response, err := h.request(http.MethodGet, addr, path, "", nil) if err != nil { - return api.Err(http.StatusInternalServerError, "", "%s", err) + return api.Err(http.StatusInternalServerError, "", "%s", err.Error()) } defer response.Body.Close() @@ -299,7 +299,7 @@ func (h *RestreamHandler) PlayoutReopenInput(c echo.Context) error { // Read the whole response data, err := io.ReadAll(response.Body) if err != nil { - return api.Err(http.StatusInternalServerError, "", "%s", err) + return api.Err(http.StatusInternalServerError, "", "%s", err.Error()) } return c.Blob(response.StatusCode, response.Header.Get("content-type"), data) @@ -328,7 +328,7 @@ func (h *RestreamHandler) PlayoutSetStream(c echo.Context) error { domain := util.DefaultQuery(c, "domain", "") if !h.iam.Enforce(user, domain, "process:"+id, "write") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "") } tid := app.ProcessID{ @@ -338,19 +338,19 @@ func (h *RestreamHandler) PlayoutSetStream(c echo.Context) error { addr, err := h.restream.GetPlayout(tid, inputid) if err != nil { - return api.Err(http.StatusNotFound, "Unknown process or input", "%s", err) + return api.Err(http.StatusNotFound, "", "unknown process or input: %s", err.Error()) } data, err := io.ReadAll(c.Request().Body) if err != nil { - return api.Err(http.StatusBadRequest, "Failed to read request body", "%s", err) + return api.Err(http.StatusBadRequest, "", "failed to read request body: %s", err.Error()) } path := "/v1/stream" response, err := h.request(http.MethodPut, addr, path, "text/plain", data) if err != nil { - return api.Err(http.StatusInternalServerError, "", "%s", err) + return api.Err(http.StatusInternalServerError, "", "%s", err.Error()) } defer response.Body.Close() @@ -358,7 +358,7 @@ func (h *RestreamHandler) PlayoutSetStream(c echo.Context) error { // Read the whole response data, err = io.ReadAll(response.Body) if err != nil { - return api.Err(http.StatusInternalServerError, "", "%s", err) + return api.Err(http.StatusInternalServerError, "", "%s", err.Error()) } return c.Blob(response.StatusCode, response.Header.Get("content-type"), data) diff --git a/http/handler/api/restream.go b/http/handler/api/restream.go index 6ca3457b..81f87c5d 100644 --- a/http/handler/api/restream.go +++ b/http/handler/api/restream.go @@ -56,7 +56,7 @@ func (h *RestreamHandler) Add(c echo.Context) error { } if err := util.ShouldBindJSON(c, &process); err != nil { - return api.Err(http.StatusBadRequest, "", "Invalid JSON: %s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } if !h.iam.Enforce(ctxuser, process.Domain, "process:"+process.ID, "write") { @@ -70,17 +70,17 @@ func (h *RestreamHandler) Add(c echo.Context) error { } if process.Type != "ffmpeg" { - return api.Err(http.StatusBadRequest, "", "Unsupported process type, supported process types are: ffmpeg") + return api.Err(http.StatusBadRequest, "", "unsupported process type, supported process types are: ffmpeg") } if len(process.Input) == 0 || len(process.Output) == 0 { - return api.Err(http.StatusBadRequest, "", "At least one input and one output need to be defined") + return api.Err(http.StatusBadRequest, "", "at least one input and one output need to be defined") } config, metadata := process.Marshal() if err := h.restream.AddProcess(config); err != nil { - return api.Err(http.StatusBadRequest, "", "Invalid process config: %s", err.Error()) + return api.Err(http.StatusBadRequest, "", "invalid process config: %s", err.Error()) } tid := app.ProcessID{ @@ -195,7 +195,7 @@ func (h *RestreamHandler) Get(c echo.Context) error { p, err := h.getProcess(tid, filter) if err != nil { - return api.Err(http.StatusNotFound, "", "Unknown process ID: %s", err.Error()) + return api.Err(http.StatusNotFound, "", "unknown process ID: %s", err.Error()) } return c.JSON(http.StatusOK, p) @@ -227,16 +227,16 @@ func (h *RestreamHandler) Delete(c echo.Context) error { if !superuser { if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "") } } if err := h.restream.StopProcess(tid); err != nil { - return api.Err(http.StatusNotFound, "Unknown process ID", "%s", err) + return api.Err(http.StatusNotFound, "", "unknown process ID: %s", err.Error()) } if err := h.restream.DeleteProcess(tid); err != nil { - return api.Err(http.StatusInternalServerError, "Process can't be deleted", "%s", err) + return api.Err(http.StatusInternalServerError, "", "process can't be deleted: %s", err.Error()) } return c.JSON(http.StatusOK, "OK") @@ -282,14 +282,14 @@ func (h *RestreamHandler) Update(c echo.Context) error { current, err := h.restream.GetProcess(tid) if err != nil { - return api.Err(http.StatusNotFound, "Process not found", "%s", id) + return api.Err(http.StatusNotFound, "") } // Prefill the config with the current values process.Unmarshal(current.Config) if err := util.ShouldBindJSON(c, &process); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } if !h.iam.Enforce(ctxuser, process.Domain, "process:"+process.ID, "write") { @@ -311,10 +311,10 @@ func (h *RestreamHandler) Update(c echo.Context) error { if err := h.restream.UpdateProcess(tid, config); err != nil { if err == restream.ErrUnknownProcess { - return api.Err(http.StatusNotFound, "Process not found", "%s", id) + return api.Err(http.StatusNotFound, "", "process not found: %s", id) } - return api.Err(http.StatusBadRequest, "Process can't be updated", "%s", err) + return api.Err(http.StatusBadRequest, "", "process can't be updated: %s", err.Error()) } tid = app.ProcessID{ @@ -353,13 +353,13 @@ func (h *RestreamHandler) Command(c echo.Context) error { domain := util.DefaultQuery(c, "domain", "") if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "") } var command api.Command if err := util.ShouldBindJSON(c, &command); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } tid := app.ProcessID{ @@ -377,11 +377,11 @@ func (h *RestreamHandler) Command(c echo.Context) error { } else if command.Command == "reload" { err = h.restream.ReloadProcess(tid) } else { - return api.Err(http.StatusBadRequest, "Unknown command provided", "Known commands are: start, stop, reload, restart") + return api.Err(http.StatusBadRequest, "", "unknown command provided: known commands are: start, stop, reload, restart") } if err != nil { - return api.Err(http.StatusBadRequest, "Command failed", "%s", err) + return api.Err(http.StatusBadRequest, "", "command failed: %s", err.Error()) } return c.JSON(http.StatusOK, "OK") @@ -407,7 +407,7 @@ func (h *RestreamHandler) GetConfig(c echo.Context) error { domain := util.DefaultQuery(c, "domain", "") if !h.iam.Enforce(ctxuser, domain, "process:"+id, "read") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "") } tid := app.ProcessID{ @@ -417,7 +417,7 @@ func (h *RestreamHandler) GetConfig(c echo.Context) error { p, err := h.restream.GetProcess(tid) if err != nil { - return api.Err(http.StatusNotFound, "Unknown process ID", "%s", err) + return api.Err(http.StatusNotFound, "", "unknown process ID: %s", err.Error()) } config := api.ProcessConfig{} @@ -446,7 +446,7 @@ func (h *RestreamHandler) GetState(c echo.Context) error { domain := util.DefaultQuery(c, "domain", "") if !h.iam.Enforce(ctxuser, domain, "process:"+id, "read") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "") } tid := app.ProcessID{ @@ -456,7 +456,7 @@ func (h *RestreamHandler) GetState(c echo.Context) error { s, err := h.restream.GetProcessState(tid) if err != nil { - return api.Err(http.StatusNotFound, "Unknown process ID", "%s", err) + return api.Err(http.StatusNotFound, "", "unknown process ID: %s", err.Error()) } state := api.ProcessState{} @@ -493,7 +493,7 @@ func (h *RestreamHandler) GetReport(c echo.Context) error { if len(createdUnix) != 0 { if x, err := strconv.ParseInt(createdUnix, 10, 64); err != nil { - return api.Err(http.StatusBadRequest, "Invalid created_at unix timestamp", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid created_at unix timestamp: %s", err.Error()) } else { createdAt = &x } @@ -501,14 +501,14 @@ func (h *RestreamHandler) GetReport(c echo.Context) error { if len(exitedUnix) != 0 { if x, err := strconv.ParseInt(exitedUnix, 10, 64); err != nil { - return api.Err(http.StatusBadRequest, "Invalid exited_at unix timestamp", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid exited_at unix timestamp: %s", err.Error()) } else { exitedAt = &x } } if !h.iam.Enforce(ctxuser, domain, "process:"+id, "read") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "") } tid := app.ProcessID{ @@ -518,7 +518,7 @@ func (h *RestreamHandler) GetReport(c echo.Context) error { l, err := h.restream.GetProcessLog(tid) if err != nil { - return api.Err(http.StatusNotFound, "Unknown process ID", "%s", err) + return api.Err(http.StatusNotFound, "", "unknown process ID: %s", err.Error()) } report := api.ProcessReport{} @@ -556,7 +556,7 @@ func (h *RestreamHandler) GetReport(c echo.Context) error { } if len(entries) == 0 { - return api.Err(http.StatusNotFound, "No matching reports found") + return api.Err(http.StatusNotFound, "", "No matching reports found") } sort.SliceStable(entries, func(i, j int) bool { @@ -603,7 +603,7 @@ func (h *RestreamHandler) SearchReportHistory(c echo.Context) error { if len(fromUnix) != 0 { if x, err := strconv.ParseInt(fromUnix, 10, 64); err != nil { - return api.Err(http.StatusBadRequest, "Invalid search range", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid search range: %s", err.Error()) } else { t := time.Unix(x, 0) from = &t @@ -612,7 +612,7 @@ func (h *RestreamHandler) SearchReportHistory(c echo.Context) error { if len(toUnix) != 0 { if x, err := strconv.ParseInt(toUnix, 10, 64); err != nil { - return api.Err(http.StatusBadRequest, "Invalid search range", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid search range: %s", err.Error()) } else { t := time.Unix(x, 0) to = &t @@ -651,7 +651,7 @@ func (h *RestreamHandler) Probe(c echo.Context) error { domain := util.DefaultQuery(c, "domain", "") if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "") } tid := app.ProcessID{ @@ -726,7 +726,7 @@ func (h *RestreamHandler) GetProcessMetadata(c echo.Context) error { domain := util.DefaultQuery(c, "domain", "") if !h.iam.Enforce(ctxuser, domain, "process:"+id, "read") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "") } tid := app.ProcessID{ @@ -736,7 +736,7 @@ func (h *RestreamHandler) GetProcessMetadata(c echo.Context) error { data, err := h.restream.GetProcessMetadata(tid, key) if err != nil { - return api.Err(http.StatusNotFound, "Unknown process ID", "%s", err) + return api.Err(http.StatusNotFound, "", "unknown process ID: %s", err.Error()) } return c.JSON(http.StatusOK, data) @@ -765,17 +765,17 @@ func (h *RestreamHandler) SetProcessMetadata(c echo.Context) error { domain := util.DefaultQuery(c, "domain", "") if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") { - return api.Err(http.StatusForbidden, "Forbidden") + return api.Err(http.StatusForbidden, "") } if len(key) == 0 { - return api.Err(http.StatusBadRequest, "Invalid key", "The key must not be of length 0") + return api.Err(http.StatusBadRequest, "", "invalid key: the key must not be of length 0") } var data api.Metadata if err := util.ShouldBindJSONValidation(c, &data, false); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } tid := app.ProcessID{ @@ -784,7 +784,7 @@ func (h *RestreamHandler) SetProcessMetadata(c echo.Context) error { } if err := h.restream.SetProcessMetadata(tid, key, data); err != nil { - return api.Err(http.StatusNotFound, "Unknown process ID", "%s", err) + return api.Err(http.StatusNotFound, "", "unknown process ID: %s", err.Error()) } return c.JSON(http.StatusOK, data) @@ -807,7 +807,7 @@ func (h *RestreamHandler) GetMetadata(c echo.Context) error { data, err := h.restream.GetMetadata(key) if err != nil { - return api.Err(http.StatusNotFound, "Metadata not found", "%s", err) + return api.Err(http.StatusNotFound, "", "metadata not found: %s", err.Error()) } return c.JSON(http.StatusOK, data) @@ -829,17 +829,17 @@ func (h *RestreamHandler) SetMetadata(c echo.Context) error { key := util.PathParam(c, "key") if len(key) == 0 { - return api.Err(http.StatusBadRequest, "Invalid key", "The key must not be of length 0") + return api.Err(http.StatusBadRequest, "", "invalid key: the key must not be of length 0") } var data api.Metadata if err := util.ShouldBindJSONValidation(c, &data, false); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } if err := h.restream.SetMetadata(key, data); err != nil { - return api.Err(http.StatusBadRequest, "Invalid metadata", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid metadata: %s", err.Error()) } return c.JSON(http.StatusOK, data) diff --git a/http/handler/api/session.go b/http/handler/api/session.go index e3b2169a..31427110 100644 --- a/http/handler/api/session.go +++ b/http/handler/api/session.go @@ -101,19 +101,19 @@ func (s *SessionHandler) CreateToken(c echo.Context) error { identity, err := s.iam.GetVerifier(username) if err != nil { - return api.Err(http.StatusNotFound, "", "%s", err) + return api.Err(http.StatusNotFound, "", "%s", err.Error()) } request := []api.SessionTokenRequest{} if err := util.ShouldBindJSONValidation(c, &request, false); err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } for _, r := range request { err := c.Validate(r) if err != nil { - return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err) + return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error()) } } diff --git a/http/handler/api/widget.go b/http/handler/api/widget.go index c453283b..3c3d953a 100644 --- a/http/handler/api/widget.go +++ b/http/handler/api/widget.go @@ -47,7 +47,7 @@ func (w *WidgetHandler) Get(c echo.Context) error { domain := util.DefaultQuery(c, "domain", "") if w.restream == nil { - return api.Err(http.StatusNotFound, "Unknown process ID") + return api.Err(http.StatusNotFound, "", "Unknown process ID") } tid := app.ProcessID{ @@ -57,12 +57,12 @@ func (w *WidgetHandler) Get(c echo.Context) error { process, err := w.restream.GetProcess(tid) if err != nil { - return api.Err(http.StatusNotFound, "Unknown process ID", "%s", err) + return api.Err(http.StatusNotFound, "", "unknown process ID: %s", err.Error()) } state, err := w.restream.GetProcessState(tid) if err != nil { - return api.Err(http.StatusNotFound, "Unknown process ID", "%s", err) + return api.Err(http.StatusNotFound, "", "unknown process ID: %s", err.Error()) } data := api.WidgetProcess{ diff --git a/http/handler/filesystem.go b/http/handler/filesystem.go index ef7552e7..f2bbbd87 100644 --- a/http/handler/filesystem.go +++ b/http/handler/filesystem.go @@ -40,7 +40,7 @@ func (h *FSHandler) GetFile(c echo.Context) error { file := h.FS.Filesystem.Open(path) if file == nil { - return api.Err(http.StatusNotFound, "File not found", path) + return api.Err(http.StatusNotFound, "", "file not found: %s", path) } stat, _ := file.Stat() @@ -53,7 +53,7 @@ func (h *FSHandler) GetFile(c echo.Context) error { file = h.FS.Filesystem.Open(path) if file == nil { - return api.Err(http.StatusNotFound, "File not found", path) + return api.Err(http.StatusNotFound, "", "file not found: %s", path) } stat, _ = file.Stat() @@ -136,7 +136,7 @@ func (h *FSHandler) PutFile(c echo.Context) error { _, created, err := h.FS.Filesystem.WriteFileReader(path, req.Body) if err != nil { - return api.Err(http.StatusBadRequest, "Bad request", "%s", err) + return api.Err(http.StatusBadRequest, "", "%s", err.Error()) } if h.FS.Cache != nil { @@ -178,7 +178,7 @@ func (h *FSHandler) DeleteFile(c echo.Context) error { } if size < 0 { - return api.Err(http.StatusNotFound, "File not found", path) + return api.Err(http.StatusNotFound, "", "file not found: %s", path) } return c.String(http.StatusOK, "Deleted: "+path) @@ -192,7 +192,7 @@ func (h *FSHandler) DeleteFiles(c echo.Context) error { modifiedEnd := util.DefaultQuery(c, "lastmod_end", "") if len(pattern) == 0 { - return api.Err(http.StatusBadRequest, "Bad request", "A glob pattern is required") + return api.Err(http.StatusBadRequest, "", "a glob pattern is required") } options := fs.ListOptions{ @@ -200,20 +200,20 @@ func (h *FSHandler) DeleteFiles(c echo.Context) error { } if x, err := strconv.ParseInt(sizeMin, 10, 64); err != nil { - return api.Err(http.StatusBadRequest, "Bad request", "%s", err) + return api.Err(http.StatusBadRequest, "", "size_min: %s", err.Error()) } else { options.SizeMin = x } if x, err := strconv.ParseInt(sizeMax, 10, 64); err != nil { - return api.Err(http.StatusBadRequest, "Bad request", "%s", err) + return api.Err(http.StatusBadRequest, "", "size_max: %s", err.Error()) } else { options.SizeMax = x } if len(modifiedStart) != 0 { if x, err := strconv.ParseInt(modifiedStart, 10, 64); err != nil { - return api.Err(http.StatusBadRequest, "Bad request", "%s", err) + return api.Err(http.StatusBadRequest, "", "lastmod_start: %s", err.Error()) } else { t := time.Unix(x, 0) options.ModifiedStart = &t @@ -222,7 +222,7 @@ func (h *FSHandler) DeleteFiles(c echo.Context) error { if len(modifiedEnd) != 0 { if x, err := strconv.ParseInt(modifiedEnd, 10, 64); err != nil { - return api.Err(http.StatusBadRequest, "Bad request", "%s", err) + return api.Err(http.StatusBadRequest, "", "lastmod_end: %s", err.Error()) } else { t := time.Unix(x+1, 0) options.ModifiedEnd = &t @@ -261,20 +261,20 @@ func (h *FSHandler) ListFiles(c echo.Context) error { } if x, err := strconv.ParseInt(sizeMin, 10, 64); err != nil { - return api.Err(http.StatusBadRequest, "Bad request", "%s", err) + return api.Err(http.StatusBadRequest, "", "size_min: %s", err.Error()) } else { options.SizeMin = x } if x, err := strconv.ParseInt(sizeMax, 10, 64); err != nil { - return api.Err(http.StatusBadRequest, "Bad request", "%s", err) + return api.Err(http.StatusBadRequest, "", "size_max: %s", err.Error()) } else { options.SizeMax = x } if len(modifiedStart) != 0 { if x, err := strconv.ParseInt(modifiedStart, 10, 64); err != nil { - return api.Err(http.StatusBadRequest, "Bad request", "%s", err) + return api.Err(http.StatusBadRequest, "", "lastmod_start: %s", err.Error()) } else { t := time.Unix(x, 0) options.ModifiedStart = &t @@ -283,7 +283,7 @@ func (h *FSHandler) ListFiles(c echo.Context) error { if len(modifiedEnd) != 0 { if x, err := strconv.ParseInt(modifiedEnd, 10, 64); err != nil { - return api.Err(http.StatusBadRequest, "Bad request", "%s", err) + return api.Err(http.StatusBadRequest, "", "lastmode_end: %s", err.Error()) } else { t := time.Unix(x+1, 0) options.ModifiedEnd = &t