Adjust returned API errors

This commit is contained in:
Ingo Oppermann 2023-06-23 21:42:01 +02:00
parent f37896a1e3
commit 37cac48223
No known key found for this signature in database
GPG Key ID: 2AB32426E9DD229E
12 changed files with 190 additions and 190 deletions

View File

@ -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")

View File

@ -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")

View File

@ -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)

View File

@ -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" {

View File

@ -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 {

View File

@ -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{

View File

@ -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{}

View File

@ -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)

View File

@ -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)

View File

@ -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())
}
}

View File

@ -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{

View File

@ -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