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

Merge pull request #805 from weseek/fix/796-show-anyone-knows-link

Fix/796 show anyone knows link
Yuki Takei 7 лет назад
Родитель
Сommit
c09ded38db

+ 1 - 1
src/server/events/user.js

@@ -14,7 +14,7 @@ UserEvent.prototype.onActivated = async function(user) {
 
   const userPagePath = Page.getUserPagePath(user);
 
-  const page = await Page.findByPathAndViewer(userPagePath, user);
+  const page = await Page.findByPath(userPagePath, user);
 
   if (page == null) {
     const body = `# ${user.username}\nThis is ${user.username}'s page`;

+ 49 - 18
src/server/models/page.js

@@ -62,6 +62,26 @@ const pageSchema = new mongoose.Schema({
 pageSchema.plugin(uniqueValidator);
 
 
+/**
+ * return an array of ancestors paths that is extracted from specified pagePath
+ * e.g.
+ *  when `pagePath` is `/foo/bar/baz`,
+ *  this method returns [`/foo/bar/baz`, `/foo/bar`, `/foo`, `/`]
+ *
+ * @param {string} pagePath
+ * @return {string[]} ancestors paths
+ */
+const extractToAncestorsPaths = (pagePath) => {
+  const ancestorsPaths = [];
+
+  let parentPath;
+  while (parentPath !== '/') {
+    parentPath = nodePath.dirname(parentPath || pagePath);
+    ancestorsPaths.push(parentPath);
+  }
+
+  return ancestorsPaths;
+};
 
 const addSlashOfEnd = (path) => {
   let returnPath = path;
@@ -168,22 +188,24 @@ class PageQueryBuilder {
     return this;
   }
 
-  addConditionToFilteringByViewer(user, userGroups, showPagesRestrictedByOwner, showPagesRestrictedByGroup) {
+  addConditionToFilteringByViewer(user, userGroups, showAnyoneKnowsLink, showPagesRestrictedByOwner, showPagesRestrictedByGroup) {
     const grantConditions = [
       {grant: null},
       {grant: GRANT_PUBLIC},
     ];
 
+    if (showAnyoneKnowsLink) {
+      grantConditions.push({grant: GRANT_RESTRICTED});
+    }
+
     if (showPagesRestrictedByOwner) {
       grantConditions.push(
-        {grant: GRANT_RESTRICTED},
         {grant: GRANT_SPECIFIED},
         {grant: GRANT_OWNER},
       );
     }
     else if (user != null) {
       grantConditions.push(
-        {grant: GRANT_RESTRICTED, grantedUsers: user._id},
         {grant: GRANT_SPECIFIED, grantedUsers: user._id},
         {grant: GRANT_OWNER, grantedUsers: user._id},
       );
@@ -549,7 +571,7 @@ module.exports = function(crowi) {
     }
 
     const queryBuilder = new PageQueryBuilder(baseQuery);
-    queryBuilder.addConditionToFilteringByViewer(user, userGroups);
+    queryBuilder.addConditionToFilteringByViewer(user, userGroups, true);
 
     const count = await queryBuilder.query.exec();
     return count > 0;
@@ -571,7 +593,7 @@ module.exports = function(crowi) {
     }
 
     const queryBuilder = new PageQueryBuilder(baseQuery);
-    queryBuilder.addConditionToFilteringByViewer(user, relatedUserGroups);
+    queryBuilder.addConditionToFilteringByViewer(user, relatedUserGroups, true);
 
     return await queryBuilder.query.exec();
   };
@@ -604,7 +626,7 @@ module.exports = function(crowi) {
     }
 
     const queryBuilder = new PageQueryBuilder(baseQuery);
-    queryBuilder.addConditionToFilteringByViewer(user, relatedUserGroups);
+    queryBuilder.addConditionToFilteringByViewer(user, relatedUserGroups, true);
 
     return await queryBuilder.query.exec();
   };
@@ -623,7 +645,10 @@ module.exports = function(crowi) {
       return null;
     }
 
-    const parentPath = nodePath.dirname(path);
+    const ancestorsPaths = extractToAncestorsPaths(path);
+
+    // pick the longest one
+    const baseQuery = this.findOne({path: { $in: ancestorsPaths }}).sort({path: -1});
 
     let relatedUserGroups = userGroups;
     if (user != null && relatedUserGroups == null) {
@@ -632,11 +657,10 @@ module.exports = function(crowi) {
       relatedUserGroups = await UserGroupRelation.findAllUserGroupIdsRelatedToUser(user);
     }
 
-    const page = await this.findByPathAndViewer(parentPath, user, relatedUserGroups);
+    const queryBuilder = new PageQueryBuilder(baseQuery);
+    queryBuilder.addConditionToFilteringByViewer(user, relatedUserGroups);
 
-    return (page != null)
-      ? page
-      : this.findAncestorByPathAndViewer(parentPath, user, relatedUserGroups);
+    return await queryBuilder.query.exec();
   };
 
   pageSchema.statics.findByRedirectTo = function(path) {
@@ -650,7 +674,7 @@ module.exports = function(crowi) {
     const builder = new PageQueryBuilder(this.find());
     builder.addConditionToListWithDescendants(path, option);
 
-    return await findListFromBuilderAndViewer(builder, user, option);
+    return await findListFromBuilderAndViewer(builder, user, false, option);
   };
 
   /**
@@ -660,7 +684,7 @@ module.exports = function(crowi) {
     const builder = new PageQueryBuilder(this.find());
     builder.addConditionToListByStartWith(path, option);
 
-    return await findListFromBuilderAndViewer(builder, user, option);
+    return await findListFromBuilderAndViewer(builder, user, false, option);
   };
 
   /**
@@ -674,7 +698,12 @@ module.exports = function(crowi) {
     const opt = Object.assign({sort: 'createdAt', desc: -1}, option);
     const builder = new PageQueryBuilder(this.find({ creator: targetUser._id }));
 
-    return await findListFromBuilderAndViewer(builder, currentUser, opt);
+    let showAnyoneKnowsLink = null;
+    if (targetUser != null && currentUser != null) {
+      showAnyoneKnowsLink = targetUser._id.equals(currentUser._id);
+    }
+
+    return await findListFromBuilderAndViewer(builder, currentUser, showAnyoneKnowsLink, opt);
   };
 
   pageSchema.statics.findListByPageIds = async function(ids, option) {
@@ -700,9 +729,10 @@ module.exports = function(crowi) {
    * find pages by PageQueryBuilder
    * @param {PageQueryBuilder} builder
    * @param {User} user
+   * @param {boolean} showAnyoneKnowsLink
    * @param {any} option
    */
-  async function findListFromBuilderAndViewer(builder, user, option) {
+  async function findListFromBuilderAndViewer(builder, user, showAnyoneKnowsLink, option) {
     validateCrowi();
 
     const User = crowi.model('User');
@@ -721,7 +751,7 @@ module.exports = function(crowi) {
     }
 
     // add grant conditions
-    await addConditionToFilteringByViewerForList(builder, user);
+    await addConditionToFilteringByViewerForList(builder, user, showAnyoneKnowsLink);
 
     builder.addConditionToPagenate(opt.offset, opt.limit, sortOpt);
 
@@ -740,8 +770,9 @@ module.exports = function(crowi) {
    *
    * @param {PageQueryBuilder} builder
    * @param {User} user
+   * @param {boolean} showAnyoneKnowsLink
    */
-  async function addConditionToFilteringByViewerForList(builder, user) {
+  async function addConditionToFilteringByViewerForList(builder, user, showAnyoneKnowsLink) {
     validateCrowi();
 
     const Config = crowi.model('Config');
@@ -758,7 +789,7 @@ module.exports = function(crowi) {
       userGroups = await UserGroupRelation.findAllUserGroupIdsRelatedToUser(user);
     }
 
-    return builder.addConditionToFilteringByViewer(user, userGroups, !hidePagesRestrictedByOwner, !hidePagesRestrictedByGroup);
+    return builder.addConditionToFilteringByViewer(user, userGroups, showAnyoneKnowsLink, !hidePagesRestrictedByOwner, !hidePagesRestrictedByGroup);
   }
 
   /**

+ 0 - 1
src/server/routes/page.js

@@ -120,7 +120,6 @@ module.exports = function(crowi, app) {
     if (userData != null) {
       renderVars.pageUser = userData;
       renderVars.bookmarkList = await Bookmark.findByUser(userData, {limit: 10, populatePage: true, requestUser: requestUser});
-      renderVars.createdList = await Page.findListByCreator(userData, {limit: 10}, requestUser);
     }
   }
 

+ 6 - 7
src/server/util/search.js

@@ -541,23 +541,22 @@ SearchClient.prototype.filterPagesByViewer = async function(query, user, userGro
 
   const grantConditions = [
     { term: { grant: GRANT_PUBLIC } },
+    { bool: {
+      must: [
+        { term: { grant: GRANT_RESTRICTED } },
+        { term: { granted_users: user._id.toString() } }
+      ]
+    } },
   ];
 
   if (showPagesRestrictedByOwner) {
     grantConditions.push(
-      { term: { grant: GRANT_RESTRICTED } },
       { term: { grant: GRANT_SPECIFIED } },
       { term: { grant: GRANT_OWNER } },
     );
   }
   else if (user != null) {
     grantConditions.push(
-      { bool: {
-        must: [
-          { term: { grant: GRANT_RESTRICTED } },
-          { term: { granted_users: user._id.toString() } }
-        ]
-      } },
       { bool: {
         must: [
           { term: { grant: GRANT_SPECIFIED } },

+ 25 - 7
src/test/models/page.test.js

@@ -76,7 +76,7 @@ describe('Page', () => {
         path: '/grant/specified',
         grant: Page.GRANT_SPECIFIED,
         grantedUsers: [testUser0],
-        creator: testUser0
+        creator: testUser0,
       },
       {
         path: '/grant/owner',
@@ -92,7 +92,7 @@ describe('Page', () => {
       },
       {
         path: '/grant/groupacl',
-        grant: 5,
+        grant: Page.GRANT_USER_GROUP,
         grantedUsers: [],
         grantedGroup: testGroup0,
         creator: testUser1,
@@ -233,7 +233,7 @@ describe('Page', () => {
     context('with a restricted page and an user who has no grant', () => {
       it('should return false', async() => {
         const user = await User.findOne({email: 'anonymous1@example.com'});
-        const page = await Page.findOne({path: '/grant/restricted'});
+        const page = await Page.findOne({path: '/grant/owner'});
 
         const bool = await Page.isAccessiblePageByViewer(page.id, user);
         expect(bool).to.be.equal(false);
@@ -283,8 +283,8 @@ describe('Page', () => {
 
   describe('.findPage', () => {
     context('findByIdAndViewer', () => {
-      it('should find page', async() => {
-        const pageToFind = createdPages[0];
+      it('should find page (public)', async() => {
+        const pageToFind = createdPages[1];
         const grantedUser = createdUsers[0];
 
         const page = await Page.findByIdAndViewer(pageToFind._id, grantedUser);
@@ -292,8 +292,26 @@ describe('Page', () => {
         expect(page.path).to.equal(pageToFind.path);
       });
 
-      it('should not be found by grant', async() => {
-        const pageToFind = createdPages[0];
+      it('should find page (anyone knows link)', async() => {
+        const pageToFind = createdPages[2];
+        const grantedUser = createdUsers[1];
+
+        const page = await Page.findByIdAndViewer(pageToFind._id, grantedUser);
+        expect(page).to.be.not.null;
+        expect(page.path).to.equal(pageToFind.path);
+      });
+
+      it('should find page (just me)', async() => {
+        const pageToFind = createdPages[4];
+        const grantedUser = createdUsers[0];
+
+        const page = await Page.findByIdAndViewer(pageToFind._id, grantedUser);
+        expect(page).to.be.not.null;
+        expect(page.path).to.equal(pageToFind.path);
+      });
+
+      it('should not be found by grant (just me)', async() => {
+        const pageToFind = createdPages[4];
         const grantedUser = createdUsers[1];
 
         const page = await Page.findByIdAndViewer(pageToFind._id, grantedUser);