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

# Feature/196, 198, 199 Grouping users
* Fix page-edit-form grant user-group selectable.
* Fix page update logic page-group-relation updatable.
* fix the page-find logic which provides page for granted user.(for user who related the granted user-group)

Tatsuya Ise 8 лет назад
Родитель
Сommit
a322bbb332
5 измененных файлов с 152 добавлено и 90 удалено
  1. 47 30
      lib/models/page-group-relation.js
  2. 59 44
      lib/models/page.js
  3. 22 4
      lib/models/user-group-relation.js
  4. 18 8
      lib/routes/page.js
  5. 6 4
      lib/views/_form.html

+ 47 - 30
lib/models/page-group-relation.js

@@ -45,7 +45,7 @@ module.exports = function(crowi) {
 
     return new Promise(function (resolve, reject) {
       PageGroupRelation
-        .find({ relatedGroup: userGroup })
+        .find({ relatedGroup: userGroup.id })
         .populate('targetPage')
         .exec(function (err, pageGroupRelationData) {
           if (err) {
@@ -56,26 +56,6 @@ module.exports = function(crowi) {
     });
   };
 
-  // 指定グループリストに対するすべてのグループ所属関係を取得
-  pageGroupRelationSchema.statics.findAllRelationForUserGroups = function (userGroups, callback) {
-    debug('findAllRelations is called', userGroups);
-    var PageGroupRelation = this;
-    var groupRelations = new Map();
-
-    return new Promise(function (resolve, reject) {
-      PageGroupRelation
-        .find({ relatedGroup: { $in: userGroups} })
-        .populate('targetPage')
-        .exec(function (err, pageGroupRelationData) {
-          if (err) {
-            return reject(err);
-          }
-          debug(pageGroupRelationData);
-          return resolve(pageGroupRelationData);
-        });
-    });
-  };
-
   // ページネーション利用の検索
   pageGroupRelationSchema.statics.findPageGroupRelationsWithPagination = function (userGroup, options, callback) {
 
@@ -89,17 +69,35 @@ module.exports = function(crowi) {
     });
   };
 
+  // ページとグループを元に関係性を取得
+  pageGroupRelationSchema.statics.checkIsExistsRelationForPageAndGroup = function (page, userGroup) {
+    var PageGroupRelation = this
+
+    return new Promise(function (resolve, reject) {
+      PageGroupRelation
+        .count({ targetPage: page.id, relatedGroup: userGroup.id })
+        .exec(function (err, count) {
+          if (err) {
+            return reject(err);
+          }
+          return resolve(0 < count);
+        });
+    });
+  };
+
   // ページを元に関係性を取得
   pageGroupRelationSchema.statics.findByPage = function(page) {
     var PageGroupRelation = this
 
-    PageGroupRelation
-      .findOne({ targetPage: page})
-      .exec(function (err, data) {
-        if (err) {
-          return reject(err);
-        }
-        return resolve(data);
+    return new Promise(function (resolve, reject) {
+      PageGroupRelation
+        .findOne({ targetPage: page.id })
+        .exec(function (err, data) {
+          if (err) {
+            return reject(err);
+          }
+          return resolve(data);
+      });
     });
   };
 
@@ -111,8 +109,9 @@ module.exports = function(crowi) {
     if (userGroup == null || page == null) {
       return callback(new Error('userGroup or page is null'));
     }
-    newPageGroupRelation.relatedGroup = userGroup;
-    newPageGroupRelation.targetPage = page;
+    debug('create new page-group-relation for group ', userGroup);
+    newPageGroupRelation.relatedGroup = userGroup.id;
+    newPageGroupRelation.targetPage = page.id;
     newPageGroupRelation.createdAt = Date.now();
 
     debug('create new page-group-relation ', newPageGroupRelation);
@@ -137,6 +136,24 @@ module.exports = function(crowi) {
     return callback(null);
   }
 
+  // ページに紐づく関係性の全削除
+  pageGroupRelationSchema.statics.removeAllByPage = function (page, callback) {
+
+    if (page === null) { return callback(null); }
+    var PageGroupRelation = this
+    var relations = PageGroupRelation.findByPage(page);
+
+    if (relations != null && relations.length > 0) {
+      // 関係性削除の実装
+      relations.array.forEach(relation => {
+        PageGroupRelation.removeById(relation.id, function (err) {
+          if (err) { return callback(err); }
+        });
+      });
+    }
+    return callback(null);
+  }
+
   // ページに紐づくグループの関係性の削除
   pageGroupRelationSchema.statics.removeRelationByUserGroupAndPage = function (userGroup, page, callback) {
     if (userGroup == null) { return callback(null); }

+ 59 - 44
lib/models/page.js

@@ -459,7 +459,18 @@ module.exports = function(crowi) {
       Page.findPageById(id)
       .then(function(pageData) {
         if (userData && !pageData.isGrantedFor(userData)) {
-          return reject(new Error('Page is not granted for the user')); //PAGE_GRANT_ERROR, null);
+          Page.isExistsGrantedGroupFor(pageData, userData)
+          .then(function (checkResult) {
+            debug('isExistsGrantedGroupFor checkResult is ', checkResult);
+            if (!checkResult) {
+              return reject(new Error('Page is not granted for the user')); //PAGE_GRANT_ERROR, null);
+            } else {
+              return resolve(pageData);
+            }
+          })
+          .catch(function(err) {
+            return reject(err);
+          });
         }
 
         return resolve(pageData);
@@ -489,8 +500,19 @@ module.exports = function(crowi) {
           return reject(pageNotFoundError);
         }
 
-        if (!pageData.isGrantedFor(userData) && !self.isExistsGrantedGroupFor(pageData, userData)) {
-          return reject(new Error('Page is not granted for the user')); //PAGE_GRANT_ERROR, null);
+        if (!pageData.isGrantedFor(userData)) {
+          self.isExistsGrantedGroupFor(pageData, userData)
+            .then(function (checkResult) {
+              debug('isExistsGrantedGroupFor checkResult is ', checkResult);
+              if (!checkResult) {
+                return reject(new Error('Page is not granted for the user')); //PAGE_GRANT_ERROR, null);
+              } else {
+                return resolve(pageData);
+              }
+            })
+            .catch(function (err) {
+              return reject(err);
+            });
         }
 
         self.populatePageData(pageData, revisionId || null).then(resolve).catch(reject);
@@ -758,12 +780,13 @@ module.exports = function(crowi) {
     });
   };
 
-  pageSchema.statics.updateGrant = function (page, grant, userData, grantUserGroup) {
+  pageSchema.statics.updateGrant = function (page, grant, userData, grantUserGroupId) {
     var Page = this;
     var PageGroupRelation = crowi.model('PageGroupRelation');
+    var UserGroupRelation = crowi.model('UserGroupRelation');
     var provGrant = page.grant;
 
-    if (grant == GRANT_USER_GROUP && grantUserGroup == null) {
+    if (grant == GRANT_USER_GROUP && grantUserGroupId == null) {
       grant = GRANT_PUBLIC;
     }
     return new Promise(function(resolve, reject) {
@@ -781,18 +804,30 @@ module.exports = function(crowi) {
           return reject(err);
         }
 
-        // グループから外れたとき、関係性を削除
-        if (provGrant == GRANT_USER_GROUP && provGrant != grant) {
-          PageGroupRelation.removeRelationByUserGroupAndPage(grantUserGroup, page, function (err, result) {
-            if (err) {
-              return reject(err);
+        // グループの場合
+        if (grant == GRANT_USER_GROUP) {
+          debug('grant is usergroup', grantUserGroupId);
+          UserGroupRelation.findByGroupIdAndUser(grantUserGroupId, userData)
+          .then(function(relation) {
+            if (relation != null) {
+              return PageGroupRelation.checkIsExistsRelationForPageAndGroup(page, relation.relatedGroup);
             }
+            else { return reject(new Error('No UserGroup is exists. userGroupId : ', grantUserGroupId)); }
+          })
+          .then(function(isAlreadyExists) {
+            if (!isAlreadyExists) {
+              debug('create new Page and Group relations', relation.relatedGroup);
+              PageGroupRelation.createRelation(relation.relatedGroup, page, function (err, relationData) {
+                if (err) {
+                  return reject(err);
+                }
+              });
+            }
+            return Promise.resolve();
           });
         }
-
-        // グループに紐づけられたとき、関係性を生成
-        if (provGrant != GRANT_USER_GROUP && grant == GRANT_USER_GROUP) {
-          PageGroupRelation.createRelation(userGroupData, page, function (err, relationData) {
+        else {
+          PageGroupRelation.removeAllByPage(page, function (err, result) {
             if (err) {
               return reject(err);
             }
@@ -803,30 +838,6 @@ module.exports = function(crowi) {
     });
   };
 
-  pageSchema.statics.updateGrantUserGroup = function(page, userGroupData) {
-    var Page = this
-      , PageGroupRelation = crowi.model('PageGroupRelation');
-
-    return new Promise(function (resolve, reject) {
-      page.grant = GRANT_USER_GROUP;
-
-      page.save(function (err, data) {
-        debug('Page.updateGrant, saved grantedUsers.', err, data);
-        if (err) {
-          return reject(err);
-        }
-
-        PageGroupRelation.createRelation(userGroupData, page, function(err, relationData) {
-          debug('Page.updateGrant, saved grantedUsers.', err, relationData);
-          if (err) {
-            return reject(err);
-          }
-        });
-        return resolve(relationData);
-      });
-    });
-  }
-
   // Instance method でいいのでは
   pageSchema.statics.pushToGrantedUsers = function(page, userData) {
 
@@ -884,7 +895,7 @@ module.exports = function(crowi) {
       , format = options.format || 'markdown'
       , grant = options.grant || GRANT_PUBLIC
       , redirectTo = options.redirectTo || null
-      , grantUserGroup = options.grantUserGroup || null;
+      , grantUserGroupId = options.grantUserGroupId || null;
 
     // force public
       if (isPortalPath(path)) {
@@ -914,8 +925,8 @@ module.exports = function(crowi) {
               return reject(err);
             }
 
-            if (newPage.grant == Page.GRANT_USER_GROUP && grantUserGroup != null) {
-              UserGroupRelation.createRelation(grantUserGroup, newPage, function (err, relationData) {
+            if (newPage.grant == Page.GRANT_USER_GROUP && grantUserGroupId != null) {
+              PageGroupRelation.createRelation(grantUserGroupId, newPage, function (err, relationData) {
                 if (err) {
                   return reject(err);
                 }
@@ -938,7 +949,7 @@ module.exports = function(crowi) {
     var Page = this
       , Revision = crowi.model('Revision')
       , grant = options.grant || null
-      , grantUserGroup = options.grantUserGroup || null;
+      , grantUserGroupId = options.grantUserGroupId || null
       ;
     // update existing page
     var newRevision = Revision.prepareRevision(pageData, body, user);
@@ -947,7 +958,7 @@ module.exports = function(crowi) {
       Page.pushRevision(pageData, newRevision, user)
       .then(function(revision) {
         if (grant != pageData.grant) {
-          return Page.updateGrant(pageData, grant, user, grantUserGroup).then(function(data) {
+          return Page.updateGrant(pageData, grant, user, grantUserGroupId).then(function(data) {
             debug('Page grant update:', data);
             resolve(data);
             pageEvent.emit('update', data, user);
@@ -1227,7 +1238,11 @@ module.exports = function(crowi) {
     return new Promise(function (resolve, reject) {
       PageGroupRelation.findByPage(pageData)
       .then(function (pageRelation) {
-        UserGroupRelation.checkIsRelatedUserForGroup(userData, data.relatedGroup)
+        if (pageRelation == null) {
+          debug('isExistsGrantedGroupFor is return resolve(false);');
+          return resolve(false);
+        }
+        return UserGroupRelation.checkIsRelatedUserForGroup(userData, pageRelation.relatedGroup)
         .then(function (checkResult) {
           return resolve(checkResult);
         })

+ 22 - 4
lib/models/user-group-relation.js

@@ -40,7 +40,7 @@ module.exports = function(crowi) {
 
   // 指定グループに対するすべてのグループ所属関係を取得
   userGroupRelationSchema.statics.findAllRelationForUserGroup = function (userGroup) {
-    debug('findAllRelation is called', userGroup);
+    debug('findAllRelationForUserGroup is called', userGroup);
     var UserGroupRelation = this;
 
     return new Promise(function (resolve, reject) {
@@ -56,6 +56,24 @@ module.exports = function(crowi) {
     });
   };
 
+  // 指定ユーザが所属するすべてのグループ所属関係を取得
+  userGroupRelationSchema.statics.findAllRelationForUser = function (user) {
+    debug('findAllRelationForUser is called');
+    var UserGroupRelation = this;
+
+    return new Promise(function (resolve, reject) {
+      UserGroupRelation
+        .find({ relatedUser: user.id })
+        .populate('relatedGroup')
+        .exec(function (err, userGroupRelationData) {
+          if (err) {
+            return reject(err);
+          }
+          return resolve(userGroupRelationData);
+        });
+    });
+  };
+
   // 指定グループリストに対するすべてのグループ所属関係を取得
   userGroupRelationSchema.statics.findAllRelationForUserGroups = function (userGroups, callback) {
     debug('findAllRelations is called', userGroups);
@@ -94,12 +112,12 @@ module.exports = function(crowi) {
     var UserGroupRelation = this;
 
     return new Promise(function (resolve, reject) {
-      UserGroupRelation.count( {relatedGroup: userGroup, relatedUser: userData}, function (err, count) {
+      UserGroupRelation.count( {relatedGroup: userGroup.id, relatedUser: userData.id}, function (err, count) {
       if (err) {
         return reject(err);
       }
-      // isRelated == (1 < count)
-      return resolve((1 < count));
+      debug('checkIsRelatedUserForGroup count : ', count);
+      return resolve((0 < count));
       });
     });
   };

+ 18 - 8
lib/routes/page.js

@@ -8,6 +8,7 @@ module.exports = function(crowi, app) {
     , config   = crowi.getConfig()
     , Revision = crowi.model('Revision')
     , Bookmark = crowi.model('Bookmark')
+    , UserGroupRelation = crowi.model('UserGroupRelation')
     , ApiResponse = require('../util/apiResponse')
     , interceptorManager = crowi.getInterceptorManager()
 
@@ -230,6 +231,7 @@ module.exports = function(crowi, app) {
       author: false,
       pages: [],
       tree: [],
+      relatedUserGroups: [],
     };
 
     var pageTeamplate = 'customlayout-selector/page';
@@ -330,6 +332,14 @@ module.exports = function(crowi, app) {
           debug('Error on rendering pageListShowForCrowiPlus', err);
         });
       }
+    })
+    .then(function() {
+      return UserGroupRelation.findAllRelationForUser(req.user);
+    }).then(function (groupRelations) {
+      debug('findPage : relatedGroups ', groupRelations);
+      renderVars.relatedUserGroups = groupRelations;
+
+      return Promise.resolve();
     });
   }
 
@@ -547,7 +557,7 @@ module.exports = function(crowi, app) {
     var currentRevision = pageForm.currentRevision;
     var grant = pageForm.grant;
     var path = pageForm.path;
-    var grantUserGroup = pageForm.grantUserGroup
+    var grantUserGroupId = pageForm.grantUserGroupId
 
     // TODO: make it pluggable
     var notify = pageForm.notify || {};
@@ -586,11 +596,11 @@ module.exports = function(crowi, app) {
 
       if (data) {
         previousRevision = data.revision;
-        return Page.updatePage(data, body, req.user, { grant: grant, grantUserGroup: grantUserGroup});
+        return Page.updatePage(data, body, req.user, { grant: grant, grantUserGroupId: grantUserGroupId});
       } else {
         // new page
         updateOrCreate = 'create';
-        return Page.create(path, body, req.user, { grant: grant, grantUserGroup: grantUserGroup});
+        return Page.create(path, body, req.user, { grant: grant, grantUserGroupId: grantUserGroupId});
       }
     }).then(function(data) {
       // data is a saved page data.
@@ -788,7 +798,7 @@ module.exports = function(crowi, app) {
     var body = req.body.body || null;
     var pagePath = req.body.path || null;
     var grant = req.body.grant || null;
-    var grantUserGroup = req.body.grantUserGroup || null;
+    var grantUserGroupId = req.body.grantUserGroupId || null;
 
     if (body === null || pagePath === null) {
       return res.json(ApiResponse.error('Parameters body and path are required.'));
@@ -801,7 +811,7 @@ module.exports = function(crowi, app) {
         throw new Error('Page exists');
       }
 
-      return Page.create(pagePath, body, req.user, { grant: grant, grantUserGroup: grantUserGroup});
+      return Page.create(pagePath, body, req.user, { grant: grant, grantUserGroupId: grantUserGroupId});
     }).then(function(data) {
       if (!data) {
         throw new Error('Failed to create page.');
@@ -836,7 +846,7 @@ module.exports = function(crowi, app) {
     var pageId = req.body.page_id || null;
     var revisionId = req.body.revision_id || null;
     var grant = req.body.grant || null;
-    var grantUserGroup = req.body.grantUserGroup || null;
+    var grantUserGroupId = req.body.grantUserGroupId || null;
 
     if (pageId === null || pageBody === null) {
       return res.json(ApiResponse.error('page_id and body are required.'));
@@ -852,8 +862,8 @@ module.exports = function(crowi, app) {
       if (grant !== null) {
         grantOption.grant = grant;
       }
-      if (grantUserGroup != null) {
-        grantOption.grantUserGroup = grantUserGroup;
+      if (grantUserGroupId != null) {
+        grantOption.grantUserGroupId = grantUserGroupId;
       }
       return Page.updatePage(pageData, pageBody, req.user, grantOption);
     }).then(function(pageData) {

+ 6 - 4
lib/views/_form.html

@@ -50,15 +50,17 @@
         {% else %}
         <select name="pageForm[grant]" class="form-control">
           {% for grantId, grantLabel in consts.pageGrants %}
-          <option value="{{ grantId }}" {% if pageForm.grant|default(page.grant) == grantId %}selected{% endif %}>{{ t(grantLabel) }}</option>
+          <option value="{{ grantId }}" {% if pageForm.grant|default(page.grant) == grantId %}selected{% endif %} {% if grantId == 5 && relatedUserGroups.length == 0 %}disabled{% endif %}>{{ t(grantLabel) }}</option>
           {% endfor %}
         </select>
         {% endif %}
-        <select name="pageForm[grantUserGroup]" class="form-control">
-          {% for userGroup in relatedUserGroups %}
-          <option value="{{ userGroup }}"></option>
+        {% if relatedUserGroups.length != 0 %}
+        <select name="pageForm[grantUserGroupId]" class="form-control">
+          {% for userGroupRelation in relatedUserGroups %}
+          <option value="{{ userGroupRelation.relatedGroup.id }}">{{ userGroupRelation.relatedGroup.name }}</option>
           {% endfor %}
         </select>
+        {% endif %}
         <input type="hidden" id="edit-form-csrf" name="_csrf" value="{{ csrf() }}">
         <input type="submit" class="btn btn-primary" id="edit-form-submit" value="{{ t('Update Page') }}" />
       </div>