mirror of
https://github.com/absmach/supermq.git
synced 2026-06-23 06:30:22 +00:00
SMQ-2719 - Update list domain invitations endpoint (#2965)
Continuous Delivery / Build and Push (push) Has been cancelled
Check the consistency of generated files / check-generated-files (push) Has been cancelled
Check License Header / check-license (push) Has been cancelled
Deploy GitHub Pages / swagger-ui (push) Has been cancelled
Continuous Delivery / Build and Push (push) Has been cancelled
Check the consistency of generated files / check-generated-files (push) Has been cancelled
Check License Header / check-license (push) Has been cancelled
Deploy GitHub Pages / swagger-ui (push) Has been cancelled
Signed-off-by: Felix Gateru <felix.gateru@gmail.com>
This commit is contained in:
@@ -234,9 +234,8 @@ func listDomainInvitationsEndpoint(svc domains.Service) endpoint.Endpoint {
|
||||
if !ok {
|
||||
return nil, svcerr.ErrAuthorization
|
||||
}
|
||||
req.InvitationPageMeta.DomainID = session.DomainID
|
||||
|
||||
page, err := svc.ListInvitations(ctx, session, req.InvitationPageMeta)
|
||||
page, err := svc.ListDomainInvitations(ctx, session, req.InvitationPageMeta)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -258,7 +257,6 @@ func listUserInvitationsEndpoint(svc domains.Service) endpoint.Endpoint {
|
||||
if !ok {
|
||||
return nil, svcerr.ErrAuthorization
|
||||
}
|
||||
session.DomainID = req.DomainID
|
||||
|
||||
page, err := svc.ListInvitations(ctx, session, req.InvitationPageMeta)
|
||||
if err != nil {
|
||||
|
||||
@@ -1164,7 +1164,169 @@ func TestSendInvitation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestListInvitation(t *testing.T) {
|
||||
func TestListDomainInvitations(t *testing.T) {
|
||||
is, svc, auth := newDomainsServer()
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
token string
|
||||
session authn.Session
|
||||
domainID string
|
||||
query string
|
||||
contentType string
|
||||
status int
|
||||
svcErr error
|
||||
authnErr error
|
||||
}{
|
||||
{
|
||||
desc: "list invitations with valid request",
|
||||
token: validToken,
|
||||
domainID: domainID,
|
||||
status: http.StatusOK,
|
||||
contentType: contentType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "list invitations with invalid token",
|
||||
token: "",
|
||||
domainID: domainID,
|
||||
status: http.StatusUnauthorized,
|
||||
contentType: contentType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "list invitations with offset",
|
||||
token: validToken,
|
||||
domainID: domainID,
|
||||
query: "offset=1",
|
||||
status: http.StatusOK,
|
||||
contentType: contentType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "list invitations with invalid offset",
|
||||
token: validToken,
|
||||
domainID: domainID,
|
||||
query: "offset=invalid",
|
||||
status: http.StatusBadRequest,
|
||||
contentType: contentType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "list invitations with limit",
|
||||
token: validToken,
|
||||
query: "limit=1",
|
||||
domainID: domainID,
|
||||
status: http.StatusOK,
|
||||
contentType: contentType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "list invitations with invalid limit",
|
||||
token: validToken,
|
||||
domainID: domainID,
|
||||
query: "limit=invalid",
|
||||
status: http.StatusBadRequest,
|
||||
contentType: contentType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "list invitations with invitee_user_id",
|
||||
token: validToken,
|
||||
domainID: domainID,
|
||||
query: fmt.Sprintf("invitee_user_id=%s", validID),
|
||||
status: http.StatusOK,
|
||||
contentType: contentType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "list invitations with duplicate invitee_user_id",
|
||||
token: validToken,
|
||||
domainID: domainID,
|
||||
query: "invitee_user_id=1&invitee_user_id=2",
|
||||
status: http.StatusBadRequest,
|
||||
contentType: contentType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "list invitations with invited_by",
|
||||
token: validToken,
|
||||
domainID: domainID,
|
||||
query: fmt.Sprintf("invited_by=%s", validID),
|
||||
status: http.StatusOK,
|
||||
contentType: contentType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "list invitations with duplicate invited_by",
|
||||
token: validToken,
|
||||
domainID: domainID,
|
||||
query: "invited_by=1&invited_by=2",
|
||||
status: http.StatusBadRequest,
|
||||
contentType: contentType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "list invitations with state",
|
||||
token: validToken,
|
||||
domainID: domainID,
|
||||
query: "state=pending",
|
||||
status: http.StatusOK,
|
||||
contentType: contentType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "list invitations with invalid state",
|
||||
token: validToken,
|
||||
domainID: domainID,
|
||||
query: "state=invalid",
|
||||
status: http.StatusBadRequest,
|
||||
contentType: contentType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "list invitations with duplicate state",
|
||||
token: validToken,
|
||||
domainID: domainID,
|
||||
query: "state=all&state=all",
|
||||
status: http.StatusBadRequest,
|
||||
contentType: contentType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "list invitations with service error",
|
||||
token: validToken,
|
||||
domainID: invalid,
|
||||
status: http.StatusForbidden,
|
||||
contentType: contentType,
|
||||
svcErr: svcerr.ErrAuthorization,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
if tc.token == validToken {
|
||||
tc.session = authn.Session{UserID: userID, DomainID: tc.domainID}
|
||||
}
|
||||
authnCall := auth.On("Authenticate", mock.Anything, tc.token).Return(tc.session, tc.authnErr)
|
||||
repoCall := svc.On("ListDomainInvitations", mock.Anything, tc.session, mock.Anything).Return(domains.InvitationPage{}, tc.svcErr)
|
||||
req := testRequest{
|
||||
client: is.Client(),
|
||||
method: http.MethodGet,
|
||||
url: fmt.Sprintf("%s/domains/%s/invitations?", is.URL, tc.domainID) + tc.query,
|
||||
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)
|
||||
repoCall.Unset()
|
||||
authnCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestListUserInvitations(t *testing.T) {
|
||||
is, svc, auth := newDomainsServer()
|
||||
|
||||
cases := []struct {
|
||||
@@ -1223,22 +1385,6 @@ func TestListInvitation(t *testing.T) {
|
||||
contentType: contentType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "list invitations with invitee_user_id",
|
||||
token: validToken,
|
||||
query: fmt.Sprintf("invitee_user_id=%s", validID),
|
||||
status: http.StatusOK,
|
||||
contentType: contentType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "list invitations with duplicate invitee_user_id",
|
||||
token: validToken,
|
||||
query: "invitee_user_id=1&invitee_user_id=2",
|
||||
status: http.StatusBadRequest,
|
||||
contentType: contentType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "list invitations with invited_by",
|
||||
token: validToken,
|
||||
|
||||
+5
-2
@@ -201,11 +201,14 @@ type Service interface {
|
||||
ViewInvitation(ctx context.Context, session authn.Session, inviteeUserID, domainID string) (invitation Invitation, err error)
|
||||
|
||||
// ListInvitations returns a list of invitations.
|
||||
// By default, it will list invitations the current user has received.
|
||||
ListInvitations(ctx context.Context, session authn.Session, page InvitationPageMeta) (invitations InvitationPage, err error)
|
||||
|
||||
// ListDomainInvitations returns a list of invitations for the domain.
|
||||
// People who can list invitations are:
|
||||
// - platform administrators can list all invitations
|
||||
// - domain administrators can list invitations for their domain
|
||||
// By default, it will list invitations the current user has sent or received.
|
||||
ListInvitations(ctx context.Context, session authn.Session, page InvitationPageMeta) (invitations InvitationPage, err error)
|
||||
ListDomainInvitations(ctx context.Context, session authn.Session, page InvitationPageMeta) (invitations InvitationPage, err error)
|
||||
|
||||
// AcceptInvitation accepts an invitation by adding the user to the domain.
|
||||
AcceptInvitation(ctx context.Context, session authn.Session, domainID string) (invitation Invitation, err error)
|
||||
|
||||
+54
-22
@@ -13,21 +13,22 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
domainPrefix = "domain."
|
||||
domainCreate = domainPrefix + "create"
|
||||
domainRetrieve = domainPrefix + "retrieve"
|
||||
domainUpdate = domainPrefix + "update"
|
||||
domainEnable = domainPrefix + "enable"
|
||||
domainDisable = domainPrefix + "disable"
|
||||
domainFreeze = domainPrefix + "freeze"
|
||||
domainList = domainPrefix + "list"
|
||||
invitationPrefix = "invitation."
|
||||
invitationSend = invitationPrefix + "send"
|
||||
invitationAccept = invitationPrefix + "accept"
|
||||
invitationReject = invitationPrefix + "reject"
|
||||
invitationList = invitationPrefix + "list"
|
||||
invitationRetrieve = invitationPrefix + "retrieve"
|
||||
invitationDelete = invitationPrefix + "delete"
|
||||
domainPrefix = "domain."
|
||||
domainCreate = domainPrefix + "create"
|
||||
domainRetrieve = domainPrefix + "retrieve"
|
||||
domainUpdate = domainPrefix + "update"
|
||||
domainEnable = domainPrefix + "enable"
|
||||
domainDisable = domainPrefix + "disable"
|
||||
domainFreeze = domainPrefix + "freeze"
|
||||
domainList = domainPrefix + "list"
|
||||
invitationPrefix = "invitation."
|
||||
invitationSend = invitationPrefix + "send"
|
||||
invitationAccept = invitationPrefix + "accept"
|
||||
invitationReject = invitationPrefix + "reject"
|
||||
invitationList = invitationPrefix + "list"
|
||||
invitationListDomain = invitationPrefix + "list_domain"
|
||||
invitationRetrieve = invitationPrefix + "retrieve"
|
||||
invitationDelete = invitationPrefix + "delete"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -42,6 +43,7 @@ var (
|
||||
_ events.Event = (*sendInvitationEvent)(nil)
|
||||
_ events.Event = (*viewInvitationEvent)(nil)
|
||||
_ events.Event = (*listInvitationsEvent)(nil)
|
||||
_ events.Event = (*listDomainInvitationsEvent)(nil)
|
||||
_ events.Event = (*acceptInvitationEvent)(nil)
|
||||
_ events.Event = (*rejectInvitationEvent)(nil)
|
||||
_ events.Event = (*deleteInvitationEvent)(nil)
|
||||
@@ -351,12 +353,11 @@ type listInvitationsEvent struct {
|
||||
|
||||
func (lie listInvitationsEvent) Encode() (map[string]interface{}, error) {
|
||||
val := map[string]interface{}{
|
||||
"operation": invitationList,
|
||||
"offset": lie.Offset,
|
||||
"limit": lie.Limit,
|
||||
"user_id": lie.session.UserID,
|
||||
"token_type": lie.session.Type.String(),
|
||||
"super_admin": lie.session.SuperAdmin,
|
||||
"operation": invitationList,
|
||||
"offset": lie.Offset,
|
||||
"limit": lie.Limit,
|
||||
"user_id": lie.session.UserID,
|
||||
"token_type": lie.session.Type.String(),
|
||||
}
|
||||
|
||||
if lie.InvitedBy != "" {
|
||||
@@ -371,7 +372,38 @@ func (lie listInvitationsEvent) Encode() (map[string]interface{}, error) {
|
||||
if lie.RoleID != "" {
|
||||
val["role_id"] = lie.RoleID
|
||||
}
|
||||
if lie.State.String() != "" {
|
||||
if lie.State.String() != domains.UnknownState {
|
||||
val["state"] = lie.State.String()
|
||||
}
|
||||
|
||||
return val, nil
|
||||
}
|
||||
|
||||
type listDomainInvitationsEvent struct {
|
||||
domains.InvitationPageMeta
|
||||
session authn.Session
|
||||
}
|
||||
|
||||
func (lie listDomainInvitationsEvent) Encode() (map[string]interface{}, error) {
|
||||
val := map[string]interface{}{
|
||||
"operation": invitationListDomain,
|
||||
"offset": lie.Offset,
|
||||
"limit": lie.Limit,
|
||||
"domain_id": lie.session.DomainID,
|
||||
"token_type": lie.session.Type.String(),
|
||||
"super_admin": lie.session.SuperAdmin,
|
||||
}
|
||||
|
||||
if lie.InvitedBy != "" {
|
||||
val["invited_by"] = lie.InvitedBy
|
||||
}
|
||||
if lie.InviteeUserID != "" {
|
||||
val["invitee_user_id"] = lie.InviteeUserID
|
||||
}
|
||||
if lie.RoleID != "" {
|
||||
val["role_id"] = lie.RoleID
|
||||
}
|
||||
if lie.State.String() != domains.UnknownState {
|
||||
val["state"] = lie.State.String()
|
||||
}
|
||||
|
||||
|
||||
+33
-14
@@ -16,20 +16,21 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
supermqPrefix = "supermq."
|
||||
createStream = supermqPrefix + domainCreate
|
||||
retrieveStream = supermqPrefix + domainRetrieve
|
||||
updateStream = supermqPrefix + domainUpdate
|
||||
enableStream = supermqPrefix + domainEnable
|
||||
disableStream = supermqPrefix + domainDisable
|
||||
freezeStream = supermqPrefix + domainFreeze
|
||||
listStream = supermqPrefix + domainList
|
||||
sendInvitationStream = supermqPrefix + invitationSend
|
||||
acceptInvitationStream = supermqPrefix + invitationAccept
|
||||
rejectInvitationStream = supermqPrefix + invitationReject
|
||||
listInvitationsStream = supermqPrefix + invitationList
|
||||
retrieveInvitationStream = supermqPrefix + invitationRetrieve
|
||||
deleteInvitationStream = supermqPrefix + invitationDelete
|
||||
supermqPrefix = "supermq."
|
||||
createStream = supermqPrefix + domainCreate
|
||||
retrieveStream = supermqPrefix + domainRetrieve
|
||||
updateStream = supermqPrefix + domainUpdate
|
||||
enableStream = supermqPrefix + domainEnable
|
||||
disableStream = supermqPrefix + domainDisable
|
||||
freezeStream = supermqPrefix + domainFreeze
|
||||
listStream = supermqPrefix + domainList
|
||||
sendInvitationStream = supermqPrefix + invitationSend
|
||||
acceptInvitationStream = supermqPrefix + invitationAccept
|
||||
rejectInvitationStream = supermqPrefix + invitationReject
|
||||
listInvitationsStream = supermqPrefix + invitationList
|
||||
listDomainInvitationsStream = supermqPrefix + invitationListDomain
|
||||
retrieveInvitationStream = supermqPrefix + invitationRetrieve
|
||||
deleteInvitationStream = supermqPrefix + invitationDelete
|
||||
)
|
||||
|
||||
var _ domains.Service = (*eventStore)(nil)
|
||||
@@ -252,6 +253,24 @@ func (es *eventStore) ListInvitations(ctx context.Context, session authn.Session
|
||||
return ip, nil
|
||||
}
|
||||
|
||||
func (es *eventStore) ListDomainInvitations(ctx context.Context, session authn.Session, pm domains.InvitationPageMeta) (domains.InvitationPage, error) {
|
||||
ip, err := es.svc.ListDomainInvitations(ctx, session, pm)
|
||||
if err != nil {
|
||||
return ip, err
|
||||
}
|
||||
|
||||
event := listDomainInvitationsEvent{
|
||||
InvitationPageMeta: pm,
|
||||
session: session,
|
||||
}
|
||||
|
||||
if err := es.Publish(ctx, listDomainInvitationsStream, event); err != nil {
|
||||
return ip, err
|
||||
}
|
||||
|
||||
return ip, nil
|
||||
}
|
||||
|
||||
func (es *eventStore) AcceptInvitation(ctx context.Context, session authn.Session, domainID string) (domains.Invitation, error) {
|
||||
inv, err := es.svc.AcceptInvitation(ctx, session, domainID)
|
||||
if err != nil {
|
||||
|
||||
@@ -226,23 +226,6 @@ func (am *authorizationMiddleware) ViewInvitation(ctx context.Context, session a
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) ListInvitations(ctx context.Context, session authn.Session, page domains.InvitationPageMeta) (invs domains.InvitationPage, err error) {
|
||||
session.DomainUserID = auth.EncodeDomainUserID(session.DomainID, session.UserID)
|
||||
if err := am.extAuthorize(ctx, session.UserID, policies.AdminPermission, policies.PlatformType, policies.SuperMQObject); err == nil {
|
||||
session.SuperAdmin = true
|
||||
page.DomainID = ""
|
||||
}
|
||||
|
||||
if !session.SuperAdmin {
|
||||
switch {
|
||||
case page.DomainID != "":
|
||||
if err := am.extAuthorize(ctx, session.DomainUserID, policies.AdminPermission, policies.DomainType, page.DomainID); err != nil {
|
||||
return domains.InvitationPage{}, err
|
||||
}
|
||||
default:
|
||||
page.InvitedByOrUserID = session.UserID
|
||||
}
|
||||
}
|
||||
|
||||
params := map[string]any{
|
||||
"page": page,
|
||||
}
|
||||
@@ -253,6 +236,21 @@ func (am *authorizationMiddleware) ListInvitations(ctx context.Context, session
|
||||
return am.svc.ListInvitations(ctx, session, page)
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) ListDomainInvitations(ctx context.Context, session authn.Session, page domains.InvitationPageMeta) (invs domains.InvitationPage, err error) {
|
||||
if err := am.extAuthorize(ctx, session.DomainUserID, policies.AdminPermission, policies.DomainType, session.DomainID); err != nil {
|
||||
return domains.InvitationPage{}, err
|
||||
}
|
||||
|
||||
params := map[string]any{
|
||||
"page": page,
|
||||
}
|
||||
if err := am.callOut(ctx, session, domains.OpListDomainInvitations.String(domains.OperationNames), params); err != nil {
|
||||
return domains.InvitationPage{}, err
|
||||
}
|
||||
|
||||
return am.svc.ListDomainInvitations(ctx, session, page)
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) AcceptInvitation(ctx context.Context, session authn.Session, domainID string) (inv domains.Invitation, err error) {
|
||||
params := map[string]any{
|
||||
"domain": domainID,
|
||||
|
||||
@@ -229,6 +229,26 @@ func (lm *loggingMiddleware) ListInvitations(ctx context.Context, session authn.
|
||||
return lm.svc.ListInvitations(ctx, session, pm)
|
||||
}
|
||||
|
||||
func (lm *loggingMiddleware) ListDomainInvitations(ctx context.Context, session authn.Session, pm domains.InvitationPageMeta) (invs domains.InvitationPage, err error) {
|
||||
defer func(begin time.Time) {
|
||||
args := []any{
|
||||
slog.String("duration", time.Since(begin).String()),
|
||||
slog.Group("page",
|
||||
slog.Uint64("offset", pm.Offset),
|
||||
slog.Uint64("limit", pm.Limit),
|
||||
slog.Uint64("total", invs.Total),
|
||||
),
|
||||
}
|
||||
if err != nil {
|
||||
args = append(args, slog.Any("error", err))
|
||||
lm.logger.Warn("List domain invitations failed", args...)
|
||||
return
|
||||
}
|
||||
lm.logger.Info("List domain invitations completed successfully", args...)
|
||||
}(time.Now())
|
||||
return lm.svc.ListDomainInvitations(ctx, session, pm)
|
||||
}
|
||||
|
||||
func (lm *loggingMiddleware) AcceptInvitation(ctx context.Context, session authn.Session, domainID string) (inv domains.Invitation, err error) {
|
||||
defer func(begin time.Time) {
|
||||
args := []any{
|
||||
|
||||
@@ -117,6 +117,14 @@ func (mm *metricsMiddleware) ListInvitations(ctx context.Context, session authn.
|
||||
return mm.svc.ListInvitations(ctx, session, pm)
|
||||
}
|
||||
|
||||
func (mm *metricsMiddleware) ListDomainInvitations(ctx context.Context, session authn.Session, pm domains.InvitationPageMeta) (invs domains.InvitationPage, err error) {
|
||||
defer func(begin time.Time) {
|
||||
mm.counter.With("method", "list_invitee_invitations").Add(1)
|
||||
mm.latency.With("method", "list_invitee_invitations").Observe(time.Since(begin).Seconds())
|
||||
}(time.Now())
|
||||
return mm.svc.ListDomainInvitations(ctx, session, pm)
|
||||
}
|
||||
|
||||
func (mm *metricsMiddleware) AcceptInvitation(ctx context.Context, session authn.Session, domainID string) (inv domains.Invitation, err error) {
|
||||
defer func(begin time.Time) {
|
||||
mm.counter.With("method", "accept_invitation").Add(1)
|
||||
|
||||
@@ -495,6 +495,62 @@ func (_c *Service_ListAvailableActions_Call) RunAndReturn(run func(ctx context.C
|
||||
return _c
|
||||
}
|
||||
|
||||
// ListDomainInvitations provides a mock function for the type Service
|
||||
func (_mock *Service) ListDomainInvitations(ctx context.Context, session authn.Session, page domains.InvitationPageMeta) (domains.InvitationPage, error) {
|
||||
ret := _mock.Called(ctx, session, page)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for ListDomainInvitations")
|
||||
}
|
||||
|
||||
var r0 domains.InvitationPage
|
||||
var r1 error
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, authn.Session, domains.InvitationPageMeta) (domains.InvitationPage, error)); ok {
|
||||
return returnFunc(ctx, session, page)
|
||||
}
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, authn.Session, domains.InvitationPageMeta) domains.InvitationPage); ok {
|
||||
r0 = returnFunc(ctx, session, page)
|
||||
} else {
|
||||
r0 = ret.Get(0).(domains.InvitationPage)
|
||||
}
|
||||
if returnFunc, ok := ret.Get(1).(func(context.Context, authn.Session, domains.InvitationPageMeta) error); ok {
|
||||
r1 = returnFunc(ctx, session, page)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Service_ListDomainInvitations_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListDomainInvitations'
|
||||
type Service_ListDomainInvitations_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// ListDomainInvitations is a helper method to define mock.On call
|
||||
// - ctx
|
||||
// - session
|
||||
// - page
|
||||
func (_e *Service_Expecter) ListDomainInvitations(ctx interface{}, session interface{}, page interface{}) *Service_ListDomainInvitations_Call {
|
||||
return &Service_ListDomainInvitations_Call{Call: _e.mock.On("ListDomainInvitations", ctx, session, page)}
|
||||
}
|
||||
|
||||
func (_c *Service_ListDomainInvitations_Call) Run(run func(ctx context.Context, session authn.Session, page domains.InvitationPageMeta)) *Service_ListDomainInvitations_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(authn.Session), args[2].(domains.InvitationPageMeta))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *Service_ListDomainInvitations_Call) Return(invitations domains.InvitationPage, err error) *Service_ListDomainInvitations_Call {
|
||||
_c.Call.Return(invitations, err)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *Service_ListDomainInvitations_Call) RunAndReturn(run func(ctx context.Context, session authn.Session, page domains.InvitationPageMeta) (domains.InvitationPage, error)) *Service_ListDomainInvitations_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// ListDomains provides a mock function for the type Service
|
||||
func (_mock *Service) ListDomains(ctx context.Context, sesssion authn.Session, page domains.Page) (domains.DomainsPage, error) {
|
||||
ret := _mock.Called(ctx, sesssion, page)
|
||||
|
||||
@@ -157,7 +157,7 @@ func TestSaveInvitation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvitationRetrieve(t *testing.T) {
|
||||
func TestRetrieveInvitation(t *testing.T) {
|
||||
t.Cleanup(func() {
|
||||
_, err := db.Exec("DELETE FROM invitations")
|
||||
require.Nil(t, err, fmt.Sprintf("clean invitations unexpected error: %s", err))
|
||||
@@ -245,7 +245,7 @@ func TestInvitationRetrieve(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvitationRetrieveAll(t *testing.T) {
|
||||
func TestRetrieveAllInvitations(t *testing.T) {
|
||||
t.Cleanup(func() {
|
||||
_, err := db.Exec("DELETE FROM invitations")
|
||||
require.Nil(t, err, fmt.Sprintf("clean invitations unexpected error: %s", err))
|
||||
@@ -633,7 +633,7 @@ func TestInvitationRetrieveAll(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvitationUpdateConfirmation(t *testing.T) {
|
||||
func TestUpdateConfirmation(t *testing.T) {
|
||||
t.Cleanup(func() {
|
||||
_, err := db.Exec("DELETE FROM invitations")
|
||||
require.Nil(t, err, fmt.Sprintf("clean invitations unexpected error: %s", err))
|
||||
@@ -697,7 +697,7 @@ func TestInvitationUpdateConfirmation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvitationUpdateRejection(t *testing.T) {
|
||||
func TestUpdateRejection(t *testing.T) {
|
||||
t.Cleanup(func() {
|
||||
_, err := db.Exec("DELETE FROM invitations")
|
||||
require.Nil(t, err, fmt.Sprintf("clean invitations unexpected error: %s", err))
|
||||
@@ -761,7 +761,7 @@ func TestInvitationUpdateRejection(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvitationDelete(t *testing.T) {
|
||||
func TestDeleteInvitation(t *testing.T) {
|
||||
t.Cleanup(func() {
|
||||
_, err := db.Exec("DELETE FROM invitations")
|
||||
require.Nil(t, err, fmt.Sprintf("clean invitations unexpected error: %s", err))
|
||||
|
||||
@@ -20,6 +20,7 @@ const (
|
||||
OpListDomains
|
||||
OpViewInvitation
|
||||
OpListInvitations
|
||||
OpListDomainInvitations
|
||||
OpRejectInvitation
|
||||
OpDeleteInvitation
|
||||
)
|
||||
@@ -43,6 +44,7 @@ var OperationNames = []string{
|
||||
"OpListDomains",
|
||||
"OpViewInvitation",
|
||||
"OpListInvitations",
|
||||
"OpListDomainInvitations",
|
||||
"OpRejectInvitation",
|
||||
"OpDeleteInvitation",
|
||||
}
|
||||
|
||||
+11
-1
@@ -244,9 +244,19 @@ func (svc *service) ViewInvitation(ctx context.Context, session authn.Session, i
|
||||
}
|
||||
|
||||
func (svc *service) ListInvitations(ctx context.Context, session authn.Session, page InvitationPageMeta) (invitations InvitationPage, err error) {
|
||||
page.InviteeUserID = session.UserID
|
||||
ip, err := svc.repo.RetrieveAllInvitations(ctx, page)
|
||||
if err != nil {
|
||||
return InvitationPage{}, err
|
||||
return InvitationPage{}, errors.Wrap(svcerr.ErrViewEntity, err)
|
||||
}
|
||||
return ip, nil
|
||||
}
|
||||
|
||||
func (svc *service) ListDomainInvitations(ctx context.Context, session authn.Session, page InvitationPageMeta) (invitations InvitationPage, err error) {
|
||||
page.DomainID = session.DomainID
|
||||
ip, err := svc.repo.RetrieveAllInvitations(ctx, page)
|
||||
if err != nil {
|
||||
return InvitationPage{}, errors.Wrap(svcerr.ErrViewEntity, err)
|
||||
}
|
||||
return ip, nil
|
||||
}
|
||||
|
||||
+65
-2
@@ -829,7 +829,7 @@ func TestListInvitations(t *testing.T) {
|
||||
desc: "list invitations unsuccessful",
|
||||
session: validSession,
|
||||
page: validPageMeta,
|
||||
err: repoerr.ErrViewEntity,
|
||||
err: svcerr.ErrViewEntity,
|
||||
resp: domains.InvitationPage{},
|
||||
repoErr: repoerr.ErrViewEntity,
|
||||
},
|
||||
@@ -839,7 +839,70 @@ func TestListInvitations(t *testing.T) {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
repoCall := drepo.On("RetrieveAllInvitations", context.Background(), mock.Anything).Return(tc.resp, tc.repoErr)
|
||||
resp, err := svc.ListInvitations(context.Background(), tc.session, tc.page)
|
||||
assert.Equal(t, tc.err, err, tc.desc)
|
||||
assert.True(t, errors.Contains(err, tc.err), tc.desc)
|
||||
assert.Equal(t, tc.resp, resp, tc.desc)
|
||||
repoCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestListDomainInvitations(t *testing.T) {
|
||||
svc := newService()
|
||||
|
||||
validPageMeta := domains.InvitationPageMeta{
|
||||
Offset: 0,
|
||||
Limit: 10,
|
||||
}
|
||||
validResp := domains.InvitationPage{
|
||||
Total: 1,
|
||||
Offset: 0,
|
||||
Limit: 10,
|
||||
Invitations: []domains.Invitation{
|
||||
{
|
||||
InvitedBy: testsutil.GenerateUUID(t),
|
||||
InviteeUserID: testsutil.GenerateUUID(t),
|
||||
DomainID: testsutil.GenerateUUID(t),
|
||||
RoleID: testsutil.GenerateUUID(t),
|
||||
RoleName: "admin",
|
||||
CreatedAt: time.Now().Add(-time.Hour),
|
||||
UpdatedAt: time.Now().Add(-time.Hour),
|
||||
ConfirmedAt: time.Now().Add(-time.Hour),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
session authn.Session
|
||||
page domains.InvitationPageMeta
|
||||
resp domains.InvitationPage
|
||||
repoErr error
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "list domain invitations successful",
|
||||
session: validSession,
|
||||
page: validPageMeta,
|
||||
resp: validResp,
|
||||
repoErr: nil,
|
||||
err: nil,
|
||||
},
|
||||
|
||||
{
|
||||
desc: "list domain invitations unsuccessful",
|
||||
session: validSession,
|
||||
page: validPageMeta,
|
||||
resp: domains.InvitationPage{},
|
||||
repoErr: repoerr.ErrViewEntity,
|
||||
err: svcerr.ErrViewEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
repoCall := drepo.On("RetrieveAllInvitations", context.Background(), mock.Anything).Return(tc.resp, tc.repoErr)
|
||||
resp, err := svc.ListDomainInvitations(context.Background(), tc.session, tc.page)
|
||||
assert.True(t, errors.Contains(err, tc.err), tc.desc)
|
||||
assert.Equal(t, tc.resp, resp, tc.desc)
|
||||
repoCall.Unset()
|
||||
})
|
||||
|
||||
+6
-6
@@ -22,11 +22,11 @@ const (
|
||||
|
||||
// String representation of the possible state values.
|
||||
const (
|
||||
all = "all"
|
||||
pending = "pending"
|
||||
accepted = "accepted"
|
||||
rejected = "rejected"
|
||||
unknown = "unknown"
|
||||
all = "all"
|
||||
pending = "pending"
|
||||
accepted = "accepted"
|
||||
rejected = "rejected"
|
||||
UnknownState = "unknown"
|
||||
)
|
||||
|
||||
// String converts invitation state to string literal.
|
||||
@@ -41,7 +41,7 @@ func (s State) String() string {
|
||||
case Rejected:
|
||||
return rejected
|
||||
default:
|
||||
return unknown
|
||||
return UnknownState
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +116,17 @@ func (tm *tracingMiddleware) ListInvitations(ctx context.Context, session authn.
|
||||
return tm.svc.ListInvitations(ctx, session, pm)
|
||||
}
|
||||
|
||||
func (tm *tracingMiddleware) ListDomainInvitations(ctx context.Context, session authn.Session, pm domains.InvitationPageMeta) (invs domains.InvitationPage, err error) {
|
||||
ctx, span := tracing.StartSpan(ctx, tm.tracer, "list_domain_invitations", trace.WithAttributes(
|
||||
attribute.Int("limit", int(pm.Limit)),
|
||||
attribute.Int("offset", int(pm.Offset)),
|
||||
attribute.String("domain_id", session.DomainID),
|
||||
))
|
||||
defer span.End()
|
||||
|
||||
return tm.svc.ListDomainInvitations(ctx, session, pm)
|
||||
}
|
||||
|
||||
func (tm *tracingMiddleware) AcceptInvitation(ctx context.Context, session authn.Session, domainID string) (inv domains.Invitation, err error) {
|
||||
ctx, span := tracing.StartSpan(ctx, tm.tracer, "accept_invitation", trace.WithAttributes(
|
||||
attribute.String("domain_id", domainID),
|
||||
|
||||
Reference in New Issue
Block a user