Skip to content

Commit ba8caac

Browse files
authored
feat(authentication): update team RPC (#1395)
* feat(authentication): switch parent team RPC * fix: address code review feedback * fix: use prototype TS type instead of hardcoding it
1 parent 365779e commit ba8caac

File tree

3 files changed

+102
-0
lines changed

3 files changed

+102
-0
lines changed

libraries/grpc-sdk/src/modules/authentication/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,8 @@ export class Authentication extends ConduitModule<typeof AuthenticationDefinitio
115115
userData: JSON.stringify(userData),
116116
});
117117
}
118+
119+
updateTeam(teamId: string, name?: string, newParentTeamId?: string): Promise<Team> {
120+
return this.client!.updateTeam({ teamId, name, newParentTeamId });
121+
}
118122
}

modules/authentication/src/Authentication.ts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import {
4141
ValidateAccessTokenResponse_Status,
4242
InviteUserToTeamRequest,
4343
InviteUserToTeamResponse,
44+
UpdateTeamRequest,
4445
} from './protoTypes/authentication.js';
4546
import { Empty } from './protoTypes/google/protobuf/empty.js';
4647
import { runMigrations } from './migrations/index.js';
@@ -83,6 +84,7 @@ export default class Authentication extends ManagedModule<Config> {
8384
removeTeamMembers: this.removeTeamMembers.bind(this),
8485
invitationDelete: this.invitationDelete.bind(this),
8586
inviteUserToTeam: this.inviteUserToTeam.bind(this),
87+
updateTeam: this.updateTeam.bind(this),
8688
},
8789
};
8890
protected metricsSchema = metricsSchema;
@@ -744,6 +746,95 @@ export default class Authentication extends ManagedModule<Config> {
744746
}
745747
}
746748

749+
async updateTeam(
750+
call: GrpcRequest<UpdateTeamRequest>,
751+
callback: GrpcCallback<GrpcTeam>,
752+
) {
753+
const { teamId, name, newParentTeamId } = call.request;
754+
755+
try {
756+
if (!name && !newParentTeamId) {
757+
return callback({
758+
code: status.INVALID_ARGUMENT,
759+
message: 'At least one of name or newParentTeamId must be provided',
760+
});
761+
}
762+
763+
const team = await models.Team.getInstance().findOne({ _id: teamId });
764+
if (!team) {
765+
return callback({ code: status.NOT_FOUND, message: 'Team not found' });
766+
}
767+
768+
const updateFields: { name?: string; parentTeam?: string } = {
769+
...(name && { name }),
770+
};
771+
772+
if (newParentTeamId) {
773+
const newParentTeam = await models.Team.getInstance().findOne({
774+
_id: newParentTeamId,
775+
});
776+
if (!newParentTeam) {
777+
return callback({
778+
code: status.NOT_FOUND,
779+
message: 'New parent team not found',
780+
});
781+
}
782+
783+
const oldParentTeamId = team.parentTeam;
784+
785+
if (oldParentTeamId) {
786+
try {
787+
await this.grpcSdk.authorization!.deleteRelation({
788+
subject: 'Team:' + oldParentTeamId,
789+
relation: 'owner',
790+
resource: 'Team:' + teamId,
791+
});
792+
} catch (e) {
793+
ConduitGrpcSdk.Logger.warn(
794+
`Failed to delete old parent relation: ${(e as Error).message}`,
795+
);
796+
}
797+
}
798+
799+
await this.grpcSdk.authorization!.createRelation({
800+
subject: 'Team:' + newParentTeamId,
801+
relation: 'owner',
802+
resource: 'Team:' + teamId,
803+
});
804+
805+
updateFields.parentTeam = newParentTeamId;
806+
807+
ConduitGrpcSdk.Logger.info(
808+
`Team ${teamId} parent switched from ${
809+
oldParentTeamId ?? 'none'
810+
} to ${newParentTeamId}`,
811+
);
812+
}
813+
814+
const updatedTeam = await models.Team.getInstance().findByIdAndUpdate(
815+
teamId,
816+
updateFields,
817+
);
818+
819+
if (!updatedTeam) {
820+
return callback({ code: status.INTERNAL, message: 'Failed to update team' });
821+
}
822+
823+
if (name) {
824+
ConduitGrpcSdk.Logger.info(`Team ${teamId} name updated to ${name}`);
825+
}
826+
827+
return callback(null, {
828+
id: updatedTeam._id,
829+
name: updatedTeam.name,
830+
parentTeam: updatedTeam.parentTeam,
831+
isDefault: updatedTeam.isDefault,
832+
});
833+
} catch (e) {
834+
return callback({ code: status.INTERNAL, message: (e as Error).message });
835+
}
836+
}
837+
747838
protected registerSchemas() {
748839
const promises = Object.values(models).map(model => {
749840
const modelInstance = model.getInstance(this.database);

modules/authentication/src/authentication.proto

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ message InviteUserToTeamResponse {
124124
string invitationToken = 1;
125125
}
126126

127+
message UpdateTeamRequest {
128+
string teamId = 1;
129+
optional string name = 2;
130+
optional string newParentTeamId = 3;
131+
}
132+
127133
service Authentication {
128134
rpc UserLogin(UserLoginRequest) returns (UserLoginResponse);
129135
rpc UserCreate(UserCreateRequest) returns (UserCreateResponse);
@@ -140,4 +146,5 @@ service Authentication {
140146
rpc ValidateAccessToken(ValidateAccessTokenRequest) returns (ValidateAccessTokenResponse);
141147
rpc InvitationDelete(InvitationDeleteRequest) returns (InvitationDeleteResponse);
142148
rpc InviteUserToTeam(InviteUserToTeamRequest) returns (InviteUserToTeamResponse);
149+
rpc UpdateTeam(UpdateTeamRequest) returns (Team);
143150
}

0 commit comments

Comments
 (0)