Reimplement remove and invite user
Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
@@ -96,13 +96,13 @@ type Mutation {
|
||||
|
||||
createUser(input: CreateUserInput!): CreateUserPayload
|
||||
@session(required: PRESENT)
|
||||
inviteMember(input: InviteMemberInput!): InviteMemberPayload
|
||||
inviteUser(input: InviteUserInput!): InviteUserPayload
|
||||
@session(required: PRESENT)
|
||||
deleteInvitation(input: DeleteInvitationInput!): DeleteInvitationPayload
|
||||
@session(required: PRESENT)
|
||||
updateProfile(input: UpdateProfileInput!): UpdateProfilePayload!
|
||||
updateUser(input: UpdateUserInput!): UpdateUserPayload!
|
||||
updateMembership(input: UpdateMembershipInput!): UpdateMembershipPayload!
|
||||
removeMember(input: RemoveMemberInput!): RemoveMemberPayload
|
||||
removeUser(input: RemoveUserInput!): RemoveUserPayload
|
||||
@session(required: PRESENT)
|
||||
|
||||
acceptInvitation(input: AcceptInvitationInput!): AcceptInvitationPayload
|
||||
@@ -741,14 +741,12 @@ input CreateUserInput {
|
||||
contractEndDate: Datetime @goField(omittable: true)
|
||||
}
|
||||
|
||||
input InviteMemberInput {
|
||||
input InviteUserInput {
|
||||
organizationId: ID!
|
||||
email: EmailAddr!
|
||||
fullName: String!
|
||||
role: MembershipRole!
|
||||
profileId: ID!
|
||||
}
|
||||
|
||||
input UpdateProfileInput {
|
||||
input UpdateUserInput {
|
||||
id: ID!
|
||||
fullName: String!
|
||||
additionalEmailAddresses: [EmailAddr!]
|
||||
@@ -764,9 +762,9 @@ input UpdateMembershipInput {
|
||||
role: MembershipRole!
|
||||
}
|
||||
|
||||
input RemoveMemberInput {
|
||||
input RemoveUserInput {
|
||||
organizationId: ID!
|
||||
membershipId: ID!
|
||||
profileId: ID!
|
||||
}
|
||||
|
||||
input AcceptInvitationInput {
|
||||
@@ -908,11 +906,11 @@ type CreateUserPayload {
|
||||
profileEdge: ProfileEdge!
|
||||
}
|
||||
|
||||
type InviteMemberPayload {
|
||||
type InviteUserPayload {
|
||||
invitationEdge: InvitationEdge!
|
||||
}
|
||||
|
||||
type UpdateProfilePayload {
|
||||
type UpdateUserPayload {
|
||||
profile: Profile!
|
||||
}
|
||||
|
||||
@@ -920,8 +918,8 @@ type UpdateMembershipPayload {
|
||||
membership: Membership!
|
||||
}
|
||||
|
||||
type RemoveMemberPayload {
|
||||
deletedMembershipId: ID!
|
||||
type RemoveUserPayload {
|
||||
deletedProfileId: ID!
|
||||
}
|
||||
|
||||
type AcceptInvitationPayload {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -224,14 +224,12 @@ type InvitationEdge struct {
|
||||
Cursor page.CursorKey `json:"cursor"`
|
||||
}
|
||||
|
||||
type InviteMemberInput struct {
|
||||
OrganizationID gid.GID `json:"organizationId"`
|
||||
Email mail.Addr `json:"email"`
|
||||
FullName string `json:"fullName"`
|
||||
Role coredata.MembershipRole `json:"role"`
|
||||
type InviteUserInput struct {
|
||||
OrganizationID gid.GID `json:"organizationId"`
|
||||
ProfileID gid.GID `json:"profileId"`
|
||||
}
|
||||
|
||||
type InviteMemberPayload struct {
|
||||
type InviteUserPayload struct {
|
||||
InvitationEdge *InvitationEdge `json:"invitationEdge"`
|
||||
}
|
||||
|
||||
@@ -348,13 +346,13 @@ type RegenerateSCIMTokenPayload struct {
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
type RemoveMemberInput struct {
|
||||
type RemoveUserInput struct {
|
||||
OrganizationID gid.GID `json:"organizationId"`
|
||||
MembershipID gid.GID `json:"membershipId"`
|
||||
ProfileID gid.GID `json:"profileId"`
|
||||
}
|
||||
|
||||
type RemoveMemberPayload struct {
|
||||
DeletedMembershipID gid.GID `json:"deletedMembershipId"`
|
||||
type RemoveUserPayload struct {
|
||||
DeletedProfileID gid.GID `json:"deletedProfileId"`
|
||||
}
|
||||
|
||||
type ResetPasswordInput struct {
|
||||
@@ -566,20 +564,6 @@ type UpdateOrganizationPayload struct {
|
||||
Organization *Organization `json:"organization,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateProfileInput struct {
|
||||
ID gid.GID `json:"id"`
|
||||
FullName string `json:"fullName"`
|
||||
AdditionalEmailAddresses []mail.Addr `json:"additionalEmailAddresses,omitempty"`
|
||||
Kind coredata.MembershipProfileKind `json:"kind"`
|
||||
Position *string `json:"position,omitempty"`
|
||||
ContractStartDate graphql.Omittable[*time.Time] `json:"contractStartDate,omitempty"`
|
||||
ContractEndDate graphql.Omittable[*time.Time] `json:"contractEndDate,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateProfilePayload struct {
|
||||
Profile *Profile `json:"profile"`
|
||||
}
|
||||
|
||||
type UpdateSAMLConfigurationInput struct {
|
||||
OrganizationID gid.GID `json:"organizationId"`
|
||||
SamlConfigurationID gid.GID `json:"samlConfigurationId"`
|
||||
@@ -605,6 +589,20 @@ type UpdateSCIMBridgePayload struct {
|
||||
ScimBridge *SCIMBridge `json:"scimBridge"`
|
||||
}
|
||||
|
||||
type UpdateUserInput struct {
|
||||
ID gid.GID `json:"id"`
|
||||
FullName string `json:"fullName"`
|
||||
AdditionalEmailAddresses []mail.Addr `json:"additionalEmailAddresses,omitempty"`
|
||||
Kind coredata.MembershipProfileKind `json:"kind"`
|
||||
Position *string `json:"position,omitempty"`
|
||||
ContractStartDate graphql.Omittable[*time.Time] `json:"contractStartDate,omitempty"`
|
||||
ContractEndDate graphql.Omittable[*time.Time] `json:"contractEndDate,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateUserPayload struct {
|
||||
Profile *Profile `json:"profile"`
|
||||
}
|
||||
|
||||
type VerifyEmailInput struct {
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
@@ -907,19 +907,17 @@ func (r *mutationResolver) CreateUser(ctx context.Context, input types.CreateUse
|
||||
}, nil
|
||||
}
|
||||
|
||||
// InviteMember is the resolver for the inviteMember field.
|
||||
func (r *mutationResolver) InviteMember(ctx context.Context, input types.InviteMemberInput) (*types.InviteMemberPayload, error) {
|
||||
if err := r.authorize(ctx, input.OrganizationID, iam.ActionInvitationCreate); err != nil {
|
||||
// InviteUser is the resolver for the inviteUser field.
|
||||
func (r *mutationResolver) InviteUser(ctx context.Context, input types.InviteUserInput) (*types.InviteUserPayload, error) {
|
||||
if err := r.authorize(ctx, input.ProfileID, iam.ActionInvitationCreate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
invitation, err := r.iam.OrganizationService.InviteMember(
|
||||
invitation, err := r.iam.OrganizationService.InviteUser(
|
||||
ctx,
|
||||
input.OrganizationID,
|
||||
&iam.CreateInvitationRequest{
|
||||
Email: input.Email,
|
||||
FullName: input.FullName,
|
||||
Role: input.Role,
|
||||
OrganizationID: input.OrganizationID,
|
||||
ProfileID: input.ProfileID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
@@ -934,11 +932,11 @@ func (r *mutationResolver) InviteMember(ctx context.Context, input types.InviteM
|
||||
return nil, gqlutils.Conflict(ctx, err)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot add member to organization", log.Error(err))
|
||||
r.logger.ErrorCtx(ctx, "cannot invite user", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.InviteMemberPayload{
|
||||
return &types.InviteUserPayload{
|
||||
InvitationEdge: types.NewInvitationEdge(invitation, coredata.InvitationOrderFieldCreatedAt),
|
||||
}, nil
|
||||
}
|
||||
@@ -969,15 +967,15 @@ func (r *mutationResolver) DeleteInvitation(ctx context.Context, input types.Del
|
||||
return &types.DeleteInvitationPayload{DeletedInvitationID: input.InvitationID}, nil
|
||||
}
|
||||
|
||||
// UpdateProfile is the resolver for the updateProfile field.
|
||||
func (r *mutationResolver) UpdateProfile(ctx context.Context, input types.UpdateProfileInput) (*types.UpdateProfilePayload, error) {
|
||||
// UpdateUser is the resolver for the updateUser field.
|
||||
func (r *mutationResolver) UpdateUser(ctx context.Context, input types.UpdateUserInput) (*types.UpdateUserPayload, error) {
|
||||
if err := r.authorize(ctx, input.ID, iam.ActionMembershipProfileUpdate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
profile, err := r.iam.OrganizationService.UpdateProfile(
|
||||
profile, err := r.iam.OrganizationService.UpdateUser(
|
||||
ctx,
|
||||
&iam.UpdateProfileRequest{
|
||||
&iam.UpdateUserRequest{
|
||||
ID: input.ID,
|
||||
FullName: input.FullName,
|
||||
AdditionalEmailAddresses: input.AdditionalEmailAddresses,
|
||||
@@ -992,7 +990,7 @@ func (r *mutationResolver) UpdateProfile(ctx context.Context, input types.Update
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.UpdateProfilePayload{
|
||||
return &types.UpdateUserPayload{
|
||||
Profile: types.NewProfile(profile),
|
||||
}, nil
|
||||
}
|
||||
@@ -1020,13 +1018,13 @@ func (r *mutationResolver) UpdateMembership(ctx context.Context, input types.Upd
|
||||
}, nil
|
||||
}
|
||||
|
||||
// RemoveMember is the resolver for the removeMember field.
|
||||
func (r *mutationResolver) RemoveMember(ctx context.Context, input types.RemoveMemberInput) (*types.RemoveMemberPayload, error) {
|
||||
if err := r.authorize(ctx, input.MembershipID, iam.ActionMembershipDelete); err != nil {
|
||||
// RemoveUser is the resolver for the removeUser field.
|
||||
func (r *mutationResolver) RemoveUser(ctx context.Context, input types.RemoveUserInput) (*types.RemoveUserPayload, error) {
|
||||
if err := r.authorize(ctx, input.ProfileID, iam.ActionMembershipProfileDelete); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err := r.iam.OrganizationService.RemoveMember(ctx, input.OrganizationID, input.MembershipID)
|
||||
err := r.iam.OrganizationService.RemoveUser(ctx, input.OrganizationID, input.ProfileID)
|
||||
if err != nil {
|
||||
var errManagedBySCIM *iam.ErrUserManagedBySCIM
|
||||
var errLastActiveOwner *iam.ErrLastActiveOwner
|
||||
@@ -1039,11 +1037,11 @@ func (r *mutationResolver) RemoveMember(ctx context.Context, input types.RemoveM
|
||||
return nil, gqlutils.Conflict(ctx, err)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot remove member from organization", log.Error(err))
|
||||
r.logger.ErrorCtx(ctx, "cannot remove user from organization", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.RemoveMemberPayload{DeletedMembershipID: input.MembershipID}, nil
|
||||
return &types.RemoveUserPayload{DeletedProfileID: input.ProfileID}, nil
|
||||
}
|
||||
|
||||
// AcceptInvitation is the resolver for the acceptInvitation field.
|
||||
|
||||
@@ -7,10 +7,12 @@ package mcp_v1
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/modelcontextprotocol/go-sdk/mcp"
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
"go.probo.inc/probo/pkg/iam"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
"go.probo.inc/probo/pkg/probo"
|
||||
"go.probo.inc/probo/pkg/server/api/authn"
|
||||
|
||||
Reference in New Issue
Block a user