mirror of
https://github.com/mainflux/mainflux.git
synced 2025-04-27 13:48:49 +08:00

* update error encoding Signed-off-by: ianmuchyri <ianmuchiri8@gmail.com> * fix semaphore fail Signed-off-by: ianmuchyri <ianmuchiri8@gmail.com> * update encode error Signed-off-by: ianmuchyri <ianmuchiri8@gmail.com> * update bootstraptests Signed-off-by: ianmuchyri <ianmuchiri8@gmail.com> * Update notifiers endpoint_test Signed-off-by: ianmuchyri <ianmuchiri8@gmail.com> * Update tokens_test Signed-off-by: ianmuchyri <ianmuchiri8@gmail.com> * Update json.unmarshal into expected struct Signed-off-by: ianmuchyri <ianmuchiri8@gmail.com> * update .env Signed-off-by: ianmuchyri <ianmuchiri8@gmail.com> * update sdk_error to check if err is empty Signed-off-by: ianmuchyri <ianmuchiri8@gmail.com> * update message_test Signed-off-by: ianmuchyri <ianmuchiri8@gmail.com> * Update error marshaling Signed-off-by: ianmuchyri <ianmuchiri8@gmail.com> * update tests Signed-off-by: ianmuchyri <ianmuchiri8@gmail.com> * Redo makefile Signed-off-by: ianmuchyri <ianmuchiri8@gmail.com> * Add fullstop to comments Signed-off-by: ianmuchyri <ianmuchiri8@gmail.com> * Update rebase error Signed-off-by: ianmuchyri <ianmuchiri8@gmail.com> --------- Signed-off-by: ianmuchyri <ianmuchiri8@gmail.com>
137 lines
3.8 KiB
Go
137 lines
3.8 KiB
Go
// Copyright (c) Mainflux
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package api
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
|
|
"github.com/gofrs/uuid"
|
|
"github.com/mainflux/mainflux"
|
|
"github.com/mainflux/mainflux/internal/apiutil"
|
|
"github.com/mainflux/mainflux/internal/postgres"
|
|
mfclients "github.com/mainflux/mainflux/pkg/clients"
|
|
"github.com/mainflux/mainflux/pkg/errors"
|
|
)
|
|
|
|
const (
|
|
StatusKey = "status"
|
|
OffsetKey = "offset"
|
|
LimitKey = "limit"
|
|
MetadataKey = "metadata"
|
|
ParentKey = "parent_id"
|
|
OwnerKey = "owner_id"
|
|
ClientKey = "client"
|
|
IdentityKey = "identity"
|
|
GroupKey = "group"
|
|
ActionKey = "action"
|
|
TagKey = "tag"
|
|
NameKey = "name"
|
|
TotalKey = "total"
|
|
SubjectKey = "subject"
|
|
ObjectKey = "object"
|
|
LevelKey = "level"
|
|
TreeKey = "tree"
|
|
DirKey = "dir"
|
|
VisibilityKey = "visibility"
|
|
SharedByKey = "shared_by"
|
|
TokenKey = "token"
|
|
DefTotal = uint64(100)
|
|
DefOffset = 0
|
|
DefLimit = 10
|
|
DefLevel = 0
|
|
DefStatus = "enabled"
|
|
DefClientStatus = mfclients.Enabled
|
|
DefGroupStatus = mfclients.Enabled
|
|
SharedVisibility = "shared"
|
|
MyVisibility = "mine"
|
|
AllVisibility = "all"
|
|
// ContentType represents JSON content type.
|
|
ContentType = "application/json"
|
|
|
|
// MaxNameSize limits name size to prevent making them too complex.
|
|
MaxLimitSize = 100
|
|
MaxNameSize = 1024
|
|
NameOrder = "name"
|
|
IDOrder = "id"
|
|
AscDir = "asc"
|
|
DescDir = "desc"
|
|
)
|
|
|
|
// ValidateUUID validates UUID format.
|
|
func ValidateUUID(extID string) (err error) {
|
|
id, err := uuid.FromString(extID)
|
|
if id.String() != extID || err != nil {
|
|
return apiutil.ErrInvalidIDFormat
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// EncodeResponse encodes successful response.
|
|
func EncodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
|
|
if ar, ok := response.(mainflux.Response); ok {
|
|
for k, v := range ar.Headers() {
|
|
w.Header().Set(k, v)
|
|
}
|
|
w.Header().Set("Content-Type", ContentType)
|
|
w.WriteHeader(ar.Code())
|
|
|
|
if ar.Empty() {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
return json.NewEncoder(w).Encode(response)
|
|
}
|
|
|
|
// EncodeError encodes an error response.
|
|
func EncodeError(_ context.Context, err error, w http.ResponseWriter) {
|
|
var wrapper error
|
|
if errors.Contains(err, apiutil.ErrValidation) {
|
|
wrapper, err = errors.Unwrap(err)
|
|
}
|
|
|
|
w.Header().Set("Content-Type", ContentType)
|
|
switch {
|
|
case errors.Contains(err, apiutil.ErrInvalidSecret),
|
|
errors.Contains(err, errors.ErrMalformedEntity),
|
|
errors.Contains(err, apiutil.ErrMissingID),
|
|
errors.Contains(err, apiutil.ErrEmptyList),
|
|
errors.Contains(err, apiutil.ErrMissingMemberType),
|
|
errors.Contains(err, apiutil.ErrNameSize):
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
case errors.Contains(err, errors.ErrAuthentication):
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
case errors.Contains(err, errors.ErrNotFound):
|
|
w.WriteHeader(http.StatusNotFound)
|
|
case errors.Contains(err, errors.ErrConflict):
|
|
w.WriteHeader(http.StatusConflict)
|
|
case errors.Contains(err, errors.ErrAuthorization):
|
|
w.WriteHeader(http.StatusForbidden)
|
|
case errors.Contains(err, postgres.ErrMemberAlreadyAssigned):
|
|
w.WriteHeader(http.StatusConflict)
|
|
case errors.Contains(err, apiutil.ErrUnsupportedContentType):
|
|
w.WriteHeader(http.StatusUnsupportedMediaType)
|
|
case errors.Contains(err, errors.ErrCreateEntity),
|
|
errors.Contains(err, errors.ErrUpdateEntity),
|
|
errors.Contains(err, errors.ErrViewEntity),
|
|
errors.Contains(err, errors.ErrRemoveEntity):
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
default:
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
}
|
|
|
|
if wrapper != nil {
|
|
err = errors.Wrap(wrapper, err)
|
|
}
|
|
|
|
if errorVal, ok := err.(errors.Error); ok {
|
|
if err := json.NewEncoder(w).Encode(errorVal); err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
}
|
|
}
|
|
}
|