trade panic for logging on render.Render

This commit is contained in:
Willy Kloucek
2021-11-26 17:38:33 +01:00
parent 20ab79deb4
commit a33b0049fc
8 changed files with 143 additions and 132 deletions
+8 -8
View File
@@ -14,13 +14,19 @@ import (
func RequireAdmin(opts ...Option) func(next http.Handler) http.Handler {
opt := newOptions(opts...)
mustRender := func(w http.ResponseWriter, r *http.Request, renderer render.Renderer) {
if err := render.Render(w, r, renderer); err != nil {
opt.Logger.Err(err).Msgf("failed to write response for ocs request %s on %s", r.Method, r.URL)
}
}
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// get roles from context
roleIDs, ok := roles.ReadRoleIDsFromContext(r.Context())
if !ok {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaUnauthorized.StatusCode, "Unauthorized")))
mustRender(w, r, response.ErrRender(data.MetaUnauthorized.StatusCode, "Unauthorized"))
return
}
@@ -30,13 +36,7 @@ func RequireAdmin(opts ...Option) func(next http.Handler) http.Handler {
return
}
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaUnauthorized.StatusCode, "Unauthorized")))
mustRender(w, r, response.ErrRender(data.MetaUnauthorized.StatusCode, "Unauthorized"))
})
}
}
func mustNotFail(err error) {
if err != nil {
panic(err)
}
}
+11 -5
View File
@@ -17,22 +17,28 @@ import (
func RequireSelfOrAdmin(opts ...Option) func(next http.Handler) http.Handler {
opt := newOptions(opts...)
mustRender := func(w http.ResponseWriter, r *http.Request, renderer render.Renderer) {
if err := render.Render(w, r, renderer); err != nil {
opt.Logger.Err(err).Msgf("failed to write response for ocs request %s on %s", r.Method, r.URL)
}
}
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
u, ok := revactx.ContextGetUser(r.Context())
if !ok {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaUnauthorized.StatusCode, "Unauthorized")))
mustRender(w, r, response.ErrRender(data.MetaUnauthorized.StatusCode, "Unauthorized"))
return
}
if u.Id == nil || u.Id.OpaqueId == "" {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "user is missing an id")))
mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "user is missing an id"))
return
}
// get roles from context
roleIDs, ok := roles.ReadRoleIDsFromContext(r.Context())
if !ok {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaUnauthorized.StatusCode, "Unauthorized")))
mustRender(w, r, response.ErrRender(data.MetaUnauthorized.StatusCode, "Unauthorized"))
return
}
@@ -47,7 +53,7 @@ func RequireSelfOrAdmin(opts ...Option) func(next http.Handler) http.Handler {
userid := chi.URLParam(r, "userid")
var err error
if userid, err = url.PathUnescape(userid); err != nil {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "malformed username")))
mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "malformed username"))
}
if userid == "" || userid == u.Id.OpaqueId || userid == u.Username {
@@ -56,7 +62,7 @@ func RequireSelfOrAdmin(opts ...Option) func(next http.Handler) http.Handler {
}
}
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaUnauthorized.StatusCode, "Unauthorized")))
mustRender(w, r, response.ErrRender(data.MetaUnauthorized.StatusCode, "Unauthorized"))
})
}
+10 -3
View File
@@ -10,18 +10,25 @@ import (
)
// RequireUser middleware is used to require a user in context
func RequireUser() func(next http.Handler) http.Handler {
func RequireUser(opts ...Option) func(next http.Handler) http.Handler {
opt := newOptions(opts...)
mustRender := func(w http.ResponseWriter, r *http.Request, renderer render.Renderer) {
if err := render.Render(w, r, renderer); err != nil {
opt.Logger.Err(err).Msgf("failed to write response for ocs request %s on %s", r.Method, r.URL)
}
}
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
u, ok := revactx.ContextGetUser(r.Context())
if !ok {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaUnauthorized.StatusCode, "Unauthorized")))
mustRender(w, r, response.ErrRender(data.MetaUnauthorized.StatusCode, "Unauthorized"))
return
}
if u.Id == nil || u.Id.OpaqueId == "" {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "user is missing an id")))
mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "user is missing an id"))
return
}
+2 -3
View File
@@ -3,18 +3,17 @@ package svc
import (
"net/http"
"github.com/go-chi/render"
"github.com/owncloud/ocis/ocs/pkg/service/v0/data"
"github.com/owncloud/ocis/ocs/pkg/service/v0/response"
)
// GetConfig renders the ocs config endpoint
func (o Ocs) GetConfig(w http.ResponseWriter, r *http.Request) {
mustNotFail(render.Render(w, r, response.DataRender(&data.ConfigData{
o.mustRender(w, r, response.DataRender(&data.ConfigData{
Version: "1.7", // TODO get from env
Website: "ocis", // TODO get from env
Host: "", // TODO get from FRONTEND config
Contact: "", // TODO get from env
SSL: "true", // TODO get from env
})))
}))
}
+48 -50
View File
@@ -11,7 +11,6 @@ import (
revactx "github.com/cs3org/reva/pkg/ctx"
"github.com/go-chi/chi/v5"
"github.com/go-chi/render"
accounts "github.com/owncloud/ocis/accounts/pkg/proto/v0"
"github.com/owncloud/ocis/ocs/pkg/service/v0/data"
"github.com/owncloud/ocis/ocs/pkg/service/v0/response"
@@ -41,7 +40,7 @@ func (o Ocs) ListUserGroups(w http.ResponseWriter, r *http.Request) {
span.SetAttributes(attribute.StringSlice("groups", u.Groups))
if len(u.Groups) > 0 {
mustNotFail(render.Render(w, r, response.DataRender(&data.Groups{Groups: u.Groups})))
o.mustRender(w, r, response.DataRender(&data.Groups{Groups: u.Groups}))
return
}
}
@@ -57,9 +56,9 @@ func (o Ocs) ListUserGroups(w http.ResponseWriter, r *http.Request) {
if err != nil {
merr := merrors.FromError(err)
if merr.Code == http.StatusNotFound {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found")))
o.mustRender(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found"))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
o.logger.Error().Err(err).Str("userid", userid).Msg("could not get list of user groups")
return
@@ -98,26 +97,31 @@ func (o Ocs) ListUserGroups(w http.ResponseWriter, r *http.Request) {
span.SetAttributes(attribute.StringSlice("groups", groups))
mustNotFail(render.Render(w, r, response.DataRender(&data.Groups{Groups: groups})))
o.mustRender(w, r, response.DataRender(&data.Groups{Groups: groups}))
}
// AddToGroup adds a user to a group
func (o Ocs) AddToGroup(w http.ResponseWriter, r *http.Request) {
mustNotFail(r.ParseForm())
err := r.ParseForm()
if err != nil {
o.mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "Could not parse form from request"))
return
}
userid := chi.URLParam(r, "userid")
groupid := r.PostForm.Get("groupid")
if groupid == "" {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "empty group assignment: unspecified group")))
o.mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "empty group assignment: unspecified group"))
return
}
account, err := o.fetchAccountByUsername(r.Context(), userid)
if err != nil {
merr := merrors.FromError(err)
if merr.Code == http.StatusNotFound {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found")))
o.mustRender(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found"))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
return
}
@@ -127,9 +131,9 @@ func (o Ocs) AddToGroup(w http.ResponseWriter, r *http.Request) {
if err != nil {
merr := merrors.FromError(err)
if merr.Code == http.StatusNotFound {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested group could not be found")))
o.mustRender(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested group could not be found"))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
return
}
@@ -142,16 +146,16 @@ func (o Ocs) AddToGroup(w http.ResponseWriter, r *http.Request) {
if err != nil {
merr := merrors.FromError(err)
if merr.Code == http.StatusNotFound {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested group could not be found")))
o.mustRender(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested group could not be found"))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
o.logger.Error().Err(err).Str("userid", account.Id).Str("groupid", group.Id).Msg("could not add user to group")
return
}
o.logger.Debug().Str("userid", account.Id).Str("groupid", group.Id).Msg("added user to group")
mustNotFail(render.Render(w, r, response.DataRender(struct{}{})))
o.mustRender(w, r, response.DataRender(struct{}{}))
}
// RemoveFromGroup removes a user from a group
@@ -165,23 +169,23 @@ func (o Ocs) RemoveFromGroup(w http.ResponseWriter, r *http.Request) {
// read it manually
body, err := ioutil.ReadAll(r.Body)
if err != nil {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, err.Error()))
return
}
if err = r.Body.Close(); err != nil {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
return
}
values, err := url.ParseQuery(string(body))
if err != nil {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, err.Error()))
return
}
groupid := values.Get("groupid")
if groupid == "" {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "no group id")))
o.mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "no group id"))
return
}
@@ -197,9 +201,9 @@ func (o Ocs) RemoveFromGroup(w http.ResponseWriter, r *http.Request) {
if err != nil {
merr := merrors.FromError(err)
if merr.Code == http.StatusNotFound {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, "The requested user could not be found")))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, "The requested user could not be found"))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
o.logger.Error().Err(err).Str("userid", userid).Msg("could not get list of user groups")
return
@@ -211,9 +215,9 @@ func (o Ocs) RemoveFromGroup(w http.ResponseWriter, r *http.Request) {
if err != nil {
merr := merrors.FromError(err)
if merr.Code == http.StatusNotFound {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested group could not be found")))
o.mustRender(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested group could not be found"))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
return
}
@@ -226,16 +230,16 @@ func (o Ocs) RemoveFromGroup(w http.ResponseWriter, r *http.Request) {
if err != nil {
merr := merrors.FromError(err)
if merr.Code == http.StatusNotFound {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested group could not be found")))
o.mustRender(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested group could not be found"))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
o.logger.Error().Err(err).Str("userid", account.Id).Str("groupid", group.Id).Msg("could not remove user from group")
return
}
o.logger.Debug().Str("userid", account.Id).Str("groupid", group.Id).Msg("removed user from group")
mustNotFail(render.Render(w, r, response.DataRender(struct{}{})))
o.mustRender(w, r, response.DataRender(struct{}{}))
}
// ListGroups lists all groups
@@ -252,7 +256,7 @@ func (o Ocs) ListGroups(w http.ResponseWriter, r *http.Request) {
if err != nil {
o.logger.Err(err).Msg("could not list users")
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, "could not list users")))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, "could not list users"))
return
}
@@ -268,7 +272,7 @@ func (o Ocs) ListGroups(w http.ResponseWriter, r *http.Request) {
span.SetAttributes(attribute.StringSlice("groups", groups))
mustNotFail(render.Render(w, r, response.DataRender(&data.Groups{Groups: groups})))
o.mustRender(w, r, response.DataRender(&data.Groups{Groups: groups}))
}
// AddGroup adds a group
@@ -283,7 +287,7 @@ func (o Ocs) AddGroup(w http.ResponseWriter, r *http.Request) {
if response.APIVersion(r.Context()) == "2" {
code = data.MetaBadRequest.StatusCode
}
render.Render(w, r, response.ErrRender(code, "No groupid or display name provided"))
o.mustRender(w, r, response.ErrRender(code, "No groupid or display name provided"))
return
}
@@ -299,7 +303,7 @@ func (o Ocs) AddGroup(w http.ResponseWriter, r *http.Request) {
if gid != "" {
gidNumber, err = strconv.ParseInt(gid, 10, 64)
if err != nil {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "Cannot use the gidnumber provided")))
o.mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "Cannot use the gidnumber provided"))
o.logger.Error().Err(err).Str("gid", gid).Str("groupid", groupid).Msg("Cannot use the gidnumber provided")
return
}
@@ -318,17 +322,17 @@ func (o Ocs) AddGroup(w http.ResponseWriter, r *http.Request) {
merr := merrors.FromError(err)
switch merr.Code {
case http.StatusBadRequest:
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, merr.Detail)))
o.mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, merr.Detail))
case http.StatusConflict:
if response.APIVersion(r.Context()) == "2" {
// it seems the application framework sets the ocs status code to the httpstatus code, which affects the provisioning api
// see https://github.com/owncloud/core/blob/b9ff4c93e051c94adfb301545098ae627e52ef76/lib/public/AppFramework/OCSController.php#L142-L150
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, merr.Detail)))
o.mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, merr.Detail))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaInvalidInput.StatusCode, merr.Detail)))
o.mustRender(w, r, response.ErrRender(data.MetaInvalidInput.StatusCode, merr.Detail))
}
default:
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
o.logger.Error().Err(err).Str("groupid", groupid).Msg("could not add group")
// TODO check error if group already existed
@@ -336,7 +340,7 @@ func (o Ocs) AddGroup(w http.ResponseWriter, r *http.Request) {
}
o.logger.Debug().Interface("group", group).Msg("added group")
mustNotFail(render.Render(w, r, response.DataRender(struct{}{})))
o.mustRender(w, r, response.DataRender(struct{}{}))
}
// DeleteGroup deletes a group
@@ -348,9 +352,9 @@ func (o Ocs) DeleteGroup(w http.ResponseWriter, r *http.Request) {
if err != nil {
merr := merrors.FromError(err)
if merr.Code == http.StatusNotFound {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested group could not be found")))
o.mustRender(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested group could not be found"))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
return
}
@@ -362,16 +366,16 @@ func (o Ocs) DeleteGroup(w http.ResponseWriter, r *http.Request) {
if err != nil {
merr := merrors.FromError(err)
if merr.Code == http.StatusNotFound {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested group could not be found")))
o.mustRender(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested group could not be found"))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
o.logger.Error().Err(err).Str("groupid", group.Id).Msg("could not remove group")
return
}
o.logger.Debug().Str("groupid", group.Id).Msg("removed group")
mustNotFail(render.Render(w, r, response.DataRender(struct{}{})))
o.mustRender(w, r, response.DataRender(struct{}{}))
}
// GetGroupMembers lists all members of a group
@@ -384,9 +388,9 @@ func (o Ocs) GetGroupMembers(w http.ResponseWriter, r *http.Request) {
if err != nil {
merr := merrors.FromError(err)
if merr.Code == http.StatusNotFound {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested group could not be found")))
o.mustRender(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested group could not be found"))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
return
}
@@ -396,9 +400,9 @@ func (o Ocs) GetGroupMembers(w http.ResponseWriter, r *http.Request) {
if err != nil {
merr := merrors.FromError(err)
if merr.Code == http.StatusNotFound {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested group could not be found")))
o.mustRender(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested group could not be found"))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
o.logger.Error().Err(err).Str("groupid", group.Id).Msg("could not get list of members")
return
@@ -410,7 +414,7 @@ func (o Ocs) GetGroupMembers(w http.ResponseWriter, r *http.Request) {
}
o.logger.Error().Err(err).Int("count", len(members)).Str("groupid", groupid).Msg("listing group members")
mustNotFail(render.Render(w, r, response.DataRender(&data.Users{Users: members})))
o.mustRender(w, r, response.DataRender(&data.Users{Users: members}))
}
func isValidUUID(uuid string) bool {
@@ -431,9 +435,3 @@ func (o Ocs) fetchGroupByName(ctx context.Context, name string) (*accounts.Group
}
return nil, merrors.NotFound("", "The requested group could not be found")
}
func mustNotFail(err error) {
if err != nil {
panic(err)
}
}
+1 -7
View File
@@ -80,7 +80,7 @@ func VersionCtx(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
version := chi.URLParam(r, "version")
if version == "" {
mustNotFail(render.Render(w, r, ErrRender(data.MetaBadRequest.StatusCode, "unknown ocs api version")))
_ = render.Render(w, r, ErrRender(data.MetaBadRequest.StatusCode, "unknown ocs api version"))
return
}
w.Header().Set("Ocs-Api-Version", version)
@@ -90,9 +90,3 @@ func VersionCtx(next http.Handler) http.Handler {
next.ServeHTTP(w, r.WithContext(ctx))
})
}
func mustNotFail(err error) {
if err != nil {
panic(err)
}
}
+11 -3
View File
@@ -63,7 +63,9 @@ func NewService(opts ...Option) Service {
svc.config.AccountBackend = "accounts"
}
requireUser := ocsm.RequireUser()
requireUser := ocsm.RequireUser(
ocsm.Logger(options.Logger),
)
requireAdmin := ocsm.RequireAdmin(
ocsm.RoleManager(roleManager),
@@ -153,7 +155,7 @@ func (o Ocs) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// NotFound uses ErrRender to always return a proper OCS payload
func (o Ocs) NotFound(w http.ResponseWriter, r *http.Request) {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "not found")))
o.mustRender(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "not found"))
}
func (o Ocs) getAccountService() accounts.AccountsService {
@@ -174,5 +176,11 @@ func (o Ocs) getGroupsService() accounts.GroupsService {
// NotImplementedStub returns a not implemented error
func (o Ocs) NotImplementedStub(w http.ResponseWriter, r *http.Request) {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaUnknownError.StatusCode, "Not implemented")))
o.mustRender(w, r, response.ErrRender(data.MetaUnknownError.StatusCode, "Not implemented"))
}
func (o Ocs) mustRender(w http.ResponseWriter, r *http.Request, renderer render.Renderer) {
if err := render.Render(w, r, renderer); err != nil {
o.logger.Err(err).Msgf("failed to write response for ocs request %s on %s", r.Method, r.URL)
}
}
+52 -53
View File
@@ -18,7 +18,6 @@ import (
"github.com/cs3org/reva/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/pkg/token/manager/jwt"
"github.com/go-chi/chi/v5"
"github.com/go-chi/render"
accounts "github.com/owncloud/ocis/accounts/pkg/proto/v0"
"github.com/owncloud/ocis/ocs/pkg/service/v0/data"
"github.com/owncloud/ocis/ocs/pkg/service/v0/response"
@@ -37,7 +36,7 @@ func (o Ocs) GetSelf(w http.ResponseWriter, r *http.Request) {
var err error
u, ok := revactx.ContextGetUser(r.Context())
if !ok || u.Id == nil || u.Id.OpaqueId == "" {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "user is missing an id")))
o.mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "user is missing an id"))
return
}
@@ -58,7 +57,7 @@ func (o Ocs) GetSelf(w http.ResponseWriter, r *http.Request) {
UIDNumber: u.UidNumber,
GIDNumber: u.GidNumber,
}
mustNotFail(render.Render(w, r, response.DataRender(d)))
o.mustRender(w, r, response.DataRender(d))
return
}
o.logger.Error().Err(merr).Interface("user", u).Msg("could not get account for user")
@@ -80,7 +79,7 @@ func (o Ocs) GetSelf(w http.ResponseWriter, r *http.Request) {
GIDNumber: account.GidNumber,
// TODO hide enabled flag or it might get rendered as false
}
mustNotFail(render.Render(w, r, response.DataRender(d)))
o.mustRender(w, r, response.DataRender(d))
}
// GetUser returns the user with the given userid
@@ -91,7 +90,7 @@ func (o Ocs) GetUser(w http.ResponseWriter, r *http.Request) {
switch {
case userid == "":
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "missing user in context")))
o.mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "missing user in context"))
case o.config.AccountBackend == "accounts":
account, err = o.fetchAccountByUsername(r.Context(), userid)
case o.config.AccountBackend == "cs3":
@@ -103,9 +102,9 @@ func (o Ocs) GetUser(w http.ResponseWriter, r *http.Request) {
if err != nil {
merr := merrors.FromError(err)
if merr.Code == http.StatusNotFound {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found")))
o.mustRender(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found"))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
o.logger.Error().Err(merr).Str("userid", userid).Msg("could not get account for user")
return
@@ -148,7 +147,7 @@ func (o Ocs) GetUser(w http.ResponseWriter, r *http.Request) {
Start(r.Context(), "GetUser")
defer span.End()
mustNotFail(render.Render(w, r, response.DataRender(d)))
o.mustRender(w, r, response.DataRender(d))
}
// AddUser creates a new user account
@@ -166,7 +165,7 @@ func (o Ocs) AddUser(w http.ResponseWriter, r *http.Request) {
if uid != "" {
uidNumber, err = strconv.ParseInt(uid, 10, 64)
if err != nil {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "Cannot use the uidnumber provided")))
o.mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "Cannot use the uidnumber provided"))
o.logger.Error().Err(err).Str("userid", userid).Msg("Cannot use the uidnumber provided")
return
}
@@ -174,13 +173,13 @@ func (o Ocs) AddUser(w http.ResponseWriter, r *http.Request) {
if gid != "" {
gidNumber, err = strconv.ParseInt(gid, 10, 64)
if err != nil {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "Cannot use the gidnumber provided")))
o.mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "Cannot use the gidnumber provided"))
o.logger.Error().Err(err).Str("userid", userid).Msg("Cannot use the gidnumber provided")
return
}
}
if strings.TrimSpace(password) == "" {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "empty password not allowed")))
o.mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "empty password not allowed"))
o.logger.Error().Str("userid", userid).Msg("empty password not allowed")
return
}
@@ -230,17 +229,17 @@ func (o Ocs) AddUser(w http.ResponseWriter, r *http.Request) {
merr := merrors.FromError(err)
switch merr.Code {
case http.StatusBadRequest:
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, merr.Detail)))
o.mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, merr.Detail))
case http.StatusConflict:
if response.APIVersion(r.Context()) == "2" {
// it seems the application framework sets the ocs status code to the httpstatus code, which affects the provisioning api
// see https://github.com/owncloud/core/blob/b9ff4c93e051c94adfb301545098ae627e52ef76/lib/public/AppFramework/OCSController.php#L142-L150
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, merr.Detail)))
o.mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, merr.Detail))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaInvalidInput.StatusCode, merr.Detail)))
o.mustRender(w, r, response.ErrRender(data.MetaInvalidInput.StatusCode, merr.Detail))
}
default:
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
o.logger.Error().Err(err).Str("userid", userid).Msg("could not add user")
// TODO check error if account already existed
@@ -260,7 +259,7 @@ func (o Ocs) AddUser(w http.ResponseWriter, r *http.Request) {
} else {
enabled = "false"
}
mustNotFail(render.Render(w, r, response.DataRender(&data.User{
o.mustRender(w, r, response.DataRender(&data.User{
UserID: account.OnPremisesSamAccountName,
DisplayName: account.DisplayName,
LegacyDisplayName: account.DisplayName,
@@ -268,7 +267,7 @@ func (o Ocs) AddUser(w http.ResponseWriter, r *http.Request) {
UIDNumber: account.UidNumber,
GIDNumber: account.GidNumber,
Enabled: enabled,
})))
}))
}
// EditUser creates a new user account
@@ -289,9 +288,9 @@ func (o Ocs) EditUser(w http.ResponseWriter, r *http.Request) {
if err != nil {
merr := merrors.FromError(err)
if merr.Code == http.StatusNotFound {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found")))
o.mustRender(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found"))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
o.logger.Error().Err(err).Str("userid", userid).Msg("could not edit user")
return
@@ -323,7 +322,7 @@ func (o Ocs) EditUser(w http.ResponseWriter, r *http.Request) {
req.UpdateMask = &fieldmaskpb.FieldMask{Paths: []string{"DisplayName"}}
default:
// https://github.com/owncloud/core/blob/24b7fa1d2604a208582055309a5638dbd9bda1d1/apps/provisioning_api/lib/Users.php#L321
mustNotFail(render.Render(w, r, response.ErrRender(103, "unknown key '"+key+"'")))
o.mustRender(w, r, response.ErrRender(103, "unknown key '"+key+"'"))
return
}
@@ -332,9 +331,9 @@ func (o Ocs) EditUser(w http.ResponseWriter, r *http.Request) {
merr := merrors.FromError(err)
switch merr.Code {
case http.StatusBadRequest:
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, merr.Detail)))
o.mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, merr.Detail))
default:
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
o.logger.Error().Err(err).Str("account_id", req.Account.Id).Str("user_id", userid).Msg("could not edit user")
return
@@ -346,7 +345,7 @@ func (o Ocs) EditUser(w http.ResponseWriter, r *http.Request) {
}
o.logger.Debug().Interface("account", account).Msg("updated user")
mustNotFail(render.Render(w, r, response.DataRender(struct{}{})))
o.mustRender(w, r, response.DataRender(struct{}{}))
}
// DeleteUser deletes a user
@@ -367,9 +366,9 @@ func (o Ocs) DeleteUser(w http.ResponseWriter, r *http.Request) {
if err != nil {
merr := merrors.FromError(err)
if merr.Code == http.StatusNotFound {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found")))
o.mustRender(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found"))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
o.logger.Error().Err(err).Str("userid", userid).Msg("could not delete user")
return
@@ -378,7 +377,7 @@ func (o Ocs) DeleteUser(w http.ResponseWriter, r *http.Request) {
if o.config.Reva.Address != "" && o.config.StorageUsersDriver != "owncloud" {
t, err := o.mintTokenForUser(r.Context(), account)
if err != nil {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "error minting token").Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "error minting token").Error()))
return
}
@@ -391,7 +390,7 @@ func (o Ocs) DeleteUser(w http.ResponseWriter, r *http.Request) {
homeResp, err := gwc.GetHome(ctx, &provider.GetHomeRequest{})
if err != nil {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "could not get home").Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "could not get home").Error()))
return
}
@@ -410,7 +409,7 @@ func (o Ocs) DeleteUser(w http.ResponseWriter, r *http.Request) {
})
if err != nil {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "could not stat home").Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "could not stat home").Error()))
return
}
@@ -430,7 +429,7 @@ func (o Ocs) DeleteUser(w http.ResponseWriter, r *http.Request) {
delResp, err := gwc.Delete(ctx, delReq)
if err != nil {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "could not delete home").Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "could not delete home").Error()))
return
}
@@ -450,7 +449,7 @@ func (o Ocs) DeleteUser(w http.ResponseWriter, r *http.Request) {
purgeRecycleResponse, err := gwc.PurgeRecycle(ctx, req)
if err != nil {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "could not delete trash").Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "could not delete trash").Error()))
return
}
@@ -471,16 +470,16 @@ func (o Ocs) DeleteUser(w http.ResponseWriter, r *http.Request) {
if err != nil {
merr := merrors.FromError(err)
if merr.Code == http.StatusNotFound {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found")))
o.mustRender(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found"))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
o.logger.Error().Err(err).Str("userid", req.Id).Msg("could not delete user")
return
}
o.logger.Debug().Str("userid", req.Id).Msg("deleted user")
mustNotFail(render.Render(w, r, response.DataRender(struct{}{})))
o.mustRender(w, r, response.DataRender(struct{}{}))
}
// TODO(refs) this to ocis-pkg ... we are minting tokens all over the place ... or use a service? ... like reva?
@@ -524,9 +523,9 @@ func (o Ocs) EnableUser(w http.ResponseWriter, r *http.Request) {
if err != nil {
merr := merrors.FromError(err)
if merr.Code == http.StatusNotFound {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found")))
o.mustRender(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found"))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
o.logger.Error().Err(err).Str("userid", userid).Msg("could not enable user")
return
@@ -545,16 +544,16 @@ func (o Ocs) EnableUser(w http.ResponseWriter, r *http.Request) {
if err != nil {
merr := merrors.FromError(err)
if merr.Code == http.StatusNotFound {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested account could not be found")))
o.mustRender(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested account could not be found"))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
o.logger.Error().Err(err).Str("account_id", account.Id).Msg("could not enable account")
return
}
o.logger.Debug().Str("account_id", account.Id).Msg("enabled user")
mustNotFail(render.Render(w, r, response.DataRender(struct{}{})))
o.mustRender(w, r, response.DataRender(struct{}{}))
}
// DisableUser disables a user
@@ -575,9 +574,9 @@ func (o Ocs) DisableUser(w http.ResponseWriter, r *http.Request) {
if err != nil {
merr := merrors.FromError(err)
if merr.Code == http.StatusNotFound {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found")))
o.mustRender(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found"))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
o.logger.Error().Err(err).Str("userid", userid).Msg("could not disable user")
return
@@ -596,16 +595,16 @@ func (o Ocs) DisableUser(w http.ResponseWriter, r *http.Request) {
if err != nil {
merr := merrors.FromError(err)
if merr.Code == http.StatusNotFound {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested account could not be found")))
o.mustRender(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested account could not be found"))
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
}
o.logger.Error().Err(err).Str("account_id", account.Id).Msg("could not disable account")
return
}
o.logger.Debug().Str("account_id", account.Id).Msg("disabled user")
mustNotFail(render.Render(w, r, response.DataRender(struct{}{})))
o.mustRender(w, r, response.DataRender(struct{}{}))
}
// GetSigningKey returns the signing key for the current user. It will create it on the fly if it does not exist
@@ -615,7 +614,7 @@ func (o Ocs) GetSigningKey(w http.ResponseWriter, r *http.Request) {
u, ok := revactx.ContextGetUser(r.Context())
if !ok {
//o.logger.Error().Msg("missing user in context")
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "missing user in context")))
o.mustRender(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "missing user in context"))
return
}
@@ -631,10 +630,10 @@ func (o Ocs) GetSigningKey(w http.ResponseWriter, r *http.Request) {
Key: userID,
})
if err == nil && len(res.Records) > 0 {
mustNotFail(render.Render(w, r, response.DataRender(&data.SigningKey{
o.mustRender(w, r, response.DataRender(&data.SigningKey{
User: userID,
SigningKey: string(res.Records[0].Value),
})))
}))
return
}
if err != nil {
@@ -642,7 +641,7 @@ func (o Ocs) GetSigningKey(w http.ResponseWriter, r *http.Request) {
if e.Code == http.StatusNotFound {
// not found is ok, so we can continue and generate the key on the fly
} else {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, "error reading from store")))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, "error reading from store"))
return
}
}
@@ -651,7 +650,7 @@ func (o Ocs) GetSigningKey(w http.ResponseWriter, r *http.Request) {
key := make([]byte, 64)
_, err = rand.Read(key[:])
if err != nil {
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, "could not generate signing key")))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, "could not generate signing key"))
return
}
signingKey := hex.EncodeToString(key)
@@ -670,14 +669,14 @@ func (o Ocs) GetSigningKey(w http.ResponseWriter, r *http.Request) {
if err != nil {
//o.logger.Error().Err(err).Msg("error writing key")
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, "could not persist signing key")))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, "could not persist signing key"))
return
}
mustNotFail(render.Render(w, r, response.DataRender(&data.SigningKey{
o.mustRender(w, r, response.DataRender(&data.SigningKey{
User: userID,
SigningKey: signingKey,
})))
}))
}
// ListUsers lists the users
@@ -704,7 +703,7 @@ func (o Ocs) ListUsers(w http.ResponseWriter, r *http.Request) {
if err != nil {
o.logger.Err(err).Msg("could not list users")
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, "could not list users")))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, "could not list users"))
return
}
@@ -713,7 +712,7 @@ func (o Ocs) ListUsers(w http.ResponseWriter, r *http.Request) {
users = append(users, res.Accounts[i].OnPremisesSamAccountName)
}
mustNotFail(render.Render(w, r, response.DataRender(&data.Users{Users: users})))
o.mustRender(w, r, response.DataRender(&data.Users{Users: users}))
}
// escapeValue escapes all special characters in the value