Taichi Masuyama 4 лет назад
Родитель
Сommit
683220a641

+ 5 - 38
packages/app/src/server/models/obsolete-page.js

@@ -1,6 +1,10 @@
 import { templateChecker, pagePathUtils } from '@growi/core';
+
+import { generateGrantCondition } from './page';
+
 import loggerFactory from '~/utils/logger';
 
+
 // disable no-return-await for model functions
 /* eslint-disable no-return-await */
 
@@ -239,7 +243,7 @@ export class PageQueryBuilder {
   }
 
   addConditionToFilteringByViewer(user, userGroups, showAnyoneKnowsLink = false, showPagesRestrictedByOwner = false, showPagesRestrictedByGroup = false) {
-    const condition = this.generateGrantCondition(user, userGroups, showAnyoneKnowsLink, showPagesRestrictedByOwner, showPagesRestrictedByGroup);
+    const condition = generateGrantCondition(user, userGroups, showAnyoneKnowsLink, showPagesRestrictedByOwner, showPagesRestrictedByGroup);
 
     this.query = this.query
       .and(condition);
@@ -247,43 +251,6 @@ export class PageQueryBuilder {
     return this;
   }
 
-  generateGrantCondition(user, userGroups, showAnyoneKnowsLink = false, showPagesRestrictedByOwner = false, showPagesRestrictedByGroup = false) {
-    const grantConditions = [
-      { grant: null },
-      { grant: GRANT_PUBLIC },
-    ];
-
-    if (showAnyoneKnowsLink) {
-      grantConditions.push({ grant: GRANT_RESTRICTED });
-    }
-
-    if (showPagesRestrictedByOwner) {
-      grantConditions.push(
-        { grant: GRANT_SPECIFIED },
-        { grant: GRANT_OWNER },
-      );
-    }
-    else if (user != null) {
-      grantConditions.push(
-        { grant: GRANT_SPECIFIED, grantedUsers: user._id },
-        { grant: GRANT_OWNER, grantedUsers: user._id },
-      );
-    }
-
-    if (showPagesRestrictedByGroup) {
-      grantConditions.push(
-        { grant: GRANT_USER_GROUP },
-      );
-    }
-    else if (userGroups != null && userGroups.length > 0) {
-      grantConditions.push(
-        { grant: GRANT_USER_GROUP, grantedGroup: { $in: userGroups } },
-      );
-    }
-
-    return { $or: grantConditions };
-  }
-
   addConditionToPagenate(offset, limit, sortOpt) {
     this.query = this.query
       .sort(sortOpt).skip(offset).limit(limit); // eslint-disable-line newline-per-chained-call

+ 47 - 57
packages/app/src/server/models/page.ts

@@ -51,6 +51,10 @@ export interface PageModel extends Model<PageDocument> {
   findChildrenByParentPathOrIdAndViewer(parentPathOrId: string, user, userGroups?): Promise<PageDocument[]>
   findAncestorsChildrenByPathAndViewer(path: string, user, userGroups?): Promise<Record<string, PageDocument[]>>
 
+  generateGrantCondition(
+    user, userGroups, showAnyoneKnowsLink?: boolean, showPagesRestrictedByOwner?: boolean, showPagesRestrictedByGroup?: boolean,
+  ): { $or: any[] }
+
   PageQueryBuilder: typeof PageQueryBuilder
 
   GRANT_PUBLIC
@@ -586,6 +590,49 @@ schema.statics.removeEmptyPagesByPaths = async function(paths: string[]): Promis
   });
 };
 
