Просмотр исходного кода

refs 124384: relate user to parent groups

Futa Arai 2 лет назад
Родитель
Сommit
3b0584cede

+ 11 - 0
apps/app/src/server/models/external-user-group-relation.ts

@@ -25,4 +25,15 @@ schema.statics.findOrCreateRelation = function(userGroup, user) {
   }, {}, { upsert: true });
 };
 
+schema.statics.createRelations = async function(userGroupIds, user) {
+  const documentsToInsert = userGroupIds.map((groupId) => {
+    return {
+      relatedGroup: groupId,
+      relatedUser: user._id,
+    };
+  });
+
+  return this.insertMany(documentsToInsert);
+};
+
 export default getOrCreateModel<ExternalUserGroupRelationDocument, ExternalUserGroupRelationModel>('ExternalUserGroupRelation', schema);

+ 24 - 2
apps/app/src/server/models/external-user-group.ts

@@ -24,7 +24,7 @@ const schema = new Schema<ExternalUserGroupDocument, ExternalUserGroupModel>({
 schema.statics.findAndUpdateOrCreateGroup = async function(name, description, externalId, provider, parentId) {
   // create without parent
   if (parentId == null) {
-    return this.findOneAndUpdate({ name }, { description, externalId, provider }, { upsert: true });
+    return this.findOneAndUpdate({ name }, { description, externalId, provider }, { upsert: true, new: true });
   }
 
   // create with parent
@@ -34,7 +34,29 @@ schema.statics.findAndUpdateOrCreateGroup = async function(name, description, ex
   }
   return this.findOneAndUpdate({ name }, {
     description, externalId, provider, parent,
-  }, { upsert: true });
+  }, { upsert: true, new: true });
+};
+
+/**
+ * Find all ancestor groups starting from the UserGroup of the initial "group".
+ * Set "ancestors" as "[]" if the initial group is unnecessary as result.
+ * @param groups ExternalUserGroupDocument
+ * @param ancestors ExternalUserGroupDocument[]
+ * @returns ExternalUserGroupDocument[]
+ */
+schema.statics.findGroupsWithAncestorsRecursively = async function(group, ancestors = [group]) {
+  if (group == null) {
+    return ancestors;
+  }
+
+  const parent = await this.findOne({ _id: group.parent });
+  if (parent == null) {
+    return ancestors;
+  }
+
+  ancestors.unshift(parent);
+
+  return this.findGroupsWithAncestorsRecursively(parent, ancestors);
 };
 
 export default getOrCreateModel<ExternalUserGroupDocument, ExternalUserGroupModel>('ExternalUserGroup', schema);

+ 3 - 4
apps/app/src/server/routes/apiv3/user-group.js

@@ -657,13 +657,12 @@ module.exports = (crowi) => {
       const userGroups = await UserGroup.findGroupsWithAncestorsRecursively(userGroup);
       const userGroupIds = userGroups.map(g => g._id);
 
-      // check for duplicate users in groups
+      // remove existing relations from list to create
       const existingRelations = await UserGroupRelation.find({ relatedGroup: { $in: userGroupIds }, relatedUser: user._id });
       const existingGroupIds = existingRelations.map(r => r.relatedGroup);
+      const groupIdsToCreateRelation = excludeTestIdsFromTargetIds(userGroupIds, existingGroupIds);
 
-      const groupIdsOfRelationToCreate = excludeTestIdsFromTargetIds(userGroupIds, existingGroupIds);
-
-      const insertedRelations = await UserGroupRelation.createRelations(groupIdsOfRelationToCreate, user);
+      const insertedRelations = await UserGroupRelation.createRelations(groupIdsToCreateRelation, user);
       const serializedUser = serializeUserSecurely(user);
 
       const parameters = { action: SupportedAction.ACTION_ADMIN_USER_GROUP_ADD_USER };

+ 11 - 2
apps/app/src/server/service/external-group/external-user-group-sync-service.ts

@@ -2,6 +2,7 @@ import { ExternalGroupProviderType, ExternalUserGroupTreeNode, IExternalUserGrou
 import { IUserHasId } from '~/interfaces/user';
 import ExternalUserGroup from '~/server/models/external-user-group';
 import ExternalUserGroupRelation from '~/server/models/external-user-group-relation';
+import { excludeTestIdsFromTargetIds } from '~/server/util/compare-objectId';
 
 import { configManager } from '../config-manager';
 
@@ -56,9 +57,17 @@ abstract class ExternalUserGroupSyncService {
     await Promise.all(node.externalUserIds.map((externalUserId) => {
       return (async() => {
         const user = await this.getMemberUser(externalUserId);
-        // TODO: create relations for parent groups also
+
         if (user != null) {
-          await ExternalUserGroupRelation.findOrCreateRelation(externalUserGroup, user);
+          const userGroups = await ExternalUserGroup.findGroupsWithAncestorsRecursively(externalUserGroup);
+          const userGroupIds = userGroups.map(g => g._id);
+
+          // remove existing relations from list to create
+          const existingRelations = await ExternalUserGroupRelation.find({ relatedGroup: { $in: userGroupIds }, relatedUser: user._id });
+          const existingGroupIds = existingRelations.map(r => r.relatedGroup);
+          const groupIdsToCreateRelation = excludeTestIdsFromTargetIds(userGroupIds, existingGroupIds);
+
+          await ExternalUserGroupRelation.createRelations(groupIdsToCreateRelation, user);
         }
       })();
     }));