mirror of
https://github.com/absmach/supermq.git
synced 2026-06-23 07:30:25 +00:00
NOISSUE - Remove domain prefix for invitation (#2513)
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
This commit is contained in:
+58
-25
@@ -27,7 +27,7 @@ tags:
|
||||
url: https://docs.magistrala.abstractmachines.fr/
|
||||
|
||||
paths:
|
||||
/{domainID}/invitations:
|
||||
/invitations:
|
||||
post:
|
||||
operationId: sendInvitation
|
||||
tags:
|
||||
@@ -35,8 +35,6 @@ paths:
|
||||
summary: Send invitation
|
||||
description: |
|
||||
Send invitation to user to join domain.
|
||||
parameters:
|
||||
- $ref: "auth.yml#/components/parameters/DomainID"
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/SendInvitationReq"
|
||||
security:
|
||||
@@ -49,7 +47,7 @@ paths:
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Unauthorized access to the domain ID.
|
||||
description: Failed to perform authorization over the entity.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"409":
|
||||
@@ -74,7 +72,7 @@ paths:
|
||||
- $ref: "#/components/parameters/Offset"
|
||||
- $ref: "#/components/parameters/UserID"
|
||||
- $ref: "#/components/parameters/InvitedBy"
|
||||
- $ref: "auth.yml#/components/parameters/DomainID"
|
||||
- $ref: "#/components/parameters/DomainID"
|
||||
- $ref: "#/components/parameters/Relation"
|
||||
- $ref: "#/components/parameters/State"
|
||||
security:
|
||||
@@ -89,7 +87,7 @@ paths:
|
||||
Missing or invalid access token provided.
|
||||
This endpoint is available only for administrators.
|
||||
"403":
|
||||
description: Unauthorized access to the domain ID.
|
||||
description: Failed to perform authorization over the entity.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"422":
|
||||
@@ -97,7 +95,7 @@ paths:
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/{domainID}/invitations/accept:
|
||||
/invitations/accept:
|
||||
post:
|
||||
operationId: acceptInvitation
|
||||
summary: Accept invitation
|
||||
@@ -107,8 +105,8 @@ paths:
|
||||
- Invitations
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- $ref: "auth.yml#/components/parameters/DomainID"
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/AcceptInvitationReq"
|
||||
responses:
|
||||
"204":
|
||||
description: Invitation accepted.
|
||||
@@ -118,12 +116,10 @@ paths:
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/{domainID}/invitations/reject:
|
||||
/invitations/reject:
|
||||
post:
|
||||
operationId: rejectInvitation
|
||||
summary: Reject invitation
|
||||
@@ -133,8 +129,8 @@ paths:
|
||||
- Invitations
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- $ref: "auth.yml#/components/parameters/DomainID"
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/AcceptInvitationReq"
|
||||
responses:
|
||||
"204":
|
||||
description: Invitation rejected.
|
||||
@@ -144,12 +140,10 @@ paths:
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/{domainID}/invitations/users/{user_id}:
|
||||
/invitations/{user_id}/{domain_id}:
|
||||
get:
|
||||
operationId: getInvitation
|
||||
summary: Retrieves a specific invitation
|
||||
@@ -159,7 +153,7 @@ paths:
|
||||
- Invitations
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/user_id"
|
||||
- $ref: "auth.yml#/components/parameters/DomainID"
|
||||
- $ref: "#/components/parameters/domain_id"
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
@@ -170,11 +164,9 @@ paths:
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Unauthorized access to the domain ID.
|
||||
description: Failed to perform authorization over the entity.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
@@ -189,7 +181,7 @@ paths:
|
||||
- Invitations
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/user_id"
|
||||
- $ref: "auth.yml#/components/parameters/DomainID"
|
||||
- $ref: "#/components/parameters/domain_id"
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
@@ -198,13 +190,11 @@ paths:
|
||||
"400":
|
||||
description: Failed due to malformed JSON.
|
||||
"403":
|
||||
description: Unauthorized access to the domain ID.
|
||||
description: Failed to perform authorization over the entity.
|
||||
"404":
|
||||
description: Failed due to non existing user.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
@@ -230,6 +220,11 @@ components:
|
||||
format: uuid
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
description: User unique identifier.
|
||||
domain_id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
description: Domain unique identifier.
|
||||
relation:
|
||||
type: string
|
||||
enum:
|
||||
@@ -251,6 +246,7 @@ components:
|
||||
description: Resend invitation.
|
||||
required:
|
||||
- user_id
|
||||
- domain_id
|
||||
- relation
|
||||
|
||||
Invitation:
|
||||
@@ -406,6 +402,26 @@ components:
|
||||
required: true
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
|
||||
DomainID:
|
||||
name: domain_id
|
||||
description: Unique identifier for a domain.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: false
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
|
||||
domain_id:
|
||||
name: domain_id
|
||||
description: Unique identifier for a domain.
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
|
||||
InvitedBy:
|
||||
name: invited_by
|
||||
description: Unique identifier for a user that invited the user.
|
||||
@@ -458,6 +474,22 @@ components:
|
||||
schema:
|
||||
$ref: "#/components/schemas/SendInvitationReqObj"
|
||||
|
||||
AcceptInvitationReq:
|
||||
description: JSON-formatted document describing request for accepting invitation
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
domain_id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
description: Domain unique identifier.
|
||||
required:
|
||||
- domain_id
|
||||
|
||||
responses:
|
||||
InvitationRes:
|
||||
description: Data retrieved.
|
||||
@@ -470,6 +502,7 @@ components:
|
||||
operationId: deleteInvitation
|
||||
parameters:
|
||||
user_id: $response.body#/user_id
|
||||
domain_id: $response.body#/domain_id
|
||||
|
||||
InvitationPageRes:
|
||||
description: Data retrieved.
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ var cmdInvitations = []cobra.Command{
|
||||
Limit: Limit,
|
||||
}
|
||||
if args[0] == all {
|
||||
l, err := sdk.Invitations(pageMetadata, args[1], args[2])
|
||||
l, err := sdk.Invitations(pageMetadata, args[1])
|
||||
if err != nil {
|
||||
logErrorCmd(*cmd, err)
|
||||
return
|
||||
|
||||
@@ -113,7 +113,6 @@ func TestGetInvitationCmd(t *testing.T) {
|
||||
desc: "get all invitations successfully",
|
||||
args: []string{
|
||||
all,
|
||||
domain.ID,
|
||||
token,
|
||||
},
|
||||
page: mgsdk.InvitationPage{
|
||||
@@ -148,7 +147,6 @@ func TestGetInvitationCmd(t *testing.T) {
|
||||
desc: "get all invitations with invalid token",
|
||||
args: []string{
|
||||
all,
|
||||
domain.ID,
|
||||
invalidToken,
|
||||
},
|
||||
logType: errLog,
|
||||
@@ -171,7 +169,7 @@ func TestGetInvitationCmd(t *testing.T) {
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
sdkCall := sdkMock.On("Invitation", tc.args[0], tc.args[1], mock.Anything).Return(tc.inv, tc.sdkErr)
|
||||
sdkCall1 := sdkMock.On("Invitations", mock.Anything, tc.args[1], tc.args[2]).Return(tc.page, tc.sdkErr)
|
||||
sdkCall1 := sdkMock.On("Invitations", mock.Anything, tc.args[1]).Return(tc.page, tc.sdkErr)
|
||||
|
||||
out := executeCommand(t, rootCmd, append([]string{getCmd}, tc.args...)...)
|
||||
|
||||
|
||||
+10
-11
@@ -24,15 +24,14 @@ func sendInvitationEndpoint(svc invitations.Service) endpoint.Endpoint {
|
||||
if err := req.validate(); err != nil {
|
||||
return nil, errors.Wrap(apiutil.ErrValidation, err)
|
||||
}
|
||||
|
||||
session, ok := ctx.Value(api.SessionKey).(authn.Session)
|
||||
if !ok {
|
||||
return nil, svcerr.ErrAuthorization
|
||||
}
|
||||
|
||||
session.DomainID = req.DomainID
|
||||
invitation := invitations.Invitation{
|
||||
UserID: req.UserID,
|
||||
DomainID: session.DomainID,
|
||||
DomainID: req.DomainID,
|
||||
Relation: req.Relation,
|
||||
Resend: req.Resend,
|
||||
}
|
||||
@@ -57,8 +56,7 @@ func viewInvitationEndpoint(svc invitations.Service) endpoint.Endpoint {
|
||||
if !ok {
|
||||
return nil, svcerr.ErrAuthorization
|
||||
}
|
||||
req.domainID = session.DomainID
|
||||
|
||||
session.DomainID = req.domainID
|
||||
invitation, err := svc.ViewInvitation(ctx, session, req.userID, req.domainID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -81,8 +79,8 @@ func listInvitationsEndpoint(svc invitations.Service) endpoint.Endpoint {
|
||||
if !ok {
|
||||
return nil, svcerr.ErrAuthorization
|
||||
}
|
||||
session.DomainID = req.DomainID
|
||||
|
||||
req.Page.DomainID = session.DomainID
|
||||
page, err := svc.ListInvitations(ctx, session, req.Page)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -105,8 +103,8 @@ func acceptInvitationEndpoint(svc invitations.Service) endpoint.Endpoint {
|
||||
if !ok {
|
||||
return nil, svcerr.ErrAuthorization
|
||||
}
|
||||
req.domainID = session.DomainID
|
||||
if err := svc.AcceptInvitation(ctx, session, req.domainID); err != nil {
|
||||
|
||||
if err := svc.AcceptInvitation(ctx, session, req.DomainID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -125,8 +123,8 @@ func rejectInvitationEndpoint(svc invitations.Service) endpoint.Endpoint {
|
||||
if !ok {
|
||||
return nil, svcerr.ErrAuthorization
|
||||
}
|
||||
req.domainID = session.DomainID
|
||||
if err := svc.RejectInvitation(ctx, session, req.domainID); err != nil {
|
||||
|
||||
if err := svc.RejectInvitation(ctx, session, req.DomainID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -145,7 +143,8 @@ func deleteInvitationEndpoint(svc invitations.Service) endpoint.Endpoint {
|
||||
if !ok {
|
||||
return nil, svcerr.ErrAuthorization
|
||||
}
|
||||
req.domainID = session.DomainID
|
||||
session.DomainID = req.domainID
|
||||
|
||||
if err := svc.DeleteInvitation(ctx, session, req.userID, req.domainID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -70,7 +70,6 @@ func TestSendInvitation(t *testing.T) {
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
domainID string
|
||||
token string
|
||||
data string
|
||||
contentType string
|
||||
@@ -81,9 +80,8 @@ func TestSendInvitation(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
desc: "valid request",
|
||||
domainID: domainID,
|
||||
token: validToken,
|
||||
data: fmt.Sprintf(`{"user_id": "%s", "relation": "%s"}`, validID, "domain"),
|
||||
data: fmt.Sprintf(`{"user_id": "%s","domain_id": "%s", "relation": "%s"}`, validID, domainID, "domain"),
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainID: domainID, DomainUserID: domainID + "_" + validID},
|
||||
status: http.StatusCreated,
|
||||
contentType: validContenType,
|
||||
@@ -91,27 +89,24 @@ func TestSendInvitation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "invalid token",
|
||||
domainID: domainID,
|
||||
token: "",
|
||||
data: fmt.Sprintf(`{"user_id": "%s", "relation": "%s"}`, validID, "domain"),
|
||||
data: fmt.Sprintf(`{"user_id": "%s","domain_id": "%s", "relation": "%s"}`, validID, validID, "domain"),
|
||||
status: http.StatusUnauthorized,
|
||||
contentType: validContenType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "empty domain_id",
|
||||
domainID: "",
|
||||
token: validToken,
|
||||
data: fmt.Sprintf(`{"user_id": "%s", "relation": "%s"}`, validID, "domain"),
|
||||
data: fmt.Sprintf(`{"user_id": "%s","domain_id": "%s", "relation": "%s"}`, validID, "", "domain"),
|
||||
status: http.StatusBadRequest,
|
||||
contentType: validContenType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "invalid content type",
|
||||
domainID: domainID,
|
||||
token: validToken,
|
||||
data: fmt.Sprintf(`{"user_id": "%s", "relation": "%s"}`, validID, "domain"),
|
||||
data: fmt.Sprintf(`{"user_id": "%s","domain_id": "%s", "relation": "%s"}`, validID, validID, "domain"),
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainID: domainID, DomainUserID: domainID + "_" + validID},
|
||||
status: http.StatusUnsupportedMediaType,
|
||||
contentType: "text/plain",
|
||||
@@ -119,7 +114,6 @@ func TestSendInvitation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "invalid data",
|
||||
domainID: domainID,
|
||||
token: validToken,
|
||||
data: `data`,
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainID: domainID, DomainUserID: domainID + "_" + validID},
|
||||
@@ -129,9 +123,8 @@ func TestSendInvitation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "with service error",
|
||||
domainID: domainID,
|
||||
token: validToken,
|
||||
data: fmt.Sprintf(`{"user_id": "%s", "relation": "%s"}`, validID, "domain"),
|
||||
data: fmt.Sprintf(`{"user_id": "%s", "domain_id": "%s", "relation": "%s"}`, validID, domainID, "domain"),
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainID: domainID, DomainUserID: domainID + "_" + validID},
|
||||
status: http.StatusForbidden,
|
||||
contentType: validContenType,
|
||||
@@ -146,7 +139,7 @@ func TestSendInvitation(t *testing.T) {
|
||||
req := testRequest{
|
||||
client: is.Client(),
|
||||
method: http.MethodPost,
|
||||
url: is.URL + "/" + tc.domainID + "/invitations",
|
||||
url: is.URL + "/invitations",
|
||||
token: tc.token,
|
||||
contentType: tc.contentType,
|
||||
body: strings.NewReader(tc.data),
|
||||
@@ -166,7 +159,6 @@ func TestListInvitation(t *testing.T) {
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
domainID string
|
||||
token string
|
||||
query string
|
||||
contentType string
|
||||
@@ -177,8 +169,7 @@ func TestListInvitation(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
desc: "valid request",
|
||||
domainID: domainID,
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainID: domainID, DomainUserID: domainID + "_" + validID},
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainUserID: domainID + "_" + validID},
|
||||
token: validToken,
|
||||
status: http.StatusOK,
|
||||
contentType: validContenType,
|
||||
@@ -186,7 +177,6 @@ func TestListInvitation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "invalid token",
|
||||
domainID: domainID,
|
||||
token: "",
|
||||
status: http.StatusUnauthorized,
|
||||
contentType: validContenType,
|
||||
@@ -194,8 +184,7 @@ func TestListInvitation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "with offset",
|
||||
domainID: domainID,
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainID: domainID, DomainUserID: domainID + "_" + validID},
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainUserID: domainID + "_" + validID},
|
||||
token: validToken,
|
||||
query: "offset=1",
|
||||
status: http.StatusOK,
|
||||
@@ -204,7 +193,6 @@ func TestListInvitation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "with invalid offset",
|
||||
domainID: domainID,
|
||||
token: validToken,
|
||||
query: "offset=invalid",
|
||||
status: http.StatusBadRequest,
|
||||
@@ -213,8 +201,7 @@ func TestListInvitation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "with limit",
|
||||
domainID: domainID,
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainID: domainID, DomainUserID: domainID + "_" + validID},
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainUserID: domainID + "_" + validID},
|
||||
token: validToken,
|
||||
query: "limit=1",
|
||||
status: http.StatusOK,
|
||||
@@ -223,7 +210,6 @@ func TestListInvitation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "with invalid limit",
|
||||
domainID: domainID,
|
||||
token: validToken,
|
||||
query: "limit=invalid",
|
||||
status: http.StatusBadRequest,
|
||||
@@ -232,8 +218,7 @@ func TestListInvitation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "with user_id",
|
||||
domainID: domainID,
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainID: domainID, DomainUserID: domainID + "_" + validID},
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainUserID: domainID + "_" + validID},
|
||||
token: validToken,
|
||||
query: fmt.Sprintf("user_id=%s", validID),
|
||||
status: http.StatusOK,
|
||||
@@ -242,8 +227,7 @@ func TestListInvitation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "with duplicate user_id",
|
||||
domainID: domainID,
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainID: domainID, DomainUserID: domainID + "_" + validID},
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainUserID: domainID + "_" + validID},
|
||||
token: validToken,
|
||||
query: "user_id=1&user_id=2",
|
||||
status: http.StatusBadRequest,
|
||||
@@ -252,8 +236,7 @@ func TestListInvitation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "with invited_by",
|
||||
domainID: domainID,
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainID: domainID, DomainUserID: domainID + "_" + validID},
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainUserID: domainID + "_" + validID},
|
||||
token: validToken,
|
||||
query: fmt.Sprintf("invited_by=%s", validID),
|
||||
status: http.StatusOK,
|
||||
@@ -262,8 +245,7 @@ func TestListInvitation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "with duplicate invited_by",
|
||||
domainID: domainID,
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainID: domainID, DomainUserID: domainID + "_" + validID},
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainUserID: domainID + "_" + validID},
|
||||
token: validToken,
|
||||
query: "invited_by=1&invited_by=2",
|
||||
status: http.StatusBadRequest,
|
||||
@@ -272,8 +254,7 @@ func TestListInvitation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "with relation",
|
||||
domainID: domainID,
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainID: domainID, DomainUserID: domainID + "_" + validID},
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainUserID: domainID + "_" + validID},
|
||||
token: validToken,
|
||||
query: fmt.Sprintf("relation=%s", "relation"),
|
||||
status: http.StatusOK,
|
||||
@@ -282,26 +263,16 @@ func TestListInvitation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "with duplicate relation",
|
||||
domainID: domainID,
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainID: domainID, DomainUserID: domainID + "_" + validID},
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainUserID: domainID + "_" + validID},
|
||||
token: validToken,
|
||||
query: "relation=1&relation=2",
|
||||
status: http.StatusBadRequest,
|
||||
contentType: validContenType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "with empty domain_id",
|
||||
domainID: "",
|
||||
token: validToken,
|
||||
status: http.StatusBadRequest,
|
||||
contentType: validContenType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "with state",
|
||||
domainID: domainID,
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainID: domainID, DomainUserID: domainID + "_" + validID},
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainUserID: domainID + "_" + validID},
|
||||
token: validToken,
|
||||
query: "state=pending",
|
||||
status: http.StatusOK,
|
||||
@@ -310,7 +281,6 @@ func TestListInvitation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "with invalid state",
|
||||
domainID: domainID,
|
||||
token: validToken,
|
||||
query: "state=invalid",
|
||||
status: http.StatusBadRequest,
|
||||
@@ -319,7 +289,6 @@ func TestListInvitation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "with duplicate state",
|
||||
domainID: domainID,
|
||||
token: validToken,
|
||||
query: "state=all&state=all",
|
||||
status: http.StatusBadRequest,
|
||||
@@ -328,8 +297,7 @@ func TestListInvitation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "with service error",
|
||||
domainID: domainID,
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainID: domainID, DomainUserID: domainID + "_" + validID},
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainUserID: domainID + "_" + validID},
|
||||
token: validToken,
|
||||
status: http.StatusForbidden,
|
||||
contentType: validContenType,
|
||||
@@ -344,7 +312,7 @@ func TestListInvitation(t *testing.T) {
|
||||
req := testRequest{
|
||||
client: is.Client(),
|
||||
method: http.MethodGet,
|
||||
url: is.URL + "/" + tc.domainID + "/invitations?" + tc.query,
|
||||
url: is.URL + "/invitations?" + tc.query,
|
||||
token: tc.token,
|
||||
contentType: tc.contentType,
|
||||
}
|
||||
@@ -405,7 +373,7 @@ func TestViewInvitation(t *testing.T) {
|
||||
token: validToken,
|
||||
userID: "",
|
||||
domainID: domainID,
|
||||
status: http.StatusNotFound,
|
||||
status: http.StatusBadRequest,
|
||||
contentType: validContenType,
|
||||
svcErr: nil,
|
||||
},
|
||||
@@ -414,7 +382,7 @@ func TestViewInvitation(t *testing.T) {
|
||||
token: validToken,
|
||||
userID: validID,
|
||||
domainID: "",
|
||||
status: http.StatusBadRequest,
|
||||
status: http.StatusNotFound,
|
||||
contentType: validContenType,
|
||||
svcErr: nil,
|
||||
},
|
||||
@@ -423,7 +391,7 @@ func TestViewInvitation(t *testing.T) {
|
||||
token: validToken,
|
||||
userID: "",
|
||||
domainID: "",
|
||||
status: http.StatusBadRequest,
|
||||
status: http.StatusNotFound,
|
||||
contentType: validContenType,
|
||||
svcErr: nil,
|
||||
},
|
||||
@@ -436,7 +404,7 @@ func TestViewInvitation(t *testing.T) {
|
||||
req := testRequest{
|
||||
client: is.Client(),
|
||||
method: http.MethodGet,
|
||||
url: is.URL + "/" + tc.domainID + "/invitations/users/" + tc.userID,
|
||||
url: is.URL + "/invitations/" + tc.userID + "/" + tc.domainID,
|
||||
token: tc.token,
|
||||
contentType: tc.contentType,
|
||||
}
|
||||
@@ -499,7 +467,7 @@ func TestDeleteInvitation(t *testing.T) {
|
||||
token: validToken,
|
||||
userID: "",
|
||||
domainID: domainID,
|
||||
status: http.StatusNotFound,
|
||||
status: http.StatusBadRequest,
|
||||
contentType: validContenType,
|
||||
svcErr: nil,
|
||||
},
|
||||
@@ -508,7 +476,7 @@ func TestDeleteInvitation(t *testing.T) {
|
||||
token: validToken,
|
||||
userID: validID,
|
||||
domainID: "",
|
||||
status: http.StatusBadRequest,
|
||||
status: http.StatusNotFound,
|
||||
contentType: validContenType,
|
||||
svcErr: nil,
|
||||
},
|
||||
@@ -517,7 +485,7 @@ func TestDeleteInvitation(t *testing.T) {
|
||||
token: validToken,
|
||||
userID: "",
|
||||
domainID: "",
|
||||
status: http.StatusBadRequest,
|
||||
status: http.StatusNotFound,
|
||||
contentType: validContenType,
|
||||
svcErr: nil,
|
||||
},
|
||||
@@ -530,7 +498,7 @@ func TestDeleteInvitation(t *testing.T) {
|
||||
req := testRequest{
|
||||
client: is.Client(),
|
||||
method: http.MethodDelete,
|
||||
url: is.URL + "/" + tc.domainID + "/invitations/users/" + tc.userID,
|
||||
url: is.URL + "/invitations/" + tc.userID + "/" + tc.domainID,
|
||||
token: tc.token,
|
||||
contentType: tc.contentType,
|
||||
}
|
||||
@@ -549,7 +517,6 @@ func TestAcceptInvitation(t *testing.T) {
|
||||
_ = authn
|
||||
cases := []struct {
|
||||
desc string
|
||||
domainID string
|
||||
token string
|
||||
data string
|
||||
contentType string
|
||||
@@ -560,8 +527,8 @@ func TestAcceptInvitation(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
desc: "valid request",
|
||||
domainID: domainID,
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainID: domainID, DomainUserID: domainID + "_" + validID},
|
||||
data: fmt.Sprintf(`{"domain_id": "%s"}`, validID),
|
||||
token: validToken,
|
||||
status: http.StatusNoContent,
|
||||
contentType: validContenType,
|
||||
@@ -569,33 +536,33 @@ func TestAcceptInvitation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "invalid token",
|
||||
domainID: domainID,
|
||||
token: "",
|
||||
data: fmt.Sprintf(`{"domain_id": "%s"}`, validID),
|
||||
status: http.StatusUnauthorized,
|
||||
contentType: validContenType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "with service error",
|
||||
domainID: domainID,
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainID: domainID, DomainUserID: domainID + "_" + validID},
|
||||
token: validToken,
|
||||
data: fmt.Sprintf(`{"domain_id": "%s"}`, validID),
|
||||
status: http.StatusForbidden,
|
||||
contentType: validContenType,
|
||||
svcErr: svcerr.ErrAuthorization,
|
||||
},
|
||||
{
|
||||
desc: "invalid content type",
|
||||
domainID: domainID,
|
||||
token: validToken,
|
||||
data: fmt.Sprintf(`{"domain_id": "%s"}`, validID),
|
||||
status: http.StatusUnsupportedMediaType,
|
||||
contentType: "text/plain",
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "empty domain",
|
||||
domainID: "",
|
||||
desc: "invalid data",
|
||||
token: validToken,
|
||||
data: `data`,
|
||||
status: http.StatusBadRequest,
|
||||
contentType: validContenType,
|
||||
svcErr: nil,
|
||||
@@ -609,9 +576,10 @@ func TestAcceptInvitation(t *testing.T) {
|
||||
req := testRequest{
|
||||
client: is.Client(),
|
||||
method: http.MethodPost,
|
||||
url: is.URL + "/" + tc.domainID + "/invitations/accept",
|
||||
url: is.URL + "/invitations/accept",
|
||||
token: tc.token,
|
||||
contentType: tc.contentType,
|
||||
body: strings.NewReader(tc.data),
|
||||
}
|
||||
|
||||
res, err := req.make()
|
||||
@@ -629,8 +597,8 @@ func TestRejectInvitation(t *testing.T) {
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
domainID string
|
||||
token string
|
||||
data string
|
||||
contentType string
|
||||
status int
|
||||
svcErr error
|
||||
@@ -639,42 +607,42 @@ func TestRejectInvitation(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
desc: "valid request",
|
||||
domainID: domainID,
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainID: domainID, DomainUserID: domainID + "_" + validID},
|
||||
token: validToken,
|
||||
data: fmt.Sprintf(`{"domain_id": "%s"}`, validID),
|
||||
status: http.StatusNoContent,
|
||||
contentType: validContenType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "invalid token",
|
||||
domainID: domainID,
|
||||
token: "",
|
||||
data: fmt.Sprintf(`{"domain_id": "%s"}`, validID),
|
||||
status: http.StatusUnauthorized,
|
||||
contentType: validContenType,
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "unauthorized error",
|
||||
domainID: domainID,
|
||||
authnRes: mgauthn.Session{UserID: validID, DomainID: domainID, DomainUserID: domainID + "_" + validID},
|
||||
token: validToken,
|
||||
data: fmt.Sprintf(`{"domain_id": "%s"}`, "invalid"),
|
||||
status: http.StatusForbidden,
|
||||
contentType: validContenType,
|
||||
svcErr: svcerr.ErrAuthorization,
|
||||
},
|
||||
{
|
||||
desc: "invalid content type",
|
||||
domainID: domainID,
|
||||
token: validToken,
|
||||
data: fmt.Sprintf(`{"domain_id": "%s"}`, validID),
|
||||
status: http.StatusUnsupportedMediaType,
|
||||
contentType: "text/plain",
|
||||
svcErr: nil,
|
||||
},
|
||||
{
|
||||
desc: "empty domain",
|
||||
domainID: "",
|
||||
desc: "invalid data",
|
||||
token: validToken,
|
||||
data: `data`,
|
||||
status: http.StatusBadRequest,
|
||||
contentType: validContenType,
|
||||
svcErr: nil,
|
||||
@@ -688,9 +656,10 @@ func TestRejectInvitation(t *testing.T) {
|
||||
req := testRequest{
|
||||
client: is.Client(),
|
||||
method: http.MethodPost,
|
||||
url: is.URL + "/" + tc.domainID + "/invitations/reject",
|
||||
url: is.URL + "/invitations/reject",
|
||||
token: tc.token,
|
||||
contentType: tc.contentType,
|
||||
body: strings.NewReader(tc.data),
|
||||
}
|
||||
|
||||
res, err := req.make()
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
const maxLimitSize = 100
|
||||
|
||||
type sendInvitationReq struct {
|
||||
domainID string
|
||||
UserID string `json:"user_id,omitempty"`
|
||||
DomainID string `json:"domain_id,omitempty"`
|
||||
Relation string `json:"relation,omitempty"`
|
||||
Resend bool `json:"resend,omitempty"`
|
||||
}
|
||||
@@ -21,6 +21,9 @@ func (req *sendInvitationReq) validate() error {
|
||||
if req.UserID == "" {
|
||||
return apiutil.ErrMissingID
|
||||
}
|
||||
if req.DomainID == "" {
|
||||
return apiutil.ErrMissingDomainID
|
||||
}
|
||||
if err := invitations.CheckRelation(req.Relation); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -41,10 +44,14 @@ func (req *listInvitationsReq) validate() error {
|
||||
}
|
||||
|
||||
type acceptInvitationReq struct {
|
||||
domainID string
|
||||
DomainID string `json:"domain_id,omitempty"`
|
||||
}
|
||||
|
||||
func (req *acceptInvitationReq) validate() error {
|
||||
if req.DomainID == "" {
|
||||
return apiutil.ErrMissingDomainID
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -57,6 +64,9 @@ func (req *invitationReq) validate() error {
|
||||
if req.userID == "" {
|
||||
return apiutil.ErrMissingID
|
||||
}
|
||||
if req.domainID == "" {
|
||||
return apiutil.ErrMissingDomainID
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ func TestSendInvitationReqValidation(t *testing.T) {
|
||||
desc: "valid request",
|
||||
req: sendInvitationReq{
|
||||
UserID: valid,
|
||||
domainID: valid,
|
||||
DomainID: valid,
|
||||
Relation: policies.DomainRelation,
|
||||
Resend: true,
|
||||
},
|
||||
@@ -35,17 +35,27 @@ func TestSendInvitationReqValidation(t *testing.T) {
|
||||
desc: "empty user ID",
|
||||
req: sendInvitationReq{
|
||||
UserID: "",
|
||||
domainID: valid,
|
||||
DomainID: valid,
|
||||
Relation: policies.DomainRelation,
|
||||
Resend: true,
|
||||
},
|
||||
err: apiutil.ErrMissingID,
|
||||
},
|
||||
{
|
||||
desc: "empty domain_id",
|
||||
req: sendInvitationReq{
|
||||
UserID: valid,
|
||||
DomainID: "",
|
||||
Relation: policies.DomainRelation,
|
||||
Resend: true,
|
||||
},
|
||||
err: apiutil.ErrMissingDomainID,
|
||||
},
|
||||
{
|
||||
desc: "missing relation",
|
||||
req: sendInvitationReq{
|
||||
UserID: valid,
|
||||
domainID: valid,
|
||||
DomainID: valid,
|
||||
Relation: "",
|
||||
Resend: true,
|
||||
},
|
||||
@@ -55,7 +65,7 @@ func TestSendInvitationReqValidation(t *testing.T) {
|
||||
desc: "invalid relation",
|
||||
req: sendInvitationReq{
|
||||
UserID: valid,
|
||||
domainID: valid,
|
||||
DomainID: valid,
|
||||
Relation: "invalid",
|
||||
Resend: true,
|
||||
},
|
||||
@@ -80,20 +90,14 @@ func TestListInvitationsReq(t *testing.T) {
|
||||
{
|
||||
desc: "valid request",
|
||||
req: listInvitationsReq{
|
||||
Page: invitations.Page{
|
||||
Limit: 1,
|
||||
DomainID: valid,
|
||||
},
|
||||
Page: invitations.Page{Limit: 1},
|
||||
},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "invalid limit",
|
||||
req: listInvitationsReq{
|
||||
Page: invitations.Page{
|
||||
Limit: 1000,
|
||||
DomainID: valid,
|
||||
},
|
||||
Page: invitations.Page{Limit: 1000},
|
||||
},
|
||||
err: apiutil.ErrLimitSize,
|
||||
},
|
||||
@@ -116,10 +120,17 @@ func TestAcceptInvitationReq(t *testing.T) {
|
||||
{
|
||||
desc: "valid request",
|
||||
req: acceptInvitationReq{
|
||||
domainID: valid,
|
||||
DomainID: valid,
|
||||
},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "empty domain_id",
|
||||
req: acceptInvitationReq{
|
||||
DomainID: "",
|
||||
},
|
||||
err: apiutil.ErrMissingDomainID,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
@@ -152,6 +163,14 @@ func TestInvitationReqValidation(t *testing.T) {
|
||||
},
|
||||
err: apiutil.ErrMissingID,
|
||||
},
|
||||
{
|
||||
desc: "empty domain",
|
||||
req: invitationReq{
|
||||
userID: valid,
|
||||
domainID: "",
|
||||
},
|
||||
err: apiutil.ErrMissingDomainID,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
|
||||
@@ -38,9 +38,9 @@ func MakeHandler(svc invitations.Service, logger *slog.Logger, authn mgauthn.Aut
|
||||
mux := chi.NewRouter()
|
||||
|
||||
mux.Group(func(r chi.Router) {
|
||||
r.Use(api.AuthenticateMiddleware(authn, true))
|
||||
r.Use(api.AuthenticateMiddleware(authn, false))
|
||||
|
||||
r.Route("/{domainID}/invitations", func(r chi.Router) {
|
||||
r.Route("/invitations", func(r chi.Router) {
|
||||
r.Post("/", otelhttp.NewHandler(kithttp.NewServer(
|
||||
sendInvitationEndpoint(svc),
|
||||
decodeSendInvitationReq,
|
||||
@@ -53,7 +53,7 @@ func MakeHandler(svc invitations.Service, logger *slog.Logger, authn mgauthn.Aut
|
||||
api.EncodeResponse,
|
||||
opts...,
|
||||
), "list_invitations").ServeHTTP)
|
||||
r.Route("/users/{user_id}", func(r chi.Router) {
|
||||
r.Route("/{user_id}/{domain_id}", func(r chi.Router) {
|
||||
r.Get("/", otelhttp.NewHandler(kithttp.NewServer(
|
||||
viewInvitationEndpoint(svc),
|
||||
decodeInvitationReq,
|
||||
@@ -122,6 +122,10 @@ func decodeListInvitationsReq(_ context.Context, r *http.Request) (interface{},
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(apiutil.ErrValidation, err)
|
||||
}
|
||||
domainID, err := apiutil.ReadStringQuery(r, domainIDKey, "")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(apiutil.ErrValidation, err)
|
||||
}
|
||||
st, err := apiutil.ReadStringQuery(r, stateKey, invitations.All.String())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(apiutil.ErrValidation, err)
|
||||
@@ -130,7 +134,6 @@ func decodeListInvitationsReq(_ context.Context, r *http.Request) (interface{},
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(apiutil.ErrValidation, err)
|
||||
}
|
||||
|
||||
req := listInvitationsReq{
|
||||
Page: invitations.Page{
|
||||
Offset: offset,
|
||||
@@ -138,6 +141,7 @@ func decodeListInvitationsReq(_ context.Context, r *http.Request) (interface{},
|
||||
InvitedBy: invitedBy,
|
||||
UserID: userID,
|
||||
Relation: relation,
|
||||
DomainID: domainID,
|
||||
State: state,
|
||||
},
|
||||
}
|
||||
@@ -150,14 +154,18 @@ func decodeAcceptInvitationReq(_ context.Context, r *http.Request) (interface{},
|
||||
return nil, errors.Wrap(apiutil.ErrValidation, apiutil.ErrUnsupportedContentType)
|
||||
}
|
||||
|
||||
return acceptInvitationReq{
|
||||
domainID: chi.URLParam(r, "domainID"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func decodeInvitationReq(_ context.Context, r *http.Request) (interface{}, error) {
|
||||
req := invitationReq{
|
||||
userID: chi.URLParam(r, "user_id"),
|
||||
var req acceptInvitationReq
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
return nil, errors.Wrap(apiutil.ErrValidation, errors.Wrap(err, errors.ErrMalformedEntity))
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func decodeInvitationReq(_ context.Context, r *http.Request) (interface{}, error) {
|
||||
req := invitationReq{
|
||||
userID: chi.URLParam(r, "user_id"),
|
||||
domainID: chi.URLParam(r, "domain_id"),
|
||||
}
|
||||
|
||||
return req, nil
|
||||
|
||||
@@ -33,7 +33,7 @@ func (am *authorizationMiddleware) SendInvitation(ctx context.Context, session a
|
||||
if err := am.checkAdmin(ctx, session.UserID, session.DomainID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
session.DomainUserID = auth.EncodeDomainUserID(session.DomainID, session.UserID)
|
||||
domainUserId := auth.EncodeDomainUserID(invitation.DomainID, invitation.UserID)
|
||||
if err := am.authorize(ctx, domainUserId, policies.MembershipPermission, policies.DomainType, invitation.DomainID); err == nil {
|
||||
// return error if the user is already a member of the domain
|
||||
@@ -48,6 +48,7 @@ func (am *authorizationMiddleware) SendInvitation(ctx context.Context, session a
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) ViewInvitation(ctx context.Context, session authn.Session, userID, domain string) (invitation invitations.Invitation, err error) {
|
||||
session.DomainUserID = auth.EncodeDomainUserID(session.DomainID, session.UserID)
|
||||
if session.UserID != userID {
|
||||
if err := am.checkAdmin(ctx, session.DomainUserID, domain); err != nil {
|
||||
return invitations.Invitation{}, err
|
||||
@@ -58,6 +59,7 @@ func (am *authorizationMiddleware) ViewInvitation(ctx context.Context, session a
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) ListInvitations(ctx context.Context, session authn.Session, page invitations.Page) (invs invitations.InvitationPage, err error) {
|
||||
session.DomainUserID = auth.EncodeDomainUserID(session.DomainID, session.UserID)
|
||||
if err := am.authorize(ctx, session.DomainUserID, policies.AdminPermission, policies.PlatformType, policies.MagistralaObject); err == nil {
|
||||
session.SuperAdmin = true
|
||||
}
|
||||
@@ -85,6 +87,7 @@ func (am *authorizationMiddleware) RejectInvitation(ctx context.Context, session
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) DeleteInvitation(ctx context.Context, session authn.Session, userID, domainID string) (err error) {
|
||||
session.DomainUserID = auth.EncodeDomainUserID(session.DomainID, session.UserID)
|
||||
if err := am.checkAdmin(ctx, session.DomainUserID, domainID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+29
-12
@@ -5,7 +5,6 @@ package sdk
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
@@ -44,7 +43,7 @@ func (sdk mgSDK) SendInvitation(invitation Invitation, token string) (err error)
|
||||
return errors.NewSDKError(err)
|
||||
}
|
||||
|
||||
url := sdk.invitationsURL + "/" + invitation.DomainID + "/" + invitationsEndpoint
|
||||
url := sdk.invitationsURL + "/" + invitationsEndpoint
|
||||
|
||||
_, _, sdkerr := sdk.processRequest(http.MethodPost, url, token, data, nil, http.StatusCreated)
|
||||
|
||||
@@ -52,7 +51,7 @@ func (sdk mgSDK) SendInvitation(invitation Invitation, token string) (err error)
|
||||
}
|
||||
|
||||
func (sdk mgSDK) Invitation(userID, domainID, token string) (invitation Invitation, err error) {
|
||||
url := sdk.invitationsURL + "/" + domainID + "/" + invitationsEndpoint + "/" + usersEndpoint + "/" + userID
|
||||
url := sdk.invitationsURL + "/" + invitationsEndpoint + "/" + userID + "/" + domainID
|
||||
|
||||
_, body, sdkerr := sdk.processRequest(http.MethodGet, url, token, nil, nil, http.StatusOK)
|
||||
if sdkerr != nil {
|
||||
@@ -66,10 +65,8 @@ func (sdk mgSDK) Invitation(userID, domainID, token string) (invitation Invitati
|
||||
return invitation, nil
|
||||
}
|
||||
|
||||
func (sdk mgSDK) Invitations(pm PageMetadata, domainID, token string) (invitations InvitationPage, err error) {
|
||||
endpoint := fmt.Sprintf("%s/%s", domainID, invitationsEndpoint)
|
||||
|
||||
url, err := sdk.withQueryParams(sdk.invitationsURL, endpoint, pm)
|
||||
func (sdk mgSDK) Invitations(pm PageMetadata, token string) (invitations InvitationPage, err error) {
|
||||
url, err := sdk.withQueryParams(sdk.invitationsURL, invitationsEndpoint, pm)
|
||||
if err != nil {
|
||||
return InvitationPage{}, errors.NewSDKError(err)
|
||||
}
|
||||
@@ -88,23 +85,43 @@ func (sdk mgSDK) Invitations(pm PageMetadata, domainID, token string) (invitatio
|
||||
}
|
||||
|
||||
func (sdk mgSDK) AcceptInvitation(domainID, token string) (err error) {
|
||||
url := sdk.invitationsURL + "/" + domainID + "/" + invitationsEndpoint + "/" + acceptEndpoint
|
||||
req := struct {
|
||||
DomainID string `json:"domain_id"`
|
||||
}{
|
||||
DomainID: domainID,
|
||||
}
|
||||
data, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return errors.NewSDKError(err)
|
||||
}
|
||||
|
||||
_, _, sdkerr := sdk.processRequest(http.MethodPost, url, token, nil, nil, http.StatusNoContent)
|
||||
url := sdk.invitationsURL + "/" + invitationsEndpoint + "/" + acceptEndpoint
|
||||
|
||||
_, _, sdkerr := sdk.processRequest(http.MethodPost, url, token, data, nil, http.StatusNoContent)
|
||||
|
||||
return sdkerr
|
||||
}
|
||||
|
||||
func (sdk mgSDK) RejectInvitation(domainID, token string) (err error) {
|
||||
url := sdk.invitationsURL + "/" + domainID + "/" + invitationsEndpoint + "/" + rejectEndpoint
|
||||
req := struct {
|
||||
DomainID string `json:"domain_id"`
|
||||
}{
|
||||
DomainID: domainID,
|
||||
}
|
||||
data, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return errors.NewSDKError(err)
|
||||
}
|
||||
|
||||
_, _, sdkerr := sdk.processRequest(http.MethodPost, url, token, nil, nil, http.StatusNoContent)
|
||||
url := sdk.invitationsURL + "/" + invitationsEndpoint + "/" + rejectEndpoint
|
||||
|
||||
_, _, sdkerr := sdk.processRequest(http.MethodPost, url, token, data, nil, http.StatusNoContent)
|
||||
|
||||
return sdkerr
|
||||
}
|
||||
|
||||
func (sdk mgSDK) DeleteInvitation(userID, domainID, token string) (err error) {
|
||||
url := sdk.invitationsURL + "/" + domainID + "/" + invitationsEndpoint + "/" + usersEndpoint + "/" + userID
|
||||
url := sdk.invitationsURL + "/" + invitationsEndpoint + "/" + userID + "/" + domainID
|
||||
|
||||
_, _, sdkerr := sdk.processRequest(http.MethodDelete, url, token, nil, nil, http.StatusNoContent)
|
||||
|
||||
|
||||
@@ -131,14 +131,14 @@ func TestSendInvitation(t *testing.T) {
|
||||
Relation: invitation.Relation,
|
||||
Resend: invitation.Resend,
|
||||
},
|
||||
authenticateErr: svcerr.ErrCreateEntity,
|
||||
err: errors.NewSDKErrorWithStatus(svcerr.ErrCreateEntity, http.StatusUnprocessableEntity),
|
||||
svcErr: svcerr.ErrCreateEntity,
|
||||
err: errors.NewSDKErrorWithStatus(svcerr.ErrCreateEntity, http.StatusUnprocessableEntity),
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
if tc.token == validToken {
|
||||
tc.session = mgauthn.Session{DomainUserID: invitation.DomainID + "_" + validID, UserID: validID, DomainID: invitation.DomainID}
|
||||
if tc.token == valid {
|
||||
tc.session = mgauthn.Session{UserID: tc.sendInvitationReq.UserID, DomainID: tc.sendInvitationReq.DomainID}
|
||||
}
|
||||
authCall := auth.On("Authenticate", mock.Anything, tc.token).Return(tc.session, tc.authenticateErr)
|
||||
svcCall := svc.On("SendInvitation", mock.Anything, tc.session, tc.svcReq).Return(tc.svcErr)
|
||||
@@ -206,20 +206,30 @@ func TestViewInvitation(t *testing.T) {
|
||||
err: errors.NewSDKErrorWithStatus(apiutil.ErrBearerToken, http.StatusUnauthorized),
|
||||
},
|
||||
{
|
||||
desc: "view invitation with invalid domainID",
|
||||
token: validToken,
|
||||
userID: invitation.UserID,
|
||||
domainID: wrongID,
|
||||
svcRes: invitations.Invitation{},
|
||||
authenticateErr: svcerr.ErrNotFound,
|
||||
response: sdk.Invitation{},
|
||||
err: errors.NewSDKErrorWithStatus(svcerr.ErrNotFound, http.StatusNotFound),
|
||||
desc: "view invitation with empty userID",
|
||||
token: validToken,
|
||||
userID: "",
|
||||
domainID: invitation.DomainID,
|
||||
svcRes: invitations.Invitation{},
|
||||
svcErr: nil,
|
||||
response: sdk.Invitation{},
|
||||
err: errors.NewSDKErrorWithStatus(errors.Wrap(apiutil.ErrValidation, apiutil.ErrMissingID), http.StatusBadRequest),
|
||||
},
|
||||
{
|
||||
desc: "view invitation with invalid domainID",
|
||||
token: validToken,
|
||||
userID: invitation.UserID,
|
||||
domainID: wrongID,
|
||||
svcRes: invitations.Invitation{},
|
||||
svcErr: svcerr.ErrNotFound,
|
||||
response: sdk.Invitation{},
|
||||
err: errors.NewSDKErrorWithStatus(svcerr.ErrNotFound, http.StatusNotFound),
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
if tc.token == validToken {
|
||||
tc.session = mgauthn.Session{DomainUserID: invitation.DomainID + "_" + validID, UserID: validID, DomainID: invitation.DomainID}
|
||||
if tc.token == valid {
|
||||
tc.session = mgauthn.Session{UserID: tc.userID, DomainID: tc.domainID}
|
||||
}
|
||||
authCall := auth.On("Authenticate", mock.Anything, tc.token).Return(tc.session, tc.authenticateErr)
|
||||
svcCall := svc.On("ViewInvitation", mock.Anything, tc.session, tc.userID, tc.domainID).Return(tc.svcRes, tc.svcErr)
|
||||
@@ -248,7 +258,6 @@ func TestListInvitation(t *testing.T) {
|
||||
cases := []struct {
|
||||
desc string
|
||||
token string
|
||||
domainID string
|
||||
session mgauthn.Session
|
||||
pageMeta sdk.PageMetadata
|
||||
svcReq invitations.Page
|
||||
@@ -259,17 +268,15 @@ func TestListInvitation(t *testing.T) {
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "list invitations successfully",
|
||||
domainID: invitation.DomainID,
|
||||
token: validToken,
|
||||
desc: "list invitations successfully",
|
||||
token: validToken,
|
||||
pageMeta: sdk.PageMetadata{
|
||||
Offset: 0,
|
||||
Limit: 10,
|
||||
},
|
||||
svcReq: invitations.Page{
|
||||
Offset: 0,
|
||||
Limit: 10,
|
||||
DomainID: invitation.DomainID,
|
||||
Offset: 0,
|
||||
Limit: 10,
|
||||
},
|
||||
svcRes: invitations.InvitationPage{
|
||||
Total: 1,
|
||||
@@ -283,17 +290,15 @@ func TestListInvitation(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "list invitations with invalid token",
|
||||
domainID: invitation.DomainID,
|
||||
token: invalidToken,
|
||||
desc: "list invitations with invalid token",
|
||||
token: invalidToken,
|
||||
pageMeta: sdk.PageMetadata{
|
||||
Offset: 0,
|
||||
Limit: 10,
|
||||
},
|
||||
svcReq: invitations.Page{
|
||||
Offset: 0,
|
||||
Limit: 10,
|
||||
DomainID: invitation.DomainID,
|
||||
Offset: 0,
|
||||
Limit: 10,
|
||||
},
|
||||
svcRes: invitations.InvitationPage{},
|
||||
authenticateErr: svcerr.ErrAuthentication,
|
||||
@@ -302,7 +307,6 @@ func TestListInvitation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "list invitations with empty token",
|
||||
domainID: invitation.DomainID,
|
||||
token: "",
|
||||
pageMeta: sdk.PageMetadata{},
|
||||
svcRes: invitations.InvitationPage{},
|
||||
@@ -311,18 +315,8 @@ func TestListInvitation(t *testing.T) {
|
||||
err: errors.NewSDKErrorWithStatus(apiutil.ErrBearerToken, http.StatusUnauthorized),
|
||||
},
|
||||
{
|
||||
desc: "list invitations with empty domainID",
|
||||
token: validToken,
|
||||
pageMeta: sdk.PageMetadata{},
|
||||
svcRes: invitations.InvitationPage{},
|
||||
svcErr: nil,
|
||||
response: sdk.InvitationPage{},
|
||||
err: errors.NewSDKErrorWithStatus(apiutil.ErrMissingDomainID, http.StatusBadRequest),
|
||||
},
|
||||
{
|
||||
desc: "list invitations with limit greater than max limit",
|
||||
token: validToken,
|
||||
domainID: invitation.DomainID,
|
||||
desc: "list invitations with limit greater than max limit",
|
||||
token: validToken,
|
||||
pageMeta: sdk.PageMetadata{
|
||||
Offset: 0,
|
||||
Limit: 101,
|
||||
@@ -336,12 +330,12 @@ func TestListInvitation(t *testing.T) {
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
if tc.token == validToken {
|
||||
tc.session = mgauthn.Session{DomainUserID: invitation.DomainID + "_" + validID, UserID: validID, DomainID: invitation.DomainID}
|
||||
if tc.token == valid {
|
||||
tc.session = mgauthn.Session{DomainUserID: validID, UserID: validID}
|
||||
}
|
||||
authCall := auth.On("Authenticate", mock.Anything, tc.token).Return(tc.session, tc.authenticateErr)
|
||||
svcCall := svc.On("ListInvitations", mock.Anything, tc.session, tc.svcReq).Return(tc.svcRes, tc.svcErr)
|
||||
resp, err := mgsdk.Invitations(tc.pageMeta, tc.domainID, tc.token)
|
||||
resp, err := mgsdk.Invitations(tc.pageMeta, tc.token)
|
||||
assert.Equal(t, tc.err, err)
|
||||
assert.Equal(t, tc.response, resp)
|
||||
if tc.err == nil {
|
||||
@@ -394,17 +388,17 @@ func TestAcceptInvitation(t *testing.T) {
|
||||
err: errors.NewSDKErrorWithStatus(apiutil.ErrBearerToken, http.StatusUnauthorized),
|
||||
},
|
||||
{
|
||||
desc: "accept invitation with invalid domainID",
|
||||
token: validToken,
|
||||
domainID: wrongID,
|
||||
authenticateErr: svcerr.ErrNotFound,
|
||||
err: errors.NewSDKErrorWithStatus(svcerr.ErrNotFound, http.StatusNotFound),
|
||||
desc: "accept invitation with invalid domainID",
|
||||
token: validToken,
|
||||
domainID: wrongID,
|
||||
svcErr: svcerr.ErrNotFound,
|
||||
err: errors.NewSDKErrorWithStatus(svcerr.ErrNotFound, http.StatusNotFound),
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
if tc.token == validToken {
|
||||
tc.session = mgauthn.Session{DomainUserID: invitation.DomainID + "_" + validID, UserID: validID, DomainID: invitation.DomainID}
|
||||
if tc.token == valid {
|
||||
tc.session = mgauthn.Session{DomainUserID: validID, UserID: validID, DomainID: validID}
|
||||
}
|
||||
authCall := auth.On("Authenticate", mock.Anything, tc.token).Return(tc.session, tc.authenticateErr)
|
||||
svcCall := svc.On("AcceptInvitation", mock.Anything, tc.session, tc.domainID).Return(tc.svcErr)
|
||||
@@ -460,17 +454,17 @@ func TestRejectInvitation(t *testing.T) {
|
||||
err: errors.NewSDKErrorWithStatus(apiutil.ErrBearerToken, http.StatusUnauthorized),
|
||||
},
|
||||
{
|
||||
desc: "reject invitation with invalid domainID",
|
||||
token: validToken,
|
||||
domainID: wrongID,
|
||||
authenticateErr: svcerr.ErrNotFound,
|
||||
err: errors.NewSDKErrorWithStatus(svcerr.ErrNotFound, http.StatusNotFound),
|
||||
desc: "reject invitation with invalid domainID",
|
||||
token: validToken,
|
||||
domainID: wrongID,
|
||||
svcErr: svcerr.ErrNotFound,
|
||||
err: errors.NewSDKErrorWithStatus(svcerr.ErrNotFound, http.StatusNotFound),
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
if tc.token == validToken {
|
||||
tc.session = mgauthn.Session{DomainUserID: invitation.DomainID + "_" + validID, UserID: validID, DomainID: invitation.DomainID}
|
||||
if tc.token == valid {
|
||||
tc.session = mgauthn.Session{DomainUserID: validID, UserID: validID, DomainID: validID}
|
||||
}
|
||||
authCall := auth.On("Authenticate", mock.Anything, tc.token).Return(tc.session, tc.authenticateErr)
|
||||
svcCall := svc.On("RejectInvitation", mock.Anything, tc.session, tc.domainID).Return(tc.svcErr)
|
||||
@@ -530,18 +524,26 @@ func TestDeleteInvitation(t *testing.T) {
|
||||
err: errors.NewSDKErrorWithStatus(apiutil.ErrBearerToken, http.StatusUnauthorized),
|
||||
},
|
||||
{
|
||||
desc: "delete invitation with invalid domainID",
|
||||
token: validToken,
|
||||
userID: invitation.UserID,
|
||||
domainID: wrongID,
|
||||
authenticateErr: svcerr.ErrNotFound,
|
||||
err: errors.NewSDKErrorWithStatus(svcerr.ErrNotFound, http.StatusNotFound),
|
||||
desc: "delete invitation with empty userID",
|
||||
token: validToken,
|
||||
userID: "",
|
||||
domainID: invitation.DomainID,
|
||||
svcErr: nil,
|
||||
err: errors.NewSDKErrorWithStatus(errors.Wrap(apiutil.ErrValidation, apiutil.ErrMissingID), http.StatusBadRequest),
|
||||
},
|
||||
{
|
||||
desc: "delete invitation with invalid domainID",
|
||||
token: validToken,
|
||||
userID: invitation.UserID,
|
||||
domainID: wrongID,
|
||||
svcErr: svcerr.ErrNotFound,
|
||||
err: errors.NewSDKErrorWithStatus(svcerr.ErrNotFound, http.StatusNotFound),
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
if tc.token == validToken {
|
||||
tc.session = mgauthn.Session{DomainUserID: invitation.DomainID + "_" + validID, UserID: validID, DomainID: invitation.DomainID}
|
||||
if tc.token == valid {
|
||||
tc.session = mgauthn.Session{UserID: tc.userID, DomainID: tc.domainID}
|
||||
}
|
||||
authCall := auth.On("Authenticate", mock.Anything, tc.token).Return(tc.session, tc.authenticateErr)
|
||||
svcCall := svc.On("DeleteInvitation", mock.Anything, tc.session, tc.userID, tc.domainID).Return(tc.svcErr)
|
||||
|
||||
+2
-2
@@ -1182,9 +1182,9 @@ type SDK interface {
|
||||
// Invitations returns a list of invitations.
|
||||
//
|
||||
// For example:
|
||||
// invitations, _ := sdk.Invitations(PageMetadata{Offset: 0, Limit: 10}, "domainID", "token")
|
||||
// invitations, _ := sdk.Invitations(PageMetadata{Offset: 0, Limit: 10}, "token")
|
||||
// fmt.Println(invitations)
|
||||
Invitations(pm PageMetadata, domainID, token string) (invitations InvitationPage, err error)
|
||||
Invitations(pm PageMetadata, token string) (invitations InvitationPage, err error)
|
||||
|
||||
// AcceptInvitation accepts an invitation by adding the user to the domain that they were invited to.
|
||||
//
|
||||
|
||||
@@ -1344,9 +1344,9 @@ func (_m *SDK) Invitation(userID string, domainID string, token string) (sdk.Inv
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Invitations provides a mock function with given fields: pm, domainID, token
|
||||
func (_m *SDK) Invitations(pm sdk.PageMetadata, domainID string, token string) (sdk.InvitationPage, error) {
|
||||
ret := _m.Called(pm, domainID, token)
|
||||
// Invitations provides a mock function with given fields: pm, token
|
||||
func (_m *SDK) Invitations(pm sdk.PageMetadata, token string) (sdk.InvitationPage, error) {
|
||||
ret := _m.Called(pm, token)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Invitations")
|
||||
@@ -1354,17 +1354,17 @@ func (_m *SDK) Invitations(pm sdk.PageMetadata, domainID string, token string) (
|
||||
|
||||
var r0 sdk.InvitationPage
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(sdk.PageMetadata, string, string) (sdk.InvitationPage, error)); ok {
|
||||
return rf(pm, domainID, token)
|
||||
if rf, ok := ret.Get(0).(func(sdk.PageMetadata, string) (sdk.InvitationPage, error)); ok {
|
||||
return rf(pm, token)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(sdk.PageMetadata, string, string) sdk.InvitationPage); ok {
|
||||
r0 = rf(pm, domainID, token)
|
||||
if rf, ok := ret.Get(0).(func(sdk.PageMetadata, string) sdk.InvitationPage); ok {
|
||||
r0 = rf(pm, token)
|
||||
} else {
|
||||
r0 = ret.Get(0).(sdk.InvitationPage)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(sdk.PageMetadata, string, string) error); ok {
|
||||
r1 = rf(pm, domainID, token)
|
||||
if rf, ok := ret.Get(1).(func(sdk.PageMetadata, string) error); ok {
|
||||
r1 = rf(pm, token)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user