+export function generateGrantCondition(
+    user, userGroups, showAnyoneKnowsLink = false, showPagesRestrictedByOwner = false, showPagesRestrictedByGroup = false,
+): { $or: any[] } {
+  const grantConditions: AnyObject[] = [
+    { grant: null },
+    { grant: GRANT_PUBLIC },
+  ];
+
+  if (showAnyoneKnowsLink) {
+    grantConditions.push({ grant: GRANT_RESTRICTED });
+  }
+
+  if (showPagesRestrictedByOwner) {
+    grantConditions.push(
+      { grant: GRANT_SPECIFIED },
+      { grant: GRANT_OWNER },
+    );
+  }
+  else if (user != null) {
+    grantConditions.push(
+      { grant: GRANT_SPECIFIED, grantedUsers: user._id },
+      { grant: GRANT_OWNER, grantedUsers: user._id },
+    );
+  }
+
+  if (showPagesRestrictedByGroup) {
+    grantConditions.push(
+      { grant: GRANT_USER_GROUP },
+    );
+  }
+  else if (userGroups != null && userGroups.length > 0) {
+    grantConditions.push(
+      { grant: GRANT_USER_GROUP, grantedGroup: { $in: userGroups } },
+    );
+  }
+
+  return {
+    $or: grantConditions,
+  };
+}
+
+schema.statics.generateGrantCondition = generateGrantCondition;
+
 export type PageCreateOptions = {
   format?: string
   grantUserGroupId?: ObjectIdLike
@@ -790,60 +837,3 @@ export default (crowi: Crowi): any => {
 
   return getOrCreateModel<PageDocument, PageModel>('Page', schema as any); // TODO: improve type
 };
-
-/*
- * Aggregation utilities
- */
-// TODO: use the original type when upgraded https://github.com/Automattic/mongoose/blob/master/index.d.ts#L3090
-type PipelineStageMatch = {
-  $match: AnyObject
-};
-
-export const generateGrantCondition = async(
-    user, _userGroups, showAnyoneKnowsLink = false, showPagesRestrictedByOwner = false, showPagesRestrictedByGroup = false,
-): Promise<PipelineStageMatch> => {
-  let userGroups = _userGroups;
-  if (user != null && userGroups == null) {
-    const UserGroupRelation: any = mongoose.model('UserGroupRelation');
-    userGroups = await UserGroupRelation.findAllUserGroupIdsRelatedToUser(user);
-  }
-
-  const grantConditions: AnyObject[] = [
-    { grant: null },
-    { grant: GRANT_PUBLIC },
-  ];
-
-  if (showAnyoneKnowsLink) {
-    grantConditions.push({ grant: GRANT_RESTRICTED });
-  }
-
-  if (showPagesRestrictedByOwner) {
-    grantConditions.push(
-      { grant: GRANT_SPECIFIED },
-      { grant: GRANT_OWNER },
-    );
-  }
-  else if (user != null) {
-    grantConditions.push(
-      { grant: GRANT_SPECIFIED, grantedUsers: user._id },
-      { grant: GRANT_OWNER, grantedUsers: user._id },
-    );
-  }
-
-  if (showPagesRestrictedByGroup) {
-    grantConditions.push(
-      { grant: GRANT_USER_GROUP },
-    );
-  }
-  else if (userGroups != null && userGroups.length > 0) {
-    grantConditions.push(
-      { grant: GRANT_USER_GROUP, grantedGroup: { $in: userGroups } },
-    );
-  }
-
-  return {
-    $match: {
-      $or: grantConditions,
-    },
-  };
-};

+ 12 - 5
packages/app/src/server/service/page.ts

@@ -8,7 +8,7 @@ import { Readable, Writable } from 'stream';
 import { createBatchStream } from '~/server/util/batch-stream';
 import loggerFactory from '~/utils/logger';
 import {
-  CreateMethod, generateGrantCondition, PageCreateOptions, PageModel, PageDocument,
+  CreateMethod, PageCreateOptions, PageModel, PageDocument,
 } from '~/server/models/page';
 import { stringifySnapshot } from '~/models/serializers/in-app-notification-snapshot/page';
 import {
@@ -2082,11 +2082,16 @@ class PageService {
   }
 
   async shortBodiesMapByPageIds(pageIds: ObjectId[] = [], user): Promise<Record<string, string | null>> {
-    const Page = mongoose.model('Page');
+    const Page = mongoose.model('Page') as unknown as PageModel;
     const MAX_LENGTH = 350;
 
     // aggregation options
-    const viewerCondition = await generateGrantCondition(user, null);
+    let userGroups;
+    if (user != null && userGroups == null) {
+      const UserGroupRelation = mongoose.model('UserGroupRelation') as any; // Typescriptize model
+      userGroups = await UserGroupRelation.findAllUserGroupIdsRelatedToUser(user);
+    }
+    const viewerCondition = Page.generateGrantCondition(user, userGroups);
     const filterByIds = {
       _id: { $in: pageIds },
     };
@@ -2100,7 +2105,9 @@ class PageService {
             $match: filterByIds,
           },
           // filter by viewer
-          viewerCondition,
+          {
+            $match: viewerCondition,
+          },
           // lookup: https://docs.mongodb.com/v4.4/reference/operator/aggregation/lookup/
           {
             $lookup: {
@@ -2487,7 +2494,7 @@ class PageService {
       userGroups = await UserGroupRelation.findAllUserGroupIdsRelatedToUser(user);
     }
 
-    const grantFiltersByUser: { $or: any[] } = PageQueryBuilder.generateGrantCondition(user, userGroups);
+    const grantFiltersByUser: { $or: any[] } = Page.generateGrantCondition(user, userGroups);
 
     return this._normalizeParentRecursively(regexps, ancestorPaths, grantFiltersByUser, user);
   }