|
|
@@ -1,11 +1,13 @@
|
|
|
import mongoose from 'mongoose';
|
|
|
-import { pagePathUtils } from '@growi/core';
|
|
|
+import { pagePathUtils, pathUtils } from '@growi/core';
|
|
|
+import escapeStringRegexp from 'escape-string-regexp';
|
|
|
|
|
|
import UserGroup from '~/server/models/user-group';
|
|
|
import { PageModel } from '~/server/models/page';
|
|
|
import { PageQueryBuilder } from '../models/obsolete-page';
|
|
|
import { isIncludesObjectId, removeDuplicates, excludeTestIdsFromTargetIds } from '~/server/util/compare-objectId';
|
|
|
|
|
|
+const { addTrailingSlash } = pathUtils;
|
|
|
const { isTopPage } = pagePathUtils;
|
|
|
|
|
|
type ObjectId = mongoose.Types.ObjectId;
|
|
|
@@ -254,32 +256,50 @@ class PageGrantService {
|
|
|
/*
|
|
|
* make granted users list of descendant's
|
|
|
*/
|
|
|
- // find all descendants excluding empty pages
|
|
|
- const builderForDescendants = new PageQueryBuilder(Page.find({}, {
|
|
|
- _id: 0, grant: 1, grantedUsers: 1, grantedGroup: 1,
|
|
|
- }), false);
|
|
|
- const descendants = await builderForDescendants
|
|
|
- .addConditionToListOnlyDescendants(targetPath)
|
|
|
- .query
|
|
|
- .exec();
|
|
|
+ const pathWithTrailingSlash = addTrailingSlash(targetPath);
|
|
|
+ const startsPattern = escapeStringRegexp(pathWithTrailingSlash);
|
|
|
+
|
|
|
+ const result = await Page.aggregate([
|
|
|
+ { // match to descendants excluding empty pages
|
|
|
+ $match: {
|
|
|
+ path: new RegExp(`^${startsPattern}`),
|
|
|
+ isEmpty: { $ne: true },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ $project: {
|
|
|
+ _id: 0,
|
|
|
+ grant: 1,
|
|
|
+ grantedUsers: 1,
|
|
|
+ grantedGroup: 1,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ { // remove duplicates from pipeline
|
|
|
+ $group: {
|
|
|
+ _id: '$grant',
|
|
|
+ grantedGroupSet: { $addToSet: '$grantedGroup' },
|
|
|
+ grantedUsersSet: { $addToSet: '$grantedUsers' },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ { // flatten granted user set
|
|
|
+ $unwind: {
|
|
|
+ path: '$grantedUsersSet',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // GRANT_PUBLIC group
|
|
|
+ const isPublicExist = result.some(r => r._id === Page.GRANT_PUBLIC);
|
|
|
+ // GRANT_OWNER group
|
|
|
+ const grantOwnerResult = result.filter(r => r._id === Page.GRANT_OWNER)[0]; // users of GRANT_OWNER
|
|
|
+ const grantedUserIds: ObjectId[] = grantOwnerResult?.grantedUsersSet ?? [];
|
|
|
+ // GRANT_USER_GROUP group
|
|
|
+ const grantUserGroupResult = result.filter(r => r._id === Page.GRANT_USER_GROUP)[0]; // users of GRANT_OWNER
|
|
|
+ const grantedGroupIds = grantUserGroupResult?.grantedGroupSet ?? [];
|
|
|
|
|
|
- const isPublicExist = descendants.some(d => d.grant === Page.GRANT_PUBLIC);
|
|
|
-
|
|
|
- let grantedUsersOfGrantOwner: ObjectId[] = []; // users of GRANT_OWNER
|
|
|
- const grantedGroups: ObjectId[] = [];
|
|
|
- descendants.forEach((d) => {
|
|
|
- if (d.grantedUsers != null) {
|
|
|
- grantedUsersOfGrantOwner = grantedUsersOfGrantOwner.concat(d.grantedUsers);
|
|
|
- }
|
|
|
- if (d.grantedGroup != null) {
|
|
|
- grantedGroups.push(d.grantedGroup);
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- const grantedGroupIds = removeDuplicates(grantedGroups);
|
|
|
return {
|
|
|
isPublicExist,
|
|
|
- grantedUserIds: grantedUsersOfGrantOwner,
|
|
|
+ grantedUserIds,
|
|
|
grantedGroupIds,
|
|
|
};
|
|
|
}
|