MG-2117 - Remove repository errors from API layer (#2119)

Signed-off-by: WashingtonKK <washingtonkigan@gmail.com>
This commit is contained in:
Washington Kigani Kamadi
2024-05-10 16:09:21 +03:00
committed by GitHub
parent 551d5cf4ca
commit 75db28c522
27 changed files with 646 additions and 440 deletions
+4
View File
@@ -152,8 +152,12 @@ paths:
responses:
"200":
$ref: "#/components/responses/DomainPermissionRes"
"400":
description: Malformed entity specification.
"401":
description: Missing or invalid access token provided.
"403":
description: Failed authorization over the domain.
"404":
description: A non-existent entity request.
"422":
+2
View File
@@ -96,6 +96,8 @@ paths:
responses:
"200":
$ref: "#/components/responses/ConfigRes"
"400":
description: Missing or invalid config.
"401":
description: Missing or invalid access token provided.
"404":
+4
View File
@@ -419,6 +419,8 @@ paths:
description: Failed due to malformed JSON.
"401":
description: Missing or invalid access token provided.
"404":
description: Entity not found.
"415":
description: Missing or invalid content type.
"422":
@@ -517,6 +519,8 @@ paths:
$ref: "#/components/responses/TokenRes"
"400":
description: Failed due to malformed JSON.
"401":
description: Missing or invalid access token provided.
"404":
description: A non-existent entity request.
"415":
+6 -6
View File
@@ -307,21 +307,21 @@ func TestListDomains(t *testing.T) {
err: nil,
},
{
desc: "list domains with empty name",
desc: "list domains with empty name",
token: validToken,
query: "name= ",
status: http.StatusBadRequest,
err: apiutil.ErrValidation,
},
{
desc: "list domains with duplicate name",
desc: "list domains with duplicate name",
token: validToken,
query: "name=1&name=2",
status: http.StatusBadRequest,
err: apiutil.ErrInvalidQueryParams,
},
{
desc: "list domains with status",
desc: "list domains with status",
token: validToken,
listDomainsRequest: auth.DomainsPage{
Total: 1,
@@ -332,7 +332,7 @@ func TestListDomains(t *testing.T) {
err: nil,
},
{
desc: "list domains with invalid status",
desc: "list domains with invalid status",
token: validToken,
query: "status=invalid",
status: http.StatusBadRequest,
@@ -1047,7 +1047,7 @@ func TestAssignDomainUsers(t *testing.T) {
contentType: contentType,
token: validToken,
status: http.StatusBadRequest,
err: apiutil.ErrValidation,
err: apiutil.ErrMissingID,
},
{
desc: "assign domain users with empty relation",
@@ -1056,7 +1056,7 @@ func TestAssignDomainUsers(t *testing.T) {
contentType: contentType,
token: validToken,
status: http.StatusBadRequest,
err: apiutil.ErrValidation,
err: apiutil.ErrMalformedPolicy,
},
}
+1 -1
View File
@@ -239,7 +239,7 @@ func TestRetrieve(t *testing.T) {
desc: "retrieve a non-existing key",
id: "non-existing",
token: token.AccessToken,
status: http.StatusNotFound,
status: http.StatusBadRequest,
err: svcerr.ErrNotFound,
},
{
+18 -8
View File
@@ -139,7 +139,7 @@ func (svc service) Identify(ctx context.Context, token string) (Key, error) {
key, err := svc.tokenizer.Parse(token)
if errors.Contains(err, ErrExpiry) {
err = svc.keys.Remove(ctx, key.Issuer, key.ID)
return Key{}, errors.Wrap(ErrKeyExpired, err)
return Key{}, errors.Wrap(svcerr.ErrAuthentication, errors.Wrap(ErrKeyExpired, err))
}
if err != nil {
return Key{}, errors.Wrap(svcerr.ErrAuthentication, errors.Wrap(errIdentify, err))
@@ -204,6 +204,16 @@ func (svc service) checkPolicy(ctx context.Context, pr PolicyReq) error {
}
func (svc service) checkDomain(ctx context.Context, subjectType, subject, domainID string) error {
if err := svc.agent.CheckPolicy(ctx, PolicyReq{
Subject: subject,
SubjectType: subjectType,
Permission: MembershipPermission,
Object: domainID,
ObjectType: DomainType,
}); err != nil {
return svcerr.ErrDomainAuthorization
}
d, err := svc.domains.RetrieveByID(ctx, domainID)
if err != nil {
return errors.Wrap(svcerr.ErrViewEntity, err)
@@ -531,7 +541,7 @@ func (svc service) CreateDomain(ctx context.Context, token string, d Domain) (do
domainID, err := svc.idProvider.ID()
if err != nil {
return Domain{}, err
return Domain{}, errors.Wrap(svcerr.ErrCreateEntity, err)
}
d.ID = domainID
@@ -580,7 +590,7 @@ func (svc service) RetrieveDomain(ctx context.Context, token, id string) (Domain
func (svc service) RetrieveDomainPermissions(ctx context.Context, token, id string) (Permissions, error) {
res, err := svc.Identify(ctx, token)
if err != nil {
return []string{}, errors.Wrap(svcerr.ErrAuthentication, err)
return []string{}, err
}
if err := svc.Authorize(ctx, PolicyReq{
@@ -591,7 +601,7 @@ func (svc service) RetrieveDomainPermissions(ctx context.Context, token, id stri
ObjectType: DomainType,
Permission: MembershipPermission,
}); err != nil {
return []string{}, errors.Wrap(svcerr.ErrAuthorization, err)
return []string{}, err
}
lp, err := svc.ListPermissions(ctx, PolicyReq{
@@ -609,7 +619,7 @@ func (svc service) RetrieveDomainPermissions(ctx context.Context, token, id stri
func (svc service) UpdateDomain(ctx context.Context, token, id string, d DomainReq) (Domain, error) {
key, err := svc.Identify(ctx, token)
if err != nil {
return Domain{}, errors.Wrap(svcerr.ErrAuthentication, err)
return Domain{}, err
}
if err := svc.Authorize(ctx, PolicyReq{
Subject: key.Subject,
@@ -619,7 +629,7 @@ func (svc service) UpdateDomain(ctx context.Context, token, id string, d DomainR
ObjectType: DomainType,
Permission: EditPermission,
}); err != nil {
return Domain{}, errors.Wrap(svcerr.ErrAuthorization, err)
return Domain{}, err
}
dom, err := svc.domains.Update(ctx, id, key.User, d)
@@ -642,7 +652,7 @@ func (svc service) ChangeDomainStatus(ctx context.Context, token, id string, d D
ObjectType: DomainType,
Permission: AdminPermission,
}); err != nil {
return Domain{}, errors.Wrap(svcerr.ErrAuthorization, err)
return Domain{}, err
}
dom, err := svc.domains.Update(ctx, id, key.User, d)
@@ -765,7 +775,7 @@ func (svc service) UnassignUsers(ctx context.Context, token, id string, userIds
for _, rel := range []string{MemberRelation, ViewerRelation, EditorRelation} {
// Remove only non-admins.
if err := svc.removeDomainPolicies(ctx, id, rel, userIds...); err != nil {
return errors.Wrap(errRemovePolicies, err)
return err
}
}
+365 -216
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -88,9 +88,9 @@ var (
missingIDRes = toJSON(apiutil.ErrorRes{Err: apiutil.ErrMissingID.Error(), Msg: apiutil.ErrValidation.Error()})
missingKeyRes = toJSON(apiutil.ErrorRes{Err: apiutil.ErrBearerKey.Error(), Msg: apiutil.ErrValidation.Error()})
bsErrorRes = toJSON(apiutil.ErrorRes{Err: svcerr.ErrNotFound.Error(), Msg: bootstrap.ErrBootstrap.Error()})
bsErrorRes = toJSON(apiutil.ErrorRes{Msg: bootstrap.ErrBootstrap.Error()})
extKeyRes = toJSON(apiutil.ErrorRes{Msg: bootstrap.ErrExternalKey.Error()})
extSecKeyRes = toJSON(apiutil.ErrorRes{Err: "encoding/hex: invalid byte: U+002D '-'", Msg: bootstrap.ErrExternalKeySecure.Error()})
extSecKeyRes = toJSON(apiutil.ErrorRes{Msg: bootstrap.ErrExternalKeySecure.Error()})
)
type testRequest struct {
@@ -1138,7 +1138,7 @@ func TestBootstrap(t *testing.T) {
status: http.StatusNotFound,
res: bsErrorRes,
secure: false,
err: errors.Wrap(bootstrap.ErrBootstrap, svcerr.ErrNotFound),
err: bootstrap.ErrBootstrap,
},
{
desc: "bootstrap a Thing with an empty ID",
@@ -1192,7 +1192,7 @@ func TestBootstrap(t *testing.T) {
status: http.StatusForbidden,
res: extSecKeyRes,
secure: true,
err: errors.Wrap(bootstrap.ErrExternalKeySecure, errors.New("encoding/hex: invalid byte: U+002D '-'")),
err: bootstrap.ErrExternalKeySecure,
},
}
+5 -3
View File
@@ -31,7 +31,9 @@ var (
// ErrBootstrap indicates error in getting bootstrap configuration.
ErrBootstrap = errors.New("failed to read bootstrap configuration")
errAddBootstrap = errors.New("failed to add bootstrap configuration")
// ErrAddBootstrap indicates error in adding bootstrap configuration.
ErrAddBootstrap = errors.New("failed to add bootstrap configuration")
errUpdateConnections = errors.New("failed to update connections")
errRemoveBootstrap = errors.New("failed to remove bootstrap configuration")
errChangeState = errors.New("failed to change state of bootstrap configuration")
@@ -164,7 +166,7 @@ func (bs bootstrapService) Add(ctx context.Context, token string, cfg Config) (C
err = errors.Wrap(err, errT)
}
}
return Config{}, errors.Wrap(errAddBootstrap, err)
return Config{}, errors.Wrap(ErrAddBootstrap, err)
}
cfg.ThingID = saved
@@ -400,7 +402,7 @@ func (bs bootstrapService) thing(id, token string) (mgsdk.Thing, error) {
}
thing, sdkErr := bs.sdk.CreateThing(mgsdk.Thing{ID: id, Name: "Bootstrapped Thing " + id}, token)
if sdkErr != nil {
return mgsdk.Thing{}, errors.Wrap(errCreateThing, errors.New(sdkErr.Err().Msg()))
return mgsdk.Thing{}, errors.Wrap(errCreateThing, sdkErr)
}
return thing, nil
}
+2 -3
View File
@@ -10,7 +10,6 @@ import (
"github.com/absmach/magistrala"
"github.com/absmach/magistrala/certs/pki"
"github.com/absmach/magistrala/pkg/errors"
repoerr "github.com/absmach/magistrala/pkg/errors/repository"
svcerr "github.com/absmach/magistrala/pkg/errors/service"
mgsdk "github.com/absmach/magistrala/pkg/sdk/go"
)
@@ -156,7 +155,7 @@ func (cs *certsService) ListCerts(ctx context.Context, token, thingID string, of
cp, err := cs.certsRepo.RetrieveByThing(ctx, u.GetId(), thingID, offset, limit)
if err != nil {
return Page{}, errors.Wrap(repoerr.ErrNotFound, err)
return Page{}, errors.Wrap(svcerr.ErrViewEntity, err)
}
for i, cert := range cp.Certs {
@@ -188,7 +187,7 @@ func (cs *certsService) ViewCert(ctx context.Context, token, serialID string) (C
cert, err := cs.certsRepo.RetrieveBySerial(ctx, u.GetId(), serialID)
if err != nil {
return Cert{}, errors.Wrap(repoerr.ErrNotFound, err)
return Cert{}, errors.Wrap(svcerr.ErrViewEntity, err)
}
vcert, err := cs.pki.Read(serialID)
+71 -52
View File
@@ -106,66 +106,77 @@ func EncodeError(_ context.Context, err error, w http.ResponseWriter) {
w.Header().Set("Content-Type", ContentType)
switch {
case errors.Contains(err, svcerr.ErrMalformedEntity),
errors.Contains(err, errors.ErrMalformedEntity),
errors.Contains(err, apiutil.ErrMissingID),
errors.Contains(err, apiutil.ErrEmptyList),
errors.Contains(err, apiutil.ErrMissingMemberType),
errors.Contains(err, apiutil.ErrMissingMemberKind),
errors.Contains(err, apiutil.ErrLimitSize),
errors.Contains(err, apiutil.ErrBearerKey),
errors.Contains(err, apiutil.ErrNameSize),
errors.Contains(err, apiutil.ErrInvalidIDFormat),
errors.Contains(err, svcerr.ErrInvalidStatus),
errors.Contains(err, apiutil.ErrValidation),
errors.Contains(err, apiutil.ErrInvitationState),
errors.Contains(err, apiutil.ErrInvalidRole),
errors.Contains(err, apiutil.ErrMissingEmail),
errors.Contains(err, apiutil.ErrMissingHost),
errors.Contains(err, apiutil.ErrMissingIdentity),
errors.Contains(err, apiutil.ErrMissingSecret),
errors.Contains(err, apiutil.ErrMissingPass),
errors.Contains(err, apiutil.ErrMissingConfPass),
errors.Contains(err, apiutil.ErrInvalidResetPass),
errors.Contains(err, apiutil.ErrMissingRelation),
errors.Contains(err, apiutil.ErrPasswordFormat),
errors.Contains(err, apiutil.ErrInvalidLevel),
errors.Contains(err, apiutil.ErrMalformedPolicy),
errors.Contains(err, apiutil.ErrInvalidAPIKey),
errors.Contains(err, apiutil.ErrMissingName),
errors.Contains(err, apiutil.ErrBootstrapState),
errors.Contains(err, apiutil.ErrMissingCertData),
errors.Contains(err, apiutil.ErrInvalidCertData),
errors.Contains(err, apiutil.ErrInvalidContact),
errors.Contains(err, apiutil.ErrInvalidTopic),
errors.Contains(err, apiutil.ErrInvalidQueryParams):
w.WriteHeader(http.StatusBadRequest)
case errors.Contains(err, svcerr.ErrAuthentication),
errors.Contains(err, svcerr.ErrLogin),
errors.Contains(err, apiutil.ErrBearerToken):
w.WriteHeader(http.StatusUnauthorized)
case errors.Contains(err, svcerr.ErrNotFound):
w.WriteHeader(http.StatusNotFound)
case errors.Contains(err, svcerr.ErrConflict),
errors.Contains(err, errors.ErrStatusAlreadyAssigned):
w.WriteHeader(http.StatusConflict)
case errors.Contains(err, svcerr.ErrAuthorization),
errors.Contains(err, svcerr.ErrDomainAuthorization),
errors.Contains(err, bootstrap.ErrExternalKey),
errors.Contains(err, bootstrap.ErrExternalKeySecure):
err = unwrap(err)
w.WriteHeader(http.StatusForbidden)
case errors.Contains(err, apiutil.ErrUnsupportedContentType):
w.WriteHeader(http.StatusUnsupportedMediaType)
case errors.Contains(err, svcerr.ErrAuthentication),
errors.Contains(err, apiutil.ErrBearerToken),
errors.Contains(err, svcerr.ErrLogin):
err = unwrap(err)
w.WriteHeader(http.StatusUnauthorized)
case errors.Contains(err, svcerr.ErrMalformedEntity),
errors.Contains(err, apiutil.ErrMalformedPolicy),
errors.Contains(err, apiutil.ErrMissingSecret),
errors.Contains(err, errors.ErrMalformedEntity),
errors.Contains(err, apiutil.ErrMissingID),
errors.Contains(err, apiutil.ErrMissingName),
errors.Contains(err, apiutil.ErrMissingEmail),
errors.Contains(err, apiutil.ErrMissingHost),
errors.Contains(err, apiutil.ErrInvalidResetPass),
errors.Contains(err, apiutil.ErrEmptyList),
errors.Contains(err, apiutil.ErrMissingMemberKind),
errors.Contains(err, apiutil.ErrMissingMemberType),
errors.Contains(err, apiutil.ErrLimitSize),
errors.Contains(err, apiutil.ErrBearerKey),
errors.Contains(err, svcerr.ErrInvalidStatus),
errors.Contains(err, apiutil.ErrNameSize),
errors.Contains(err, apiutil.ErrInvalidIDFormat),
errors.Contains(err, apiutil.ErrInvalidQueryParams),
errors.Contains(err, apiutil.ErrMissingRelation),
errors.Contains(err, apiutil.ErrValidation),
errors.Contains(err, apiutil.ErrMissingIdentity),
errors.Contains(err, apiutil.ErrMissingPass),
errors.Contains(err, apiutil.ErrMissingConfPass),
errors.Contains(err, apiutil.ErrPasswordFormat),
errors.Contains(err, svcerr.ErrInvalidRole),
errors.Contains(err, svcerr.ErrInvalidPolicy),
errors.Contains(err, apiutil.ErrInvitationState),
errors.Contains(err, apiutil.ErrInvalidAPIKey),
errors.Contains(err, svcerr.ErrViewEntity),
errors.Contains(err, apiutil.ErrBootstrapState),
errors.Contains(err, apiutil.ErrMissingCertData),
errors.Contains(err, apiutil.ErrInvalidContact),
errors.Contains(err, apiutil.ErrInvalidTopic),
errors.Contains(err, bootstrap.ErrAddBootstrap),
errors.Contains(err, apiutil.ErrInvalidCertData):
err = unwrap(err)
w.WriteHeader(http.StatusBadRequest)
case errors.Contains(err, svcerr.ErrCreateEntity),
errors.Contains(err, svcerr.ErrUpdateEntity),
errors.Contains(err, svcerr.ErrFailedUpdateRole),
errors.Contains(err, svcerr.ErrViewEntity),
errors.Contains(err, svcerr.ErrAddPolicies),
errors.Contains(err, svcerr.ErrDeletePolicies),
errors.Contains(err, svcerr.ErrRemoveEntity):
errors.Contains(err, svcerr.ErrRemoveEntity),
errors.Contains(err, svcerr.ErrEnableClient):
err = unwrap(err)
w.WriteHeader(http.StatusUnprocessableEntity)
case errors.Contains(err, bootstrap.ErrThings):
w.WriteHeader(http.StatusServiceUnavailable)
case errors.Contains(err, svcerr.ErrNotFound),
errors.Contains(err, bootstrap.ErrBootstrap):
err = unwrap(err)
w.WriteHeader(http.StatusNotFound)
case errors.Contains(err, errors.ErrStatusAlreadyAssigned),
errors.Contains(err, svcerr.ErrConflict):
err = unwrap(err)
w.WriteHeader(http.StatusConflict)
case errors.Contains(err, apiutil.ErrUnsupportedContentType):
err = unwrap(err)
w.WriteHeader(http.StatusUnsupportedMediaType)
default:
w.WriteHeader(http.StatusInternalServerError)
}
@@ -180,3 +191,11 @@ func EncodeError(_ context.Context, err error, w http.ResponseWriter) {
}
}
}
func unwrap(err error) error {
wrapper, err := errors.Unwrap(err)
if wrapper != nil {
return wrapper
}
return err
}
+1 -1
View File
@@ -234,6 +234,7 @@ func TestEncodeError(t *testing.T) {
apiutil.ErrMissingMemberKind,
apiutil.ErrLimitSize,
apiutil.ErrNameSize,
svcerr.ErrViewEntity,
},
code: http.StatusBadRequest,
},
@@ -298,7 +299,6 @@ func TestEncodeError(t *testing.T) {
errs: []error{
svcerr.ErrCreateEntity,
svcerr.ErrUpdateEntity,
svcerr.ErrViewEntity,
svcerr.ErrRemoveEntity,
},
code: http.StatusUnprocessableEntity,
+3 -4
View File
@@ -13,7 +13,6 @@ import (
"github.com/absmach/magistrala/internal/apiutil"
mgclients "github.com/absmach/magistrala/pkg/clients"
"github.com/absmach/magistrala/pkg/errors"
repoerr "github.com/absmach/magistrala/pkg/errors/repository"
svcerr "github.com/absmach/magistrala/pkg/errors/service"
"github.com/absmach/magistrala/pkg/groups"
"golang.org/x/sync/errgroup"
@@ -117,7 +116,7 @@ func (svc service) ViewGroup(ctx context.Context, token, id string) (groups.Grou
group, err := svc.groups.RetrieveByID(ctx, id)
if err != nil {
return groups.Group{}, errors.Wrap(repoerr.ErrViewEntity, err)
return groups.Group{}, errors.Wrap(svcerr.ErrViewEntity, err)
}
return group, nil
@@ -467,7 +466,7 @@ func (svc service) assignParentGroup(ctx context.Context, domain, parentGroupID
var deletePolicies magistrala.DeletePoliciesReq
for _, group := range groupsPage.Groups {
if group.Parent != "" {
return errors.Wrap(repoerr.ErrConflict, fmt.Errorf("%s group already have parent", group.ID))
return errors.Wrap(svcerr.ErrConflict, fmt.Errorf("%s group already have parent", group.ID))
}
addPolicies.AddPoliciesReq = append(addPolicies.AddPoliciesReq, &magistrala.AddPolicyReq{
Domain: domain,
@@ -513,7 +512,7 @@ func (svc service) unassignParentGroup(ctx context.Context, domain, parentGroupI
var deletePolicies magistrala.DeletePoliciesReq
for _, group := range groupsPage.Groups {
if group.Parent != "" && group.Parent != parentGroupID {
return errors.Wrap(repoerr.ErrConflict, fmt.Errorf("%s group doesn't have same parent", group.ID))
return errors.Wrap(svcerr.ErrConflict, fmt.Errorf("%s group doesn't have same parent", group.ID))
}
addPolicies.AddPoliciesReq = append(addPolicies.AddPoliciesReq, &magistrala.AddPolicyReq{
Domain: domain,
-1
View File
@@ -296,7 +296,6 @@ func TestListInvitation(t *testing.T) {
token: tc.token,
contentType: tc.contentType,
}
res, err := req.make()
assert.Nil(t, err, tc.desc)
assert.Equal(t, tc.status, res.StatusCode, tc.desc)
+16 -10
View File
@@ -29,7 +29,7 @@ var (
ErrConflict = errors.New("entity already exists")
// ErrCreateEntity indicates error in creating entity or entities.
ErrCreateEntity = errors.New("failed to create entity in the db")
ErrCreateEntity = errors.New("failed to create entity")
// ErrRemoveEntity indicates error in removing entity.
ErrRemoveEntity = errors.New("failed to remove entity")
@@ -55,18 +55,24 @@ var (
// ErrFailedPolicyUpdate indicates a failure to update user policy.
ErrFailedPolicyUpdate = errors.New("failed to update user policy")
// ErrAddPolicies indicates failed to add policies.
ErrAddPolicies = errors.New("failed to add policies")
// ErrDeletePolicies indicates failed to delete policies.
ErrDeletePolicies = errors.New("failed to delete policies")
// ErrIssueToken indicates a failure to issue token.
ErrIssueToken = errors.New("failed to issue token")
// ErrPasswordFormat indicates weak password.
ErrPasswordFormat = errors.New("password does not meet the requirements")
// ErrFailedUpdateRole indicates a failure to update user role.
ErrFailedUpdateRole = errors.New("failed to update user role")
// ErrFailedPermissionsList indicates a failure to list permissions.
ErrFailedPermissionsList = errors.New("failed to list permissions")
// ErrEnableClient indicates error in enabling client.
ErrEnableClient = errors.New("failed to enable client")
// ErrDisableClient indicates error in disabling client.
ErrDisableClient = errors.New("failed to disable client")
// ErrAddPolicies indicates error in adding policies.
ErrAddPolicies = errors.New("failed to add policies")
// ErrDeletePolicies indicates error in removing policies.
ErrDeletePolicies = errors.New("failed to remove policies")
)
+5 -3
View File
@@ -175,6 +175,8 @@ func TestViewCert(t *testing.T) {
certID: validID,
token: token,
cRes: c,
err: nil,
svcerr: nil,
},
{
desc: "get non-existent cert",
@@ -291,7 +293,7 @@ func TestRevokeCert(t *testing.T) {
thingID: thingID,
token: authmocks.InvalidValue,
svcResponse: certs.Revoke{RevocationTime: time.Now()},
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthentication, svcerr.ErrAuthentication), http.StatusUnauthorized),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
svcerr: errors.Wrap(svcerr.ErrAuthentication, svcerr.ErrAuthentication),
},
{
@@ -299,7 +301,7 @@ func TestRevokeCert(t *testing.T) {
thingID: "2",
token: token,
svcResponse: certs.Revoke{RevocationTime: time.Now()},
err: errors.NewSDKErrorWithStatus(errors.Wrap(certs.ErrFailedCertRevocation, svcerr.ErrNotFound), http.StatusNotFound),
err: errors.NewSDKErrorWithStatus(certs.ErrFailedCertRevocation, http.StatusNotFound),
svcerr: errors.Wrap(certs.ErrFailedCertRevocation, svcerr.ErrNotFound),
},
{
@@ -321,7 +323,7 @@ func TestRevokeCert(t *testing.T) {
thingID: thingID,
token: token,
svcResponse: certs.Revoke{RevocationTime: time.Now()},
err: errors.NewSDKErrorWithStatus(errors.Wrap(certs.ErrFailedToRemoveCertFromDB, svcerr.ErrNotFound), http.StatusNotFound),
err: errors.NewSDKErrorWithStatus(certs.ErrFailedToRemoveCertFromDB, http.StatusNotFound),
svcerr: errors.Wrap(certs.ErrFailedToRemoveCertFromDB, svcerr.ErrNotFound),
},
}
+10 -10
View File
@@ -110,7 +110,7 @@ func TestCreateChannel(t *testing.T) {
Status: mgclients.EnabledStatus.String(),
},
token: token,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrCreateEntity, svcerr.ErrCreateEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrCreateEntity, http.StatusUnprocessableEntity),
},
{
desc: "create channel with missing name",
@@ -203,7 +203,7 @@ func TestListChannels(t *testing.T) {
token: invalidToken,
offset: offset,
limit: limit,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthentication, svcerr.ErrAuthentication), http.StatusUnauthorized),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
response: nil,
},
{
@@ -324,14 +324,14 @@ func TestViewChannel(t *testing.T) {
token: "wrongtoken",
channelID: channel.ID,
response: sdk.Channel{Children: []*sdk.Channel{}},
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrViewEntity, svcerr.ErrViewEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrViewEntity, http.StatusBadRequest),
},
{
desc: "view channel for wrong id",
token: validToken,
channelID: wrongID,
response: sdk.Channel{Children: []*sdk.Channel{}},
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrViewEntity, svcerr.ErrViewEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrViewEntity, http.StatusBadRequest),
},
}
@@ -464,7 +464,7 @@ func TestUpdateChannel(t *testing.T) {
},
response: sdk.Channel{},
token: invalidToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthorization, svcerr.ErrAuthorization), http.StatusForbidden),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
},
{
desc: "update channel description with invalid token",
@@ -474,7 +474,7 @@ func TestUpdateChannel(t *testing.T) {
},
response: sdk.Channel{},
token: invalidToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthorization, svcerr.ErrAuthorization), http.StatusForbidden),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
},
{
desc: "update channel metadata with invalid token",
@@ -486,7 +486,7 @@ func TestUpdateChannel(t *testing.T) {
},
response: sdk.Channel{},
token: invalidToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthorization, svcerr.ErrAuthorization), http.StatusForbidden),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
},
{
desc: "update channel that can't be marshalled",
@@ -616,7 +616,7 @@ func TestListChannelsByThing(t *testing.T) {
clientID: testsutil.GenerateUUID(t),
page: sdk.PageMetadata{},
response: []sdk.Channel(nil),
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthentication, svcerr.ErrAuthentication), http.StatusUnauthorized),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
},
}
@@ -659,7 +659,7 @@ func TestEnableChannel(t *testing.T) {
repoCall1 := grepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(mggroups.Group{}, repoerr.ErrNotFound)
repoCall2 := grepo.On("ChangeStatus", mock.Anything, mock.Anything).Return(nil)
_, err := mgsdk.EnableChannel("wrongID", validToken)
assert.Equal(t, errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrViewEntity, svcerr.ErrNotFound), http.StatusNotFound), err, fmt.Sprintf("Enable channel with wrong id: expected %v got %v", svcerr.ErrNotFound, err))
assert.Equal(t, errors.NewSDKErrorWithStatus(svcerr.ErrViewEntity, http.StatusBadRequest), err, fmt.Sprintf("Enable channel with wrong id: expected %v got %v", svcerr.ErrViewEntity, err))
ok := repoCall1.Parent.AssertCalled(t, "RetrieveByID", mock.Anything, "wrongID")
assert.True(t, ok, "RetrieveByID was not called on enabling channel")
repoCall.Unset()
@@ -711,7 +711,7 @@ func TestDisableChannel(t *testing.T) {
repoCall1 := grepo.On("ChangeStatus", mock.Anything, mock.Anything).Return(nil)
repoCall2 := grepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(mggroups.Group{}, repoerr.ErrNotFound)
_, err := mgsdk.DisableChannel("wrongID", validToken)
assert.Equal(t, err, errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrViewEntity, svcerr.ErrNotFound), http.StatusNotFound), fmt.Sprintf("Disable channel with wrong id: expected %v got %v", svcerr.ErrNotFound, err))
assert.Equal(t, err, errors.NewSDKErrorWithStatus(svcerr.ErrViewEntity, http.StatusBadRequest), fmt.Sprintf("Disable channel with wrong id: expected %v got %v", svcerr.ErrNotFound, err))
ok := repoCall1.Parent.AssertCalled(t, "RetrieveByID", mock.Anything, "wrongID")
assert.True(t, ok, "Memberships was not called on disabling channel with wrong id")
repoCall.Unset()
+11 -11
View File
@@ -98,7 +98,7 @@ func TestCreateGroup(t *testing.T) {
ParentID: wrongID,
Status: clients.EnabledStatus.String(),
},
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrCreateEntity, svcerr.ErrCreateEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrCreateEntity, http.StatusUnprocessableEntity),
},
{
desc: "create group with missing name",
@@ -203,7 +203,7 @@ func TestListGroups(t *testing.T) {
token: invalidToken,
offset: offset,
limit: limit,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthentication, svcerr.ErrAuthentication), http.StatusUnauthorized),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
response: nil,
},
{
@@ -334,7 +334,7 @@ func TestListParentGroups(t *testing.T) {
token: invalidToken,
offset: offset,
limit: limit,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthentication, svcerr.ErrAuthentication), http.StatusUnauthorized),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
response: nil,
},
{
@@ -466,7 +466,7 @@ func TestListChildrenGroups(t *testing.T) {
token: invalidToken,
offset: offset,
limit: limit,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthentication, svcerr.ErrAuthentication), http.StatusUnauthorized),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
response: nil,
},
{
@@ -583,14 +583,14 @@ func TestViewGroup(t *testing.T) {
token: "wrongtoken",
groupID: group.ID,
response: sdk.Group{Children: []*sdk.Group{}},
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrViewEntity, svcerr.ErrViewEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrViewEntity, http.StatusBadRequest),
},
{
desc: "view group for wrong id",
token: validToken,
groupID: wrongID,
response: sdk.Group{Children: []*sdk.Group{}},
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrViewEntity, svcerr.ErrViewEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrViewEntity, http.StatusBadRequest),
},
}
@@ -723,7 +723,7 @@ func TestUpdateGroup(t *testing.T) {
},
response: sdk.Group{},
token: invalidToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthorization, svcerr.ErrAuthorization), http.StatusForbidden),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
},
{
desc: "update group description with invalid token",
@@ -733,7 +733,7 @@ func TestUpdateGroup(t *testing.T) {
},
response: sdk.Group{},
token: invalidToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthorization, svcerr.ErrAuthorization), http.StatusForbidden),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
},
{
desc: "update group metadata with invalid token",
@@ -745,7 +745,7 @@ func TestUpdateGroup(t *testing.T) {
},
response: sdk.Group{},
token: invalidToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthorization, svcerr.ErrAuthorization), http.StatusForbidden),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
},
{
desc: "update a group that can't be marshalled",
@@ -798,7 +798,7 @@ func TestEnableGroup(t *testing.T) {
repoCall1 := grepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(mggroups.Group{}, repoerr.ErrNotFound)
repoCall2 := grepo.On("ChangeStatus", mock.Anything, mock.Anything).Return(nil)
_, err := mgsdk.EnableGroup("wrongID", validToken)
assert.Equal(t, err, errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrViewEntity, svcerr.ErrNotFound), http.StatusNotFound), fmt.Sprintf("Enable group with wrong id: expected %v got %v", svcerr.ErrNotFound, err))
assert.Equal(t, err, errors.NewSDKErrorWithStatus(svcerr.ErrViewEntity, http.StatusBadRequest), fmt.Sprintf("Enable group with wrong id: expected %v got %v", svcerr.ErrNotFound, err))
ok := repoCall1.Parent.AssertCalled(t, "RetrieveByID", mock.Anything, "wrongID")
assert.True(t, ok, "RetrieveByID was not called on enabling group")
repoCall.Unset()
@@ -851,7 +851,7 @@ func TestDisableGroup(t *testing.T) {
repoCall1 := grepo.On("ChangeStatus", mock.Anything, mock.Anything).Return(nil)
repoCall2 := grepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(mggroups.Group{}, repoerr.ErrNotFound)
_, err := mgsdk.DisableGroup("wrongID", validToken)
assert.Equal(t, err, errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrViewEntity, svcerr.ErrNotFound), http.StatusNotFound), fmt.Sprintf("Disable group with wrong id: expected %v got %v", svcerr.ErrNotFound, err))
assert.Equal(t, err, errors.NewSDKErrorWithStatus(svcerr.ErrViewEntity, http.StatusBadRequest), fmt.Sprintf("Disable group with wrong id: expected %v got %v", svcerr.ErrViewEntity, err))
ok := repoCall1.Parent.AssertCalled(t, "RetrieveByID", mock.Anything, "wrongID")
assert.True(t, ok, "Memberships was not called on disabling group with wrong id")
repoCall.Unset()
+22 -23
View File
@@ -18,7 +18,6 @@ import (
mglog "github.com/absmach/magistrala/logger"
mgclients "github.com/absmach/magistrala/pkg/clients"
"github.com/absmach/magistrala/pkg/errors"
repoerr "github.com/absmach/magistrala/pkg/errors/repository"
svcerr "github.com/absmach/magistrala/pkg/errors/service"
gmocks "github.com/absmach/magistrala/pkg/groups/mocks"
sdk "github.com/absmach/magistrala/pkg/sdk/go"
@@ -97,7 +96,7 @@ func TestCreateThing(t *testing.T) {
response: sdk.Thing{},
token: token,
repoErr: sdk.ErrFailedCreation,
err: errors.NewSDKErrorWithStatus(errors.Wrap(sdk.ErrFailedCreation, repoerr.ErrCreateEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrCreateEntity, http.StatusUnprocessableEntity),
},
{
desc: "register empty thing",
@@ -105,7 +104,7 @@ func TestCreateThing(t *testing.T) {
response: sdk.Thing{},
token: token,
repoErr: errors.ErrMalformedEntity,
err: errors.NewSDKErrorWithStatus(errors.Wrap(sdk.ErrFailedCreation, repoerr.ErrMalformedEntity), http.StatusBadRequest),
err: errors.NewSDKErrorWithStatus(svcerr.ErrCreateEntity, http.StatusBadRequest),
},
{
desc: "register a thing that can't be marshalled",
@@ -246,7 +245,7 @@ func TestCreateThings(t *testing.T) {
things: thingsList,
response: []sdk.Thing{},
token: token,
err: errors.NewSDKErrorWithStatus(errors.Wrap(sdk.ErrFailedCreation, sdk.ErrFailedCreation), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrCreateEntity, http.StatusUnprocessableEntity),
},
{
desc: "register empty things",
@@ -361,7 +360,7 @@ func TestListThings(t *testing.T) {
token: authmocks.InvalidValue,
offset: offset,
limit: limit,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthentication, svcerr.ErrAuthentication), http.StatusUnauthorized),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
response: nil,
},
{
@@ -369,7 +368,7 @@ func TestListThings(t *testing.T) {
token: "",
offset: offset,
limit: limit,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthentication, svcerr.ErrAuthentication), http.StatusUnauthorized),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
response: nil,
},
{
@@ -573,7 +572,7 @@ func TestListThingsByChannel(t *testing.T) {
channelID: testsutil.GenerateUUID(t),
page: sdk.PageMetadata{},
response: []sdk.Thing(nil),
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthentication, svcerr.ErrAuthentication), http.StatusUnauthorized),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
},
{
desc: "list things with an invalid id",
@@ -581,7 +580,7 @@ func TestListThingsByChannel(t *testing.T) {
channelID: wrongID,
page: sdk.PageMetadata{},
response: []sdk.Thing(nil),
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrViewEntity, svcerr.ErrViewEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrViewEntity, http.StatusBadRequest),
},
}
@@ -639,21 +638,21 @@ func TestThing(t *testing.T) {
response: sdk.Thing{},
token: invalidToken,
thingID: generateUUID(t),
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthorization, svcerr.ErrAuthorization), http.StatusForbidden),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
},
{
desc: "view thing with valid token and invalid thing id",
response: sdk.Thing{},
token: validToken,
thingID: wrongID,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrViewEntity, svcerr.ErrViewEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrViewEntity, http.StatusBadRequest),
},
{
desc: "view thing with an invalid token and invalid thing id",
response: sdk.Thing{},
token: invalidToken,
thingID: wrongID,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthorization, svcerr.ErrAuthorization), http.StatusForbidden),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
},
}
@@ -718,14 +717,14 @@ func TestUpdateThing(t *testing.T) {
thing: thing1,
response: sdk.Thing{},
token: invalidToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthorization, svcerr.ErrAuthorization), http.StatusForbidden),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
},
{
desc: "update thing name with invalid id",
thing: thing2,
response: sdk.Thing{},
token: validToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrUpdateEntity, svcerr.ErrUpdateEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrUpdateEntity, http.StatusUnprocessableEntity),
},
{
desc: "update thing that can't be marshalled",
@@ -803,14 +802,14 @@ func TestUpdateThingTags(t *testing.T) {
thing: thing1,
response: sdk.Thing{},
token: invalidToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthorization, svcerr.ErrAuthorization), http.StatusForbidden),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
},
{
desc: "update thing name with invalid id",
thing: thing2,
response: sdk.Thing{},
token: validToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrUpdateEntity, svcerr.ErrUpdateEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrUpdateEntity, http.StatusUnprocessableEntity),
},
{
desc: "update thing that can't be marshalled",
@@ -884,7 +883,7 @@ func TestUpdateThingSecret(t *testing.T) {
token: "non-existent",
response: sdk.Thing{},
repoErr: svcerr.ErrAuthorization,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrUpdateEntity, svcerr.ErrAuthorization), http.StatusForbidden),
err: errors.NewSDKErrorWithStatus(svcerr.ErrUpdateEntity, http.StatusForbidden),
},
{
desc: "update thing secret with wrong old secret",
@@ -893,7 +892,7 @@ func TestUpdateThingSecret(t *testing.T) {
token: validToken,
response: sdk.Thing{},
repoErr: apiutil.ErrMissingSecret,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrUpdateEntity, apiutil.ErrMissingSecret), http.StatusBadRequest),
err: errors.NewSDKErrorWithStatus(svcerr.ErrUpdateEntity, http.StatusBadRequest),
},
}
for _, tc := range cases {
@@ -956,7 +955,7 @@ func TestEnableThing(t *testing.T) {
thing: enabledThing1,
response: sdk.Thing{},
repoErr: sdk.ErrFailedEnable,
err: errors.NewSDKErrorWithStatus(errors.Wrap(sdk.ErrFailedEnable, svcerr.ErrViewEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrEnableClient, http.StatusBadRequest),
},
{
desc: "enable non-existing thing",
@@ -965,7 +964,7 @@ func TestEnableThing(t *testing.T) {
thing: sdk.Thing{},
response: sdk.Thing{},
repoErr: sdk.ErrFailedEnable,
err: errors.NewSDKErrorWithStatus(errors.Wrap(sdk.ErrFailedEnable, svcerr.ErrViewEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrEnableClient, http.StatusBadRequest),
},
}
@@ -1091,7 +1090,7 @@ func TestDisableThing(t *testing.T) {
thing: disabledThing1,
response: sdk.Thing{},
repoErr: sdk.ErrFailedDisable,
err: errors.NewSDKErrorWithStatus(errors.Wrap(sdk.ErrFailedDisable, svcerr.ErrViewEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrDisableClient, http.StatusBadRequest),
},
{
desc: "disable non-existing thing",
@@ -1100,7 +1099,7 @@ func TestDisableThing(t *testing.T) {
token: validToken,
response: sdk.Thing{},
repoErr: sdk.ErrFailedDisable,
err: errors.NewSDKErrorWithStatus(errors.Wrap(sdk.ErrFailedDisable, svcerr.ErrViewEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrDisableClient, http.StatusBadRequest),
},
}
@@ -1218,14 +1217,14 @@ func TestShareThing(t *testing.T) {
channelID: generateUUID(t),
thingID: "thingID",
token: invalidToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthentication, svcerr.ErrAuthentication), http.StatusUnauthorized),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
},
{
desc: "share thing with valid token for unauthorized user",
channelID: generateUUID(t),
thingID: "thingID",
token: validToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthorization, svcerr.ErrAuthorization), http.StatusForbidden),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
repoErr: svcerr.ErrAuthorization,
},
}
+1 -1
View File
@@ -69,7 +69,7 @@ func TestIssueToken(t *testing.T) {
login: sdk.Login{Identity: "invalid", Secret: "secret"},
token: &magistrala.Token{},
dbClient: wrongClient,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrViewEntity, svcerr.ErrViewEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
},
}
for _, tc := range cases {
+23 -24
View File
@@ -18,7 +18,6 @@ import (
mglog "github.com/absmach/magistrala/logger"
mgclients "github.com/absmach/magistrala/pkg/clients"
"github.com/absmach/magistrala/pkg/errors"
repoerr "github.com/absmach/magistrala/pkg/errors/repository"
svcerr "github.com/absmach/magistrala/pkg/errors/service"
gmocks "github.com/absmach/magistrala/pkg/groups/mocks"
oauth2mocks "github.com/absmach/magistrala/pkg/oauth2/mocks"
@@ -89,7 +88,7 @@ func TestCreateClient(t *testing.T) {
client: user,
response: sdk.User{},
token: token,
err: errors.NewSDKErrorWithStatus(errors.Wrap(sdk.ErrFailedCreation, sdk.ErrFailedCreation), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrCreateEntity, http.StatusUnprocessableEntity),
},
{
desc: "register empty user",
@@ -257,7 +256,7 @@ func TestListClients(t *testing.T) {
token: invalidToken,
offset: offset,
limit: limit,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrViewEntity, svcerr.ErrViewEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrViewEntity, http.StatusBadRequest),
response: nil,
},
{
@@ -265,7 +264,7 @@ func TestListClients(t *testing.T) {
token: "",
offset: offset,
limit: limit,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrViewEntity, svcerr.ErrViewEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrViewEntity, http.StatusBadRequest),
response: nil,
},
{
@@ -273,7 +272,7 @@ func TestListClients(t *testing.T) {
token: token,
offset: offset,
limit: 0,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrViewEntity, svcerr.ErrViewEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrViewEntity, http.StatusBadRequest),
response: nil,
},
{
@@ -404,21 +403,21 @@ func TestClient(t *testing.T) {
response: sdk.User{},
token: invalidToken,
clientID: generateUUID(t),
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthentication, svcerr.ErrAuthentication), http.StatusUnauthorized),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
},
{
desc: "view client with valid token and invalid client id",
response: sdk.User{},
token: validToken,
clientID: wrongID,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrViewEntity, svcerr.ErrViewEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrViewEntity, http.StatusBadRequest),
},
{
desc: "view client with an invalid token and invalid client id",
response: sdk.User{},
token: invalidToken,
clientID: wrongID,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthentication, svcerr.ErrAuthentication), http.StatusUnauthorized),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
},
}
@@ -477,7 +476,7 @@ func TestProfile(t *testing.T) {
desc: "view client with an invalid token",
response: sdk.User{},
token: invalidToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthentication, svcerr.ErrAuthentication), http.StatusUnauthorized),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
},
}
@@ -544,14 +543,14 @@ func TestUpdateClient(t *testing.T) {
client: client1,
response: sdk.User{},
token: invalidToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthentication, svcerr.ErrAuthentication), http.StatusUnauthorized),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
},
{
desc: "update client name with invalid id",
client: client2,
response: sdk.User{},
token: validToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrUpdateEntity, svcerr.ErrUpdateEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrUpdateEntity, http.StatusUnprocessableEntity),
},
{
desc: "update a user that can't be marshalled",
@@ -635,14 +634,14 @@ func TestUpdateClientTags(t *testing.T) {
client: client1,
response: sdk.User{},
token: invalidToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthentication, svcerr.ErrAuthentication), http.StatusUnauthorized),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
},
{
desc: "update client name with invalid id",
client: client2,
response: sdk.User{},
token: validToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrUpdateEntity, svcerr.ErrUpdateEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrUpdateEntity, http.StatusUnprocessableEntity),
},
{
desc: "update a user that can't be marshalled",
@@ -725,14 +724,14 @@ func TestUpdateClientIdentity(t *testing.T) {
client: user,
response: sdk.User{},
token: invalidToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthentication, svcerr.ErrAuthentication), http.StatusUnauthorized),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
},
{
desc: "update client name with invalid id",
client: client2,
response: sdk.User{},
token: validToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrUpdateEntity, svcerr.ErrUpdateEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrUpdateEntity, http.StatusUnprocessableEntity),
},
{
desc: "update a user that can't be marshalled",
@@ -748,7 +747,7 @@ func TestUpdateClientIdentity(t *testing.T) {
},
response: sdk.User{},
token: validToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrUpdateEntity, svcerr.ErrUpdateEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrUpdateEntity, http.StatusUnprocessableEntity),
},
}
@@ -812,7 +811,7 @@ func TestUpdateClientSecret(t *testing.T) {
token: "non-existent",
response: sdk.User{},
repoErr: svcerr.ErrAuthentication,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthentication, svcerr.ErrAuthentication), http.StatusUnauthorized),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
},
{
desc: "update client secret with wrong old secret",
@@ -821,7 +820,7 @@ func TestUpdateClientSecret(t *testing.T) {
token: validToken,
response: sdk.User{},
repoErr: apiutil.ErrMissingSecret,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrViewEntity, repoerr.ErrMissingSecret), http.StatusBadRequest),
err: errors.NewSDKErrorWithStatus(svcerr.ErrViewEntity, http.StatusBadRequest),
},
}
@@ -893,14 +892,14 @@ func TestUpdateClientRole(t *testing.T) {
client: client2,
response: sdk.User{},
token: invalidToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrAuthentication, svcerr.ErrAuthentication), http.StatusUnauthorized),
err: errors.NewSDKErrorWithStatus(svcerr.ErrAuthentication, http.StatusUnauthorized),
},
{
desc: "update client name with invalid id",
client: client2,
response: sdk.User{},
token: validToken,
err: errors.NewSDKErrorWithStatus(errors.Wrap(svcerr.ErrFailedUpdateRole, svcerr.ErrFailedUpdateRole), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrUpdateEntity, http.StatusUnprocessableEntity),
},
{
desc: "update a user that can't be marshalled",
@@ -985,7 +984,7 @@ func TestEnableClient(t *testing.T) {
client: enabledClient1,
response: sdk.User{},
repoErr: sdk.ErrFailedEnable,
err: errors.NewSDKErrorWithStatus(errors.Wrap(sdk.ErrFailedEnable, svcerr.ErrViewEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrEnableClient, http.StatusBadRequest),
},
{
desc: "enable non-existing client",
@@ -994,7 +993,7 @@ func TestEnableClient(t *testing.T) {
client: sdk.User{},
response: sdk.User{},
repoErr: sdk.ErrFailedEnable,
err: errors.NewSDKErrorWithStatus(errors.Wrap(sdk.ErrFailedEnable, svcerr.ErrViewEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrEnableClient, http.StatusBadRequest),
},
}
@@ -1114,7 +1113,7 @@ func TestDisableClient(t *testing.T) {
client: disabledClient1,
response: sdk.User{},
repoErr: sdk.ErrFailedDisable,
err: errors.NewSDKErrorWithStatus(errors.Wrap(sdk.ErrFailedDisable, svcerr.ErrViewEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrViewEntity, http.StatusBadRequest),
},
{
desc: "disable non-existing client",
@@ -1123,7 +1122,7 @@ func TestDisableClient(t *testing.T) {
token: validToken,
response: sdk.User{},
repoErr: sdk.ErrFailedDisable,
err: errors.NewSDKErrorWithStatus(errors.Wrap(sdk.ErrFailedDisable, svcerr.ErrViewEntity), http.StatusUnprocessableEntity),
err: errors.NewSDKErrorWithStatus(svcerr.ErrViewEntity, http.StatusBadRequest),
},
}
+19 -25
View File
@@ -10,18 +10,12 @@ import (
"github.com/absmach/magistrala/auth"
mgclients "github.com/absmach/magistrala/pkg/clients"
"github.com/absmach/magistrala/pkg/errors"
repoerr "github.com/absmach/magistrala/pkg/errors/repository"
svcerr "github.com/absmach/magistrala/pkg/errors/service"
mggroups "github.com/absmach/magistrala/pkg/groups"
"github.com/absmach/magistrala/things/postgres"
"golang.org/x/sync/errgroup"
)
var (
errAddPolicies = errors.New("failed to add policies")
errRemovePolicies = errors.New("failed to remove the policies")
)
type service struct {
auth magistrala.AuthServiceClient
clients postgres.Repository
@@ -101,7 +95,7 @@ func (svc service) CreateThings(ctx context.Context, token string, cls ...mgclie
saved, err := svc.clients.Save(ctx, clients...)
if err != nil {
return nil, errors.Wrap(repoerr.ErrCreateEntity, err)
return nil, errors.Wrap(svcerr.ErrCreateEntity, err)
}
policies := magistrala.AddPoliciesReq{}
@@ -125,7 +119,7 @@ func (svc service) CreateThings(ctx context.Context, token string, cls ...mgclie
})
}
if _, err := svc.auth.AddPolicies(ctx, &policies); err != nil {
return nil, errors.Wrap(errAddPolicies, err)
return nil, errors.Wrap(svcerr.ErrCreateEntity, err)
}
return saved, nil
@@ -134,7 +128,7 @@ func (svc service) CreateThings(ctx context.Context, token string, cls ...mgclie
func (svc service) ViewClient(ctx context.Context, token, id string) (mgclients.Client, error) {
_, err := svc.authorize(ctx, "", auth.UserType, auth.TokenKind, token, auth.ViewPermission, auth.ThingType, id)
if err != nil {
return mgclients.Client{}, errors.Wrap(svcerr.ErrAuthorization, err)
return mgclients.Client{}, err
}
client, err := svc.clients.RetrieveByID(ctx, id)
if err != nil {
@@ -175,11 +169,11 @@ func (svc service) ListClients(ctx context.Context, token, reqUserID string, pm
}
rtids, err := svc.listClientIDs(ctx, auth.EncodeDomainUserID(res.GetDomainId(), reqUserID), pm.Permission)
if err != nil {
return mgclients.ClientsPage{}, errors.Wrap(repoerr.ErrNotFound, err)
return mgclients.ClientsPage{}, errors.Wrap(svcerr.ErrNotFound, err)
}
ids, err = svc.filterAllowedThingIDs(ctx, res.GetId(), pm.Permission, rtids)
if err != nil {
return mgclients.ClientsPage{}, errors.Wrap(repoerr.ErrNotFound, err)
return mgclients.ClientsPage{}, errors.Wrap(svcerr.ErrNotFound, err)
}
default:
err := svc.checkSuperAdmin(ctx, res.GetUserId())
@@ -193,7 +187,7 @@ func (svc service) ListClients(ctx context.Context, token, reqUserID string, pm
}
ids, err = svc.listClientIDs(ctx, res.GetId(), pm.Permission)
if err != nil {
return mgclients.ClientsPage{}, errors.Wrap(repoerr.ErrNotFound, err)
return mgclients.ClientsPage{}, errors.Wrap(svcerr.ErrNotFound, err)
}
}
}
@@ -254,7 +248,7 @@ func (svc service) listClientIDs(ctx context.Context, userID, permission string)
ObjectType: auth.ThingType,
})
if err != nil {
return nil, errors.Wrap(repoerr.ErrNotFound, err)
return nil, errors.Wrap(svcerr.ErrNotFound, err)
}
return tids.Policies, nil
}
@@ -268,7 +262,7 @@ func (svc service) filterAllowedThingIDs(ctx context.Context, userID, permission
ObjectType: auth.ThingType,
})
if err != nil {
return nil, errors.Wrap(repoerr.ErrNotFound, err)
return nil, errors.Wrap(svcerr.ErrNotFound, err)
}
for _, thingID := range thingIDs {
for _, tid := range tids.Policies {
@@ -384,7 +378,7 @@ func (svc service) DisableClient(ctx context.Context, token, id string) (mgclien
}
if err := svc.clientCache.Remove(ctx, client.ID); err != nil {
return client, errors.Wrap(repoerr.ErrRemoveEntity, err)
return client, errors.Wrap(svcerr.ErrRemoveEntity, err)
}
return client, nil
@@ -411,10 +405,10 @@ func (svc service) Share(ctx context.Context, token, id, relation string, userid
}
res, err := svc.auth.AddPolicies(ctx, &policies)
if err != nil {
return errors.Wrap(errAddPolicies, err)
return errors.Wrap(svcerr.ErrUpdateEntity, err)
}
if !res.Added {
return err
return errors.Wrap(svcerr.ErrUpdateEntity, err)
}
return nil
}
@@ -440,7 +434,7 @@ func (svc service) Unshare(ctx context.Context, token, id, relation string, user
}
res, err := svc.auth.DeletePolicies(ctx, &policies)
if err != nil {
return errors.Wrap(errRemovePolicies, err)
return errors.Wrap(svcerr.ErrUpdateEntity, err)
}
if !res.Deleted {
return err
@@ -459,7 +453,7 @@ func (svc service) DeleteClient(ctx context.Context, token, id string) error {
// Remove from cache
if err := svc.clientCache.Remove(ctx, id); err != nil {
return errors.Wrap(repoerr.ErrRemoveEntity, err)
return errors.Wrap(svcerr.ErrRemoveEntity, err)
}
// Remove policy of groups
@@ -468,7 +462,7 @@ func (svc service) DeleteClient(ctx context.Context, token, id string) error {
Object: id,
ObjectType: auth.ThingType,
}); err != nil {
return err
return errors.Wrap(svcerr.ErrRemoveEntity, err)
}
// Remove policy from domain
@@ -477,12 +471,12 @@ func (svc service) DeleteClient(ctx context.Context, token, id string) error {
Object: id,
ObjectType: auth.ThingType,
}); err != nil {
return err
return errors.Wrap(svcerr.ErrRemoveEntity, err)
}
// Remove thing from database
if err := svc.clients.Delete(ctx, id); err != nil {
return err
return errors.Wrap(svcerr.ErrRemoveEntity, err)
}
// Remove policy of users
@@ -491,7 +485,7 @@ func (svc service) DeleteClient(ctx context.Context, token, id string) error {
Object: id,
ObjectType: auth.ThingType,
}); err != nil {
return err
return errors.Wrap(svcerr.ErrRemoveEntity, err)
}
return nil
@@ -504,7 +498,7 @@ func (svc service) changeClientStatus(ctx context.Context, token string, client
}
dbClient, err := svc.clients.RetrieveByID(ctx, client.ID)
if err != nil {
return mgclients.Client{}, errors.Wrap(repoerr.ErrViewEntity, err)
return mgclients.Client{}, errors.Wrap(svcerr.ErrViewEntity, err)
}
if dbClient.Status == client.Status {
return mgclients.Client{}, errors.ErrStatusAlreadyAssigned
@@ -535,7 +529,7 @@ func (svc service) ListClientsByGroup(ctx context.Context, token, groupID string
ObjectType: auth.ThingType,
})
if err != nil {
return mgclients.MembersPage{}, errors.Wrap(repoerr.ErrNotFound, err)
return mgclients.MembersPage{}, errors.Wrap(svcerr.ErrNotFound, err)
}
pm.IDs = tids.Policies
+4 -5
View File
@@ -43,8 +43,7 @@ var (
invalid = "invalid"
validID = "d4ebb847-5d0e-4e46-bdd9-b6aceaaa3a22"
wrongID = testsutil.GenerateUUID(&testing.T{})
errAddPolicies = errors.New("failed to add policies")
errRemovePolicies = errors.New("failed to remove the policies")
errRemovePolicies = errors.New("failed to delete policies")
)
func newService() (things.Service, *mocks.Repository, *authmocks.AuthClient, *mocks.Cache) {
@@ -1774,7 +1773,7 @@ func TestShare(t *testing.T) {
authorizeResponse: &magistrala.AuthorizeRes{Authorized: true},
addPoliciesResponse: &magistrala.AddPoliciesRes{},
addPoliciesErr: svcerr.ErrInvalidPolicy,
err: errAddPolicies,
err: svcerr.ErrInvalidPolicy,
},
{
desc: "share thing with failed authorization from add policies",
@@ -1783,7 +1782,7 @@ func TestShare(t *testing.T) {
identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)},
authorizeResponse: &magistrala.AuthorizeRes{Authorized: true},
addPoliciesResponse: &magistrala.AddPoliciesRes{Added: false},
err: nil,
err: svcerr.ErrUpdateEntity,
},
}
@@ -1852,7 +1851,7 @@ func TestUnShare(t *testing.T) {
authorizeResponse: &magistrala.AuthorizeRes{Authorized: true},
deletePoliciesResponse: &magistrala.DeletePoliciesRes{},
deletePoliciesErr: svcerr.ErrInvalidPolicy,
err: errRemovePolicies,
err: svcerr.ErrInvalidPolicy,
},
{
desc: "share thing with failed delete from delete policies",
+1 -1
View File
@@ -469,7 +469,7 @@ func TestViewTwin(t *testing.T) {
desc: "view twin by passing invalid token",
id: twin.ID,
auth: authmocks.InvalidValue,
status: http.StatusUnauthorized,
status: http.StatusForbidden,
res: twinRes{},
err: svcerr.ErrAuthentication,
identifyErr: svcerr.ErrAuthentication,
+12 -3
View File
@@ -46,6 +46,7 @@ var (
inValid = "invalid"
validID = "d4ebb847-5d0e-4e46-bdd9-b6aceaaa3a22"
passRegex = regexp.MustCompile("^.{8,}$")
testReferer = "http://localhost"
)
const contentType = "application/json"
@@ -55,6 +56,7 @@ type testRequest struct {
method string
url string
contentType string
referer string
token string
body io.Reader
}
@@ -73,7 +75,7 @@ func (tr testRequest) make() (*http.Response, error) {
req.Header.Set("Content-Type", tr.contentType)
}
req.Header.Set("Referer", "http://localhost")
req.Header.Set("Referer", tr.referer)
return tr.client.Do(req)
}
@@ -1013,6 +1015,7 @@ func TestPasswordResetRequest(t *testing.T) {
desc string
data string
contentType string
referer string
status int
err error
}{
@@ -1020,6 +1023,7 @@ func TestPasswordResetRequest(t *testing.T) {
desc: "password reset request with valid email",
data: fmt.Sprintf(`{"email": "%s", "host": "%s"}`, testemail, testhost),
contentType: contentType,
referer: testReferer,
status: http.StatusCreated,
err: nil,
},
@@ -1027,6 +1031,7 @@ func TestPasswordResetRequest(t *testing.T) {
desc: "password reset request with empty email",
data: fmt.Sprintf(`{"email": "%s", "host": "%s"}`, "", testhost),
contentType: contentType,
referer: testReferer,
status: http.StatusBadRequest,
err: apiutil.ErrValidation,
},
@@ -1034,6 +1039,7 @@ func TestPasswordResetRequest(t *testing.T) {
desc: "password reset request with empty host",
data: fmt.Sprintf(`{"email": "%s", "host": "%s"}`, testemail, ""),
contentType: contentType,
referer: "",
status: http.StatusBadRequest,
err: apiutil.ErrValidation,
},
@@ -1041,6 +1047,7 @@ func TestPasswordResetRequest(t *testing.T) {
desc: "password reset request with invalid email",
data: fmt.Sprintf(`{"email": "%s", "host": "%s"}`, "invalid", testhost),
contentType: contentType,
referer: testReferer,
status: http.StatusNotFound,
err: svcerr.ErrNotFound,
},
@@ -1048,6 +1055,7 @@ func TestPasswordResetRequest(t *testing.T) {
desc: "password reset with malformed data",
data: fmt.Sprintf(`{"email": %s, "host": %s}`, testemail, testhost),
contentType: contentType,
referer: testReferer,
status: http.StatusBadRequest,
err: apiutil.ErrValidation,
},
@@ -1055,6 +1063,7 @@ func TestPasswordResetRequest(t *testing.T) {
desc: "password reset with invalid contentype",
data: fmt.Sprintf(`{"email": "%s", "host": "%s"}`, testemail, testhost),
contentType: "application/xml",
referer: testReferer,
status: http.StatusUnsupportedMediaType,
err: apiutil.ErrValidation,
},
@@ -1066,9 +1075,9 @@ func TestPasswordResetRequest(t *testing.T) {
method: http.MethodPost,
url: fmt.Sprintf("%s/password/reset-request", us.URL),
contentType: tc.contentType,
referer: tc.referer,
body: strings.NewReader(tc.data),
}
svcCall := svc.On("GenerateResetToken", mock.Anything, mock.Anything, mock.Anything).Return(tc.err)
res, err := req.make()
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error %s", tc.desc, err))
@@ -1154,10 +1163,10 @@ func TestPasswordReset(t *testing.T) {
method: http.MethodPut,
url: fmt.Sprintf("%s/password/reset", us.URL),
contentType: tc.contentType,
referer: testReferer,
token: tc.token,
body: strings.NewReader(tc.data),
}
svcCall := svc.On("ResetSecret", mock.Anything, mock.Anything, mock.Anything).Return(tc.err)
res, err := req.make()
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error %s", tc.desc, err))
+34 -23
View File
@@ -19,6 +19,13 @@ import (
"golang.org/x/sync/errgroup"
)
var (
errIssueToken = errors.New("failed to issue token")
errUserNotSignedUp = errors.New("user not signed up")
errFailedPermissionsList = errors.New("failed to list permissions")
errRecoveryToken = errors.New("failed to generate password recovery token")
)
type service struct {
clients postgres.Repository
idProvider magistrala.IDProvider
@@ -59,7 +66,7 @@ func (svc service) RegisterClient(ctx context.Context, token string, cli mgclien
if cli.Credentials.Secret != "" {
hash, err := svc.hasher.Hash(cli.Credentials.Secret)
if err != nil {
return mgclients.Client{}, errors.Wrap(repoerr.ErrMalformedEntity, err)
return mgclients.Client{}, errors.Wrap(svcerr.ErrMalformedEntity, err)
}
cli.Credentials.Secret = hash
}
@@ -85,7 +92,7 @@ func (svc service) RegisterClient(ctx context.Context, token string, cli mgclien
}()
client, err := svc.clients.Save(ctx, cli)
if err != nil {
return mgclients.Client{}, errors.Wrap(repoerr.ErrCreateEntity, err)
return mgclients.Client{}, errors.Wrap(svcerr.ErrCreateEntity, err)
}
return client, nil
}
@@ -93,7 +100,7 @@ func (svc service) RegisterClient(ctx context.Context, token string, cli mgclien
func (svc service) IssueToken(ctx context.Context, identity, secret, domainID string) (*magistrala.Token, error) {
dbUser, err := svc.clients.RetrieveByIdentity(ctx, identity)
if err != nil {
return &magistrala.Token{}, errors.Wrap(svcerr.ErrViewEntity, err)
return &magistrala.Token{}, errors.Wrap(svcerr.ErrAuthentication, err)
}
if err := svc.hasher.Compare(secret, dbUser.Credentials.Secret); err != nil {
return &magistrala.Token{}, errors.Wrap(svcerr.ErrLogin, err)
@@ -103,7 +110,13 @@ func (svc service) IssueToken(ctx context.Context, identity, secret, domainID st
if domainID != "" {
d = domainID
}
return svc.auth.Issue(ctx, &magistrala.IssueReq{UserId: dbUser.ID, DomainId: &d, Type: uint32(auth.AccessKey)})
token, err := svc.auth.Issue(ctx, &magistrala.IssueReq{UserId: dbUser.ID, DomainId: &d, Type: uint32(auth.AccessKey)})
if err != nil {
return &magistrala.Token{}, errors.Wrap(errIssueToken, err)
}
return token, err
}
func (svc service) RefreshToken(ctx context.Context, refreshToken, domainID string) (*magistrala.Token, error) {
@@ -259,8 +272,8 @@ func (svc service) UpdateClientIdentity(ctx context.Context, token, clientID, id
func (svc service) GenerateResetToken(ctx context.Context, email, host string) error {
client, err := svc.clients.RetrieveByIdentity(ctx, email)
if err != nil || client.Credentials.Identity == "" {
return repoerr.ErrNotFound
if err != nil {
return errors.Wrap(svcerr.ErrViewEntity, err)
}
issueReq := &magistrala.IssueReq{
UserId: client.ID,
@@ -268,7 +281,7 @@ func (svc service) GenerateResetToken(ctx context.Context, email, host string) e
}
token, err := svc.auth.Issue(ctx, issueReq)
if err != nil {
return errors.Wrap(svcerr.ErrRecoveryToken, err)
return errors.Wrap(errRecoveryToken, err)
}
return svc.SendPasswordReset(ctx, host, email, client.Name, token.AccessToken)
@@ -283,12 +296,10 @@ func (svc service) ResetSecret(ctx context.Context, resetToken, secret string) e
if err != nil {
return errors.Wrap(svcerr.ErrViewEntity, err)
}
if c.Credentials.Identity == "" {
return repoerr.ErrNotFound
}
secret, err = svc.hasher.Hash(secret)
if err != nil {
return err
return errors.Wrap(svcerr.ErrMalformedEntity, err)
}
c = mgclients.Client{
ID: c.ID,
@@ -315,11 +326,11 @@ func (svc service) UpdateClientSecret(ctx context.Context, token, oldSecret, new
return mgclients.Client{}, errors.Wrap(svcerr.ErrViewEntity, err)
}
if _, err := svc.IssueToken(ctx, dbClient.Credentials.Identity, oldSecret, ""); err != nil {
return mgclients.Client{}, errors.Wrap(svcerr.ErrIssueToken, err)
return mgclients.Client{}, err
}
newSecret, err = svc.hasher.Hash(newSecret)
if err != nil {
return mgclients.Client{}, errors.Wrap(repoerr.ErrMalformedEntity, err)
return mgclients.Client{}, errors.Wrap(svcerr.ErrMalformedEntity, err)
}
dbClient.Credentials.Secret = newSecret
dbClient.UpdatedAt = time.Now()
@@ -355,15 +366,15 @@ func (svc service) UpdateClientRole(ctx context.Context, token string, cli mgcli
}
if err := svc.updateClientPolicy(ctx, cli.ID, cli.Role); err != nil {
return mgclients.Client{}, errors.Wrap(svcerr.ErrFailedPolicyUpdate, err)
return mgclients.Client{}, err
}
client, err = svc.clients.UpdateRole(ctx, client)
if err != nil {
// If failed to update role in DB, then revert back to platform admin policy in spicedb
if errRollback := svc.updateClientPolicy(ctx, cli.ID, mgclients.UserRole); errRollback != nil {
return mgclients.Client{}, errors.Wrap(err, errors.Wrap(repoerr.ErrRollbackTx, errRollback))
return mgclients.Client{}, errors.Wrap(errRollback, err)
}
return mgclients.Client{}, errors.Wrap(svcerr.ErrFailedUpdateRole, err)
return mgclients.Client{}, errors.Wrap(svcerr.ErrUpdateEntity, err)
}
return client, nil
}
@@ -390,7 +401,7 @@ func (svc service) DisableClient(ctx context.Context, token, id string) (mgclien
}
client, err := svc.changeClientStatus(ctx, token, client)
if err != nil {
return mgclients.Client{}, errors.Wrap(mgclients.ErrDisableClient, err)
return mgclients.Client{}, err
}
return client, nil
@@ -417,7 +428,7 @@ func (svc service) changeClientStatus(ctx context.Context, token string, client
if err != nil {
return mgclients.Client{}, errors.Wrap(svcerr.ErrUpdateEntity, err)
}
return client, err
return client, nil
}
func (svc service) ListMembers(ctx context.Context, token, objectKind, objectID string, pm mgclients.Page) (mgclients.MembersPage, error) {
@@ -498,7 +509,7 @@ func (svc service) retrieveObjectUsersPermissions(ctx context.Context, domainID,
userID := auth.EncodeDomainUserID(domainID, client.ID)
permissions, err := svc.listObjectUserPermission(ctx, userID, objectType, objectID)
if err != nil {
return err
return errors.Wrap(svcerr.ErrAuthorization, err)
}
client.Permissions = permissions
return nil
@@ -512,7 +523,7 @@ func (svc service) listObjectUserPermission(ctx context.Context, userID, objectT
ObjectType: objectType,
})
if err != nil {
return []string{}, err
return []string{}, errors.Wrap(errFailedPermissionsList, err)
}
return lp.GetPermissions(), nil
}
@@ -562,9 +573,9 @@ func (svc service) OAuthCallback(ctx context.Context, state mgoauth2.State, clie
rclient, err := svc.clients.RetrieveByIdentity(ctx, client.Credentials.Identity)
if err != nil {
if errors.Contains(err, repoerr.ErrNotFound) {
return &magistrala.Token{}, errors.New("user not signed up")
return &magistrala.Token{}, errors.Wrap(svcerr.ErrNotFound, errUserNotSignedUp)
}
return &magistrala.Token{}, err
return &magistrala.Token{}, errors.Wrap(svcerr.ErrViewEntity, err)
}
claims := &magistrala.IssueReq{
UserId: rclient.ID,
@@ -575,7 +586,7 @@ func (svc service) OAuthCallback(ctx context.Context, state mgoauth2.State, clie
rclient, err := svc.RegisterClient(ctx, "", client)
if err != nil {
if errors.Contains(err, repoerr.ErrConflict) {
return &magistrala.Token{}, errors.New("user already exists")
return &magistrala.Token{}, errors.Wrap(svcerr.ErrConflict, errors.New("user already exists"))
}
return &magistrala.Token{}, err
}
+2 -2
View File
@@ -1053,7 +1053,7 @@ func TestUpdateClientRole(t *testing.T) {
deletePolicyResponse: &magistrala.DeletePolicyRes{Deleted: false},
updateRoleResponse: mgclients.Client{},
token: validToken,
err: svcerr.ErrFailedPolicyUpdate,
err: svcerr.ErrAuthorization,
},
{
desc: "update client role to user role with failed to delete policy with error",
@@ -2349,7 +2349,7 @@ func TestResetSecret(t *testing.T) {
Identity: "",
},
},
err: repoerr.ErrNotFound,
err: nil,
},
{
desc: "reset secret with failed to update secret",