Skip to content

Commit 63dc2e2

Browse files
committed
[backend] users add relations in orga admin context (#13901)
1 parent 396f8da commit 63dc2e2

File tree

1 file changed

+42
-38
lines changed
  • opencti-platform/opencti-graphql/src/domain

1 file changed

+42
-38
lines changed

opencti-platform/opencti-graphql/src/domain/user.js

Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ const extractTokenFromBasicAuth = async (authorization) => {
184184

185185
export const findById = async (context, user, userId) => {
186186
if (!isUserHasCapability(user, SETTINGS_SET_ACCESSES) && user.id !== userId) {
187-
// if no organization in common with the logged user
187+
// if no organization in common with the logged user administrated organizations
188188
const memberOrganizations = await fullEntitiesThroughRelationsToList(context, user, userId, RELATION_PARTICIPATE_TO, ENTITY_TYPE_IDENTITY_ORGANIZATION);
189189
const myOrganizationsIds = user.administrated_organizations.map((organization) => organization.id);
190190
if (!memberOrganizations.map((organization) => organization.id).find((orgaId) => myOrganizationsIds.includes(orgaId))) {
@@ -525,17 +525,35 @@ const isUserAdministratingOrga = (user, organizationId) => {
525525
return user.administrated_organizations.some(({ id }) => id === organizationId);
526526
};
527527

528+
const loadUserToUpdateWithAccessCheck = async (context, user, userId) => {
529+
const userToUpdate = await internalLoadById(context, user, userId, { type: ENTITY_TYPE_USER });
530+
if (!userToUpdate) {
531+
throw FunctionalError(`${ENTITY_TYPE_USER} cannot be found.`, { userId });
532+
}
533+
if (!isUserHasCapability(user, SETTINGS_SET_ACCESSES) && user.id !== userId) {
534+
// Check in an organization admin edits a user that's not in its administrated organizations
535+
if (isOnlyOrgaAdmin(user)) {
536+
const myAdministratedOrganizationsIds = user.administrated_organizations.map((orga) => orga.id);
537+
if (!userToUpdate[RELATION_PARTICIPATE_TO].find((orga) => myAdministratedOrganizationsIds.includes(orga))) {
538+
throw ForbiddenAccess();
539+
}
540+
} else {
541+
throw ForbiddenAccess();
542+
}
543+
}
544+
return userToUpdate;
545+
};
546+
528547
export const assignOrganizationToUser = async (context, user, userId, organizationId) => {
529548
if (isOnlyOrgaAdmin(user)) {
530549
// When user is organization admin, we make sure she is also admin of organization added
531550
if (!isUserAdministratingOrga(user, organizationId)) {
532551
throw ForbiddenAccess();
533552
}
534553
}
535-
const targetUser = await findById(context, user, userId);
536-
if (!targetUser) {
537-
throw FunctionalError('Cannot add the relation, User cannot be found.', { userId });
538-
}
554+
// check the user is accessible
555+
const targetUser = await loadUserToUpdateWithAccessCheck(context, user, userId);
556+
539557
const input = { fromId: userId, toId: organizationId, relationship_type: RELATION_PARTICIPATE_TO };
540558
const created = await createRelation(context, user, input);
541559
const actionEmail = ENABLED_DEMO_MODE ? REDACTED_USER.user_email : created.from.user_email;
@@ -899,14 +917,7 @@ export const roleDeleteRelation = async (context, user, roleId, toId, relationsh
899917
// User related
900918
export const userEditField = async (context, user, userId, rawInputs) => {
901919
const inputs = [];
902-
const userToUpdate = await internalLoadById(context, user, userId);
903-
// Check in an organization admin edits a user that's not in its administrated organizations
904-
const myAdministratedOrganizationsIds = user.administrated_organizations.map((orga) => orga.id);
905-
if (isOnlyOrgaAdmin(user)) {
906-
if (userId !== user.id && !userToUpdate[RELATION_PARTICIPATE_TO].find((orga) => myAdministratedOrganizationsIds.includes(orga))) {
907-
throw ForbiddenAccess();
908-
}
909-
}
920+
const userToUpdate = await loadUserToUpdateWithAccessCheck(context, user, userId);
910921
let skipThisInput = false;
911922
for (let index = 0; index < rawInputs.length; index += 1) {
912923
const input = rawInputs[index];
@@ -1186,14 +1197,9 @@ export const deleteAllNotificationByUser = async (userId) => {
11861197
* @returns {Promise<*>}
11871198
*/
11881199
export const userDelete = async (context, user, userId) => {
1189-
if (isOnlyOrgaAdmin(user)) {
1190-
// When user is organization admin, we make sure that the deleted user is in one of the administrated organizations of the admin
1191-
const userData = await storeLoadById(context, user, userId, ENTITY_TYPE_USER);
1192-
const myAdministratedOrganizationsIds = user.administrated_organizations.map(({ id }) => id);
1193-
if (!userData[RELATION_PARTICIPATE_TO].find((orga) => myAdministratedOrganizationsIds.includes(orga))) {
1194-
throw ForbiddenAccess();
1195-
}
1196-
}
1200+
// check rights
1201+
await loadUserToUpdateWithAccessCheck(context, user, userId);
1202+
11971203
await deleteAllTriggerAndDigestByUser(userId);
11981204
await deleteAllNotificationByUser(userId);
11991205
await deleteAllWorkspaceForUser(context, user, userId);
@@ -1213,14 +1219,14 @@ export const userDelete = async (context, user, userId) => {
12131219
};
12141220

12151221
export const userAddRelation = async (context, user, userId, input) => {
1216-
const userData = await storeLoadById(context, user, userId, ENTITY_TYPE_USER);
1217-
if (!userData) {
1218-
throw FunctionalError(`Cannot add the relation, ${ENTITY_TYPE_USER} cannot be found.`, { userId });
1219-
}
1222+
// check the user is accessible
1223+
const userData = await loadUserToUpdateWithAccessCheck(context, user, userId);
1224+
1225+
// check the relationship type
12201226
if (!isInternalRelationship(input.relationship_type)) {
12211227
throw FunctionalError(`Only ${ABSTRACT_INTERNAL_RELATIONSHIP} can be added through this method, got ${input.relationship_type}.`);
12221228
}
1223-
// Check in case organization admins adds non-grantable goup a user
1229+
// Check in case organization admins adds non-grantable group a user
12241230
const myGrantableGroups = R.uniq(user.administrated_organizations.map((orga) => orga.grantable_groups).flat());
12251231
if (isOnlyOrgaAdmin(user)) {
12261232
if (input.relationship_type === 'member-of' && !myGrantableGroups.includes(input.toId)) {
@@ -1260,10 +1266,9 @@ export const userDeleteRelation = async (context, user, targetUser, toId, relati
12601266
};
12611267

12621268
export const userIdDeleteRelation = async (context, user, userId, toId, relationshipType) => {
1263-
const userData = await storeLoadById(context, user, userId, ENTITY_TYPE_USER);
1264-
if (!userData) {
1265-
throw FunctionalError('Cannot delete the relation, User cannot be found.', { userId });
1266-
}
1269+
// check the user is accessible
1270+
const userData = await loadUserToUpdateWithAccessCheck(context, user, userId);
1271+
12671272
if (!isInternalRelationship(relationshipType)) {
12681273
throw FunctionalError(`Only ${ABSTRACT_INTERNAL_RELATIONSHIP} can be deleted through this method, got ${relationshipType}.`);
12691274
}
@@ -1277,10 +1282,8 @@ export const userDeleteOrganizationRelation = async (context, user, userId, toId
12771282
throw ForbiddenAccess();
12781283
}
12791284
}
1280-
const targetUser = await findById(context, user, userId);
1281-
if (!targetUser) {
1282-
throw FunctionalError('Cannot delete the relation, User cannot be found.', { userId });
1283-
}
1285+
// check the user is accessible
1286+
const targetUser = await loadUserToUpdateWithAccessCheck(context, user, userId);
12841287

12851288
const { to } = await deleteRelationsByFromAndTo(context, user, userId, toId, RELATION_PARTICIPATE_TO, ABSTRACT_INTERNAL_RELATIONSHIP);
12861289
if (to.authorized_authorities?.includes(userId)) {
@@ -1690,10 +1693,9 @@ export const userRenewToken = async (context, user, userId) => {
16901693
throw FunctionalError('Cannot renew token of admin user defined in configuration, please change configuration instead.');
16911694
}
16921695

1693-
const userData = await storeLoadById(context, user, userId, ENTITY_TYPE_USER);
1694-
if (!userData) {
1695-
throw FunctionalError(`Cannot renew token, ${userId} user cannot be found.`);
1696-
}
1696+
// check the user is accessible
1697+
const userData = await loadUserToUpdateWithAccessCheck(context, user, userId);
1698+
16971699
const patch = { api_token: uuid() };
16981700
const { element } = await patchAttribute(context, user, userId, ENTITY_TYPE_USER, patch);
16991701

@@ -1872,11 +1874,13 @@ export const findDefaultDashboards = async (context, user, currentUser) => {
18721874

18731875
// region context
18741876
export const userCleanContext = async (context, user, userId) => {
1877+
await loadUserToUpdateWithAccessCheck(context, user, userId);
18751878
await delEditContext(user, userId);
18761879
return storeLoadById(context, user, userId, ENTITY_TYPE_USER);
18771880
};
18781881

18791882
export const userEditContext = async (context, user, userId, input) => {
1883+
await loadUserToUpdateWithAccessCheck(context, user, userId);
18801884
await setEditContext(user, userId, input);
18811885
return storeLoadById(context, user, userId, ENTITY_TYPE_USER);
18821886
};

0 commit comments

Comments
 (0)