Sfoglia il codice sorgente

WIP: refactor models/page.js

* refactor pageShowForCrowiPlus
Yuki Takei 7 anni fa
parent
commit
b26d5a5cc4
2 ha cambiato i file con 87 aggiunte e 143 eliminazioni
  1. 34 52
      src/server/models/page.js
  2. 53 91
      src/server/routes/page.js

+ 34 - 52
src/server/models/page.js

@@ -268,36 +268,28 @@ module.exports = function(crowi) {
     });
   };
 
-  pageSchema.statics.populatePageData = function(pageData, revisionId) {
+  pageSchema.methods.populateDataToShow = async function(revisionId) {
     validateCrowi();
 
-    const Page = crowi.model('Page');
     const User = crowi.model('User');
 
-    pageData.latestRevision = pageData.revision;
-    if (revisionId) {
-      pageData.revision = revisionId;
+    this.latestRevision = this.revision;
+    if (revisionId != null) {
+      this.revision = revisionId;
     }
-    pageData.likerCount = pageData.liker.length || 0;
-    pageData.seenUsersCount = pageData.seenUsers.length || 0;
+    this.likerCount = this.liker.length || 0;
+    this.seenUsersCount = this.seenUsers.length || 0;
 
-    return new Promise(function(resolve, reject) {
-      pageData.populate([
+    return this
+      .execPopulate([
         {path: 'lastUpdateUser', model: 'User', select: User.USER_PUBLIC_FIELDS},
         {path: 'creator', model: 'User', select: User.USER_PUBLIC_FIELDS},
-        {path: 'revision', model: 'Revision'},
+        {path: 'revision', model: 'Revision', populate: {
+          path: 'author', model: 'User', select: User.USER_PUBLIC_FIELDS
+        }},
         //{path: 'liker', options: { limit: 11 }},
         //{path: 'seenUsers', options: { limit: 11 }},
-      ], function(err, pageData) {
-        Page.populate(pageData, {path: 'revision.author', model: 'User', select: User.USER_PUBLIC_FIELDS}, function(err, data) {
-          if (err) {
-            return reject(err);
-          }
-
-          return resolve(data);
-        });
-      });
-    });
+      ]);
   };
 
   // TODO abolish or migrate
@@ -488,38 +480,6 @@ module.exports = function(crowi) {
     return await queryBuilder.query.exec();
   };
 
-  // find page and check if granted user
-  pageSchema.statics.findPage = async function(path, userData, revisionId, ignoreNotFound) {
-    validateCrowi();
-
-    const PageGroupRelation = crowi.model('PageGroupRelation');
-
-    const pageData = await this.findOne({path: path});
-
-    if (pageData == null) {
-      if (ignoreNotFound) {
-        return null;
-      }
-
-      const pageNotFoundError = new Error('Page Not Found');
-      pageNotFoundError.name = 'Crowi:Page:NotFound';
-      throw new Error(pageNotFoundError);
-    }
-
-    if (!pageData.isGrantedFor(userData)) {
-      const isRelationExists = await PageGroupRelation.isExistsGrantedGroupForPageAndUser(pageData, userData);
-      if (isRelationExists) {
-        return await this.populatePageData(pageData, revisionId || null);
-      }
-      else {
-        throw new UserHasNoGrantException('Page is not granted for the user', userData);
-      }
-    }
-    else {
-      return await this.populatePageData(pageData, revisionId || null);
-    }
-  };
-
   /**
    * find all templates applicable to the new page
    */
@@ -608,6 +568,28 @@ module.exports = function(crowi) {
     return this.findOne({path});
   };
 
+  pageSchema.statics.findPageByPathAndViewer = async function(path, user) {
+    validateCrowi();
+
+    if (path == null) {
+      throw new Error('path is required.');
+    }
+
+    // const Page = this;
+    const baseQuery = this.findOne({path});
+
+    const UserGroupRelation = crowi.model('UserGroupRelation');
+    let userGroups = [];
+    if (user != null) {
+      userGroups = await UserGroupRelation.findAllUserGroupIdsRelatedToUser(user);
+    }
+
+    const queryBuilder = new PageQueryBuilder(baseQuery);
+    queryBuilder.addConditionToFilteringByViewer(user, userGroups);
+
+    return await queryBuilder.query.exec();
+  };
+
   pageSchema.statics.findListByPageIds = function(ids, options) {
     validateCrowi();
 

+ 53 - 91
src/server/routes/page.js

@@ -268,8 +268,9 @@ module.exports = function(crowi, app) {
     return res.redirect(path);
   };
 
-  actions.pageShowForCrowiPlus = function(req, res) {
+  actions.pageShowForCrowiPlus = async function(req, res) {
     const path = getPathFromRequest(req);
+    const revisionId = req.query.revision;
 
     const limit = 50;
     const offset = parseInt(req.query.offset)  || 0;
@@ -303,20 +304,23 @@ module.exports = function(crowi, app) {
 
     let view = 'customlayout-selector/page';
 
-    let isRedirect = false;
-    Page.findPage(path, req.user, req.query.revision)
-    .then(function(page) {
-      debug('Page found', page._id, page.path);
+    let page = await Page.findPageByPathAndViewer(path, req.user);
 
-      // redirect
-      if (page.redirectTo) {
+    if (page == null) {
+      // https://weseek.myjetbrains.com/youtrack/issue/GC-1224
+      // TODO notfound or forbidden
+    }
+    else if (page.redirectTo) {
         debug(`Redirect to '${page.redirectTo}'`);
-        isRedirect = true;
         return res.redirect(encodeURI(page.redirectTo + '?redirectFrom=' + pagePathUtils.encodePagePath(page.path)));
       }
 
-      renderVars.page = page;
+    debug('Page found', page._id, page.path);
+
+    // populate
+    page = await page.populateDataToShow(revisionId);
 
+    renderVars.page = page;
       if (page) {
         renderVars.path = page.path;
         renderVars.revision = page.revision;
@@ -325,86 +329,26 @@ module.exports = function(crowi, app) {
         renderVars.revisionHackmdSynced = page.revisionHackmdSynced;
         renderVars.hasDraftOnHackmd = page.hasDraftOnHackmd;
 
-        return Revision.findRevisionList(page.path, {})
-        .then(function(tree) {
-          renderVars.tree = tree;
-        })
-        .then(() => {
-          return PageGroupRelation.findByPage(renderVars.page);
-        })
-        .then((pageGroupRelation) => {
-          if (pageGroupRelation != null) {
-            renderVars.pageRelatedGroup = pageGroupRelation.relatedGroup;
-          }
-        })
-        .then(() => {
-          return getSlackChannels(page);
-        })
-        .then((channels) => {
-          renderVars.slack = channels;
-        })
-        .then(function() {
-          const userPage = isUserPage(page.path);
-          let userData = null;
+      renderVars.tree = await Revision.findRevisionList(page.path, {});
+      renderVars.slack = await getSlackChannels(page);
 
+      const userPage = isUserPage(page.path);
           if (userPage) {
             // change template
             view = 'customlayout-selector/user_page';
 
-            return User.findUserByUsername(User.getUsernameByPath(page.path))
-            .then(function(data) {
-              if (data === null) {
-                throw new Error('The user not found.');
-              }
-              userData = data;
+        const userData = await User.findUserByUsername(User.getUsernameByPath(page.path));
+        if (userData != null) {
               renderVars.pageUser = userData;
-
-              return Bookmark.findByUser(userData, {limit: 10, populatePage: true, requestUser: req.user});
-            }).then(function(bookmarkList) {
-              renderVars.bookmarkList = bookmarkList;
-
-              return Page.findListByCreator(userData, {limit: 10}, req.user);
-            }).then(function(createdList) {
-              renderVars.createdList = createdList;
-              return Promise.resolve();
-            }).catch(function(err) {
-              debug('Error on finding user related entities', err);
-              // pass
-            });
+          renderVars.bookmarkList = await Bookmark.findByUser(userData, {limit: 10, populatePage: true, requestUser: req.user});
+          renderVars.createdList = await Page.findListByCreator(userData, {limit: 10}, req.user);
           }
-        });
-      }
-    })
-    // page is not found or user is forbidden
-    .catch(function(err) {
-      let isForbidden = false;
-      if (err.name === 'UserHasNoGrantException') {
-        isForbidden = true;
-      }
-
-      if (isForbidden) {
-        view = 'customlayout-selector/forbidden';
-        return;
-      }
       else {
-        view = 'customlayout-selector/not_found';
-
-        // look for templates
-        return Page.findTemplate(path)
-          .then(template => {
-            if (template) {
-              template = replacePlaceholders(template, req);
+          debug('Error on finding user related entities');
             }
-
-            renderVars.template = template;
-          });
       }
-    })
-    // get list pages
-    .then(function() {
-      if (!isRedirect) {
-        Page.findListWithDescendants(path, req.user, queryOptions)
-          .then(function(pageList) {
+
+      const pageList = await Page.findListWithDescendants(path, req.user, queryOptions);
             if (pageList.length > limit) {
               pageList.pop();
             }
@@ -417,19 +361,37 @@ module.exports = function(crowi, app) {
             renderVars.pager = generatePager(pagerOptions);
             renderVars.pages = pagePathUtils.encodePagesPath(pageList);
 
-            return;
-          })
-          .then(function() {
-            return interceptorManager.process('beforeRenderPage', req, res, renderVars);
-          })
-          .then(function() {
-            res.render(req.query.presentation ? 'page_presentation' : view, renderVars);
-          })
-          .catch(function(err) {
-            logger.error('Error on rendering pageListShowForCrowiPlus', err);
-          });
+      await interceptorManager.process('beforeRenderPage', req, res, renderVars);
+      // https://weseek.myjetbrains.com/youtrack/issue/GC-1224
+      // TODO fetch minimum data if the request is for presentation
+      return res.render(req.query.presentation ? 'page_presentation' : view, renderVars);
       }
-    });
+
+    // https://weseek.myjetbrains.com/youtrack/issue/GC-1224
+    // TODO render if not found or user is forbidden
+
+    // let isForbidden = false;
+    // if (err.name === 'UserHasNoGrantException') {
+    //   isForbidden = true;
+    // }
+
+    // if (isForbidden) {
+    //   view = 'customlayout-selector/forbidden';
+    //   return;
+    // }
+    // else {
+    //   view = 'customlayout-selector/not_found';
+
+    //   // look for templates
+    //   return Page.findTemplate(path)
+    //     .then(template => {
+    //       if (template) {
+    //         template = replacePlaceholders(template, req);
+    //       }
+
+    //       renderVars.template = template;
+    //     });
+    // }
   };
 
   const getSlackChannels = async page => {