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

# Feature/196, 198, 199 Grouping users
* Fix user-group-relation management page.
** User-group related page list viewable.
* Prepare page-group-relation model methods.
** Prepare create page-group-relation method.
** Prepare remove page-group-relation with group and page method.

Tatsuya Ise 8 лет назад
Родитель
Сommit
f43eeb3a46

+ 1 - 0
lib/locales/en-US/translation.json

@@ -76,6 +76,7 @@
   "Anyone with the link": "Anyone with the link",
   "Specified users only": "Specified users only",
   "Just me": "Just me",
+  "Only inside the group": "Only inside the group",
   "Shareable link": "Shareable link",
 
   "Show latest": "Show latest",

+ 1 - 0
lib/locales/ja/translation.json

@@ -75,6 +75,7 @@
   "Anyone with the link": "リンクを知っている人のみ",
   "Specified users": "特定ユーザーのみ",
   "Just me": "自分のみ",
+  "Only inside the group": "特定グループのみ",
   "Shareable link": "このページの共有用URL",
 
   "Show latest": "最新のページを表示",

+ 20 - 6
lib/models/page-group-relation.js

@@ -90,18 +90,18 @@ module.exports = function(crowi) {
   };
 
   // 関係性の生成
-  pageGroupRelationSchema.statics.createRelation = function(userGroup, user, callback) {
+  pageGroupRelationSchema.statics.createRelation = function(userGroup, page, callback) {
     var PageGroupRelation = this
       , newPageGroupRelation = new PageGroupRelation();
 
-    if (userGroup == null || user == null) {
-      return callback(new Error('userGroup or user is null'));
+    if (userGroup == null || page == null) {
+      return callback(new Error('userGroup or page is null'));
     }
     newPageGroupRelation.relatedGroup = userGroup;
-    newPageGroupRelation.targetPage = user;
+    newPageGroupRelation.targetPage = page;
     newPageGroupRelation.createdAt = Date.now();
 
-    debug('create new user-group-relation ', newPageGroupRelation);
+    debug('create new page-group-relation ', newPageGroupRelation);
     newPageGroupRelation.save(function(err, pageGroupRelationData) {
       return callback(err, pageGroupRelationData);
     });
@@ -110,7 +110,7 @@ module.exports = function(crowi) {
   // グループに紐づく関係性の全削除
   pageGroupRelationSchema.statics.removeAllByUserGroup = function (userGroup, callback) {
 
-    if (userGroup === null || userGroup === undefined) { return callback(null); }
+    if (userGroup === null) { return callback(null); }
     var PageGroupRelation = this
     var relations = PageGroupRelation.findAllRelation(userGroup);
 
@@ -123,6 +123,20 @@ module.exports = function(crowi) {
     return callback(null);
   }
 
+  // ページに紐づくグループの関係性の削除
+  pageGroupRelationSchema.statics.removeRelationByUserGroupAndPage = function (userGroup, page, callback) {
+    if (userGroup == null) { return callback(null); }
+    if (page == null) { return callback(null); }
+    var PageGroupRelation = this
+    var relation = PageGroupRelation.findOne()({relatedGroup: userGroup.id, targetPage: page.id });
+
+    if (relation == null) { return callback(); }
+    PageGroupRelation.removeById(relation.id, function (err) {
+      if (err) { return callback(err); }
+    });
+    return callback(null);
+  }
+
   // ユーザグループの関係性を削除
   pageGroupRelationSchema.statics.removeById = function (id, callback) {
     var PageGroupRelation = this

+ 58 - 4
lib/models/page.js

@@ -758,12 +758,17 @@ module.exports = function(crowi) {
     });
   };
 
-  pageSchema.statics.updateGrant = function(page, grant, userData) {
+  pageSchema.statics.updateGrant = function (page, grant, userData, grantUserGroup) {
     var Page = this;
+    var PageGroupRelation = crowi.model('PageGroupRelation');
+    var provGrant = page.grant;
 
+    if (grant == GRANT_USER_GROUP && grantUserGroup == null) {
+      grant = GRANT_PUBLIC;
+    }
     return new Promise(function(resolve, reject) {
       page.grant = grant;
-      if (grant == GRANT_PUBLIC) {
+      if (grant == GRANT_PUBLIC || grant == GRANT_USER_GROUP) {
         page.grantedUsers = [];
       } else {
         page.grantedUsers = [];
@@ -776,11 +781,51 @@ 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 (provGrant != GRANT_USER_GROUP && grant == GRANT_USER_GROUP) {
+          UserGroupRelation.createRelation(userGroupData, page, function (err, relationData) {
+            if (err) {
+              return reject(err);
+            }
+          });
+        }
         return resolve(data);
       });
     });
   };
 
+  pageSchema.statics.updateGrantUserGroup = function(page, userGroupData) {
+    var Page = this
+      , UserGroupRelation = crowi.model('UserGroupRelation');
+
+    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);
+        }
+
+        UserGroupRelation.createRelation(userGroupData, page, function(err, relationData) {
+          if (err) {
+            return reject(err);
+          }
+        });
+        return resolve(data);
+      });
+    });
+  }
+
   // Instance method でいいのでは
   pageSchema.statics.pushToGrantedUsers = function(page, userData) {
 
@@ -837,7 +882,8 @@ module.exports = function(crowi) {
       , Revision = crowi.model('Revision')
       , format = options.format || 'markdown'
       , grant = options.grant || GRANT_PUBLIC
-      , redirectTo = options.redirectTo || null;
+      , redirectTo = options.redirectTo || null
+      , grantUserGroup = options.grantUserGroup || null;
 
     // force public
       if (isPortalPath(path)) {
@@ -867,6 +913,13 @@ module.exports = function(crowi) {
               return reject(err);
             }
 
+            if (newPage.grant == Page.GRANT_USER_GROUP && grantUserGroup != null) {
+              UserGroupRelation.createRelation(grantUserGroup, newPage, function (err, relationData) {
+                if (err) {
+                  return reject(err);
+                }
+              });
+            }
             var newRevision = Revision.prepareRevision(newPage, body, user, {format: format});
             Page.pushRevision(newPage, newRevision, user).then(function(data) {
               resolve(data);
@@ -884,6 +937,7 @@ module.exports = function(crowi) {
     var Page = this
       , Revision = crowi.model('Revision')
       , grant = options.grant || null
+      , grantUserGroup = options.grantUserGroup || null;
       ;
     // update existing page
     var newRevision = Revision.prepareRevision(pageData, body, user);
@@ -892,7 +946,7 @@ module.exports = function(crowi) {
       Page.pushRevision(pageData, newRevision, user)
       .then(function(revision) {
         if (grant != pageData.grant) {
-          return Page.updateGrant(pageData, grant, user).then(function(data) {
+          return Page.updateGrant(pageData, grant, user, grantUserGroup).then(function(data) {
             debug('Page grant update:', data);
             resolve(data);
             pageEvent.emit('update', data, user);

+ 29 - 18
lib/routes/admin.js

@@ -506,14 +506,29 @@ module.exports = function(crowi, app) {
   // グループ詳細
   actions.userGroup.detail = function (req, res) {
     var name = req.params.name;
+    var renderVar = {
+      userGroup: null,
+      userGroupRelations: [],
+      pageGroupRelations: [],
+      notRelatedusers: []
+    }
     UserGroup.findUserGroupByName(name)
       .then(function (userGroup) {
-        var groupRelations = [];
-        if (userGroup) {
+        if (userGroup == null) {
+          req.flash('errorMessage', 'ユーザグループの検索に失敗しました');
+          debug('Error on get userGroupDetail', err);
+          return res.redirect('/admin/user-groups');
+        } else {
+          renderVar.userGroup = userGroup;
+
           UserGroupRelation.findAllRelationForUserGroup(userGroup)
           .then(function (relations) {
+            renderVar.userGroupRelations = relations;
+
             PageGroupRelation.findAllRelationForUserGroup(userGroup)
             .then(function (pageRelations) {
+              renderVar.pageGroupRelations = pageRelations;
+
               User.findAllUsers(null)
                 .then(function (users) {
                   debug('users', users);
@@ -521,39 +536,35 @@ module.exports = function(crowi, app) {
                     var relation = relations.find( function(relation) {
                       return relation.relatedUser._id.toString() == user._id.toString();
                     });
-                    return relation == null || relation == undefined;
+                    return relation == null;
                   });
                   debug('users', users);
                   debug('user-group-detail succeed', relations);
-                  return res.render('admin/user-group-detail', {
-                    userGroup: userGroup,
-                    userGroupRelations: relations,
-                    pageGroupRelations: pageRelations,
-                    notRelatedusers: users
-                  });
+                  renderVar.notRelatedusers = users;
+                  return res.render('admin/user-group-detail', renderVar);
                 })
                 .catch(function(err) {
-                  debug('Error on find all relations', err);
-                  return res.json(ApiResponse.error('Error'));
+                  req.flash('errorMessage', 'ユーザの検索に失敗しました');
+                  debug('Error on find all unrelated users', err);
+                  return res.redirect('/admin/user-groups');
                 });
             })
             .catch(function (err) {
+              req.flash('errorMessage', 'グループ関連ページの検索に失敗しました');
               debug('Error on find all relations', err);
-              return res.json(ApiResponse.error('Error'));
+              return res.redirect('/admin/user-groups');
             });
           }).catch(function (err) {
+            req.flash('errorMessage', 'グループ関連ユーザの検索に失敗しました');
             debug('Error on find all relations', err);
-            return res.json(ApiResponse.error('Error'));
+            return res.redirect('/admin/user-groups');
           });
         }
-        else {
-          debug('Error on get userGroupDetail', err);
-          return res.json(ApiResponse.error('Error'));
-        }
       })
       .catch(function(err) {
+        req.flash('errorMessage', 'ユーザグループの検索に失敗しました');
         debug('Error on get userGroupDetail', err);
-        return res.json(ApiResponse.error('Error'));
+        return res.redirect('/admin/user-groups');
       });
   }
 

+ 9 - 3
lib/routes/page.js

@@ -547,6 +547,7 @@ module.exports = function(crowi, app) {
     var currentRevision = pageForm.currentRevision;
     var grant = pageForm.grant;
     var path = pageForm.path;
+    var grantUserGroup = pageForm.grantUserGroup
 
     // TODO: make it pluggable
     var notify = pageForm.notify || {};
@@ -585,11 +586,11 @@ module.exports = function(crowi, app) {
 
       if (data) {
         previousRevision = data.revision;
-        return Page.updatePage(data, body, req.user, {grant: grant});
+        return Page.updatePage(data, body, req.user, { grant: grant, grantUserGroup: grantUserGroup});
       } else {
         // new page
         updateOrCreate = 'create';
-        return Page.create(path, body, req.user, {grant: grant});
+        return Page.create(path, body, req.user, { grant: grant, grantUserGroup: grantUserGroup});
       }
     }).then(function(data) {
       // data is a saved page data.
@@ -787,6 +788,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;
 
     if (body === null || pagePath === null) {
       return res.json(ApiResponse.error('Parameters body and path are required.'));
@@ -799,7 +801,7 @@ module.exports = function(crowi, app) {
         throw new Error('Page exists');
       }
 
-      return Page.create(pagePath, body, req.user, {grant: grant});
+      return Page.create(pagePath, body, req.user, { grant: grant, grantUserGroup: grantUserGroup});
     }).then(function(data) {
       if (!data) {
         throw new Error('Failed to create page.');
@@ -834,6 +836,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;
 
     if (pageId === null || pageBody === null) {
       return res.json(ApiResponse.error('page_id and body are required.'));
@@ -849,6 +852,9 @@ module.exports = function(crowi, app) {
       if (grant !== null) {
         grantOption.grant = grant;
       }
+      if (grantUserGroup != null) {
+        grantOption.grantUserGroup = grantUserGroup;
+      }
       return Page.updatePage(pageData, pageBody, req.user, grantOption);
     }).then(function(pageData) {
       var result = {

+ 5 - 0
lib/views/admin/user-group-detail.html

@@ -226,6 +226,11 @@
 
       <!-- {% include '../widget/pager.html' with {path: "/admin/user-group-detail", pager: pager} %} -->
 
+      <legend>ページ一覧</legend>
+
+      {% if pageGroupRelations.length == 0 %}<p>グループが閲覧権限を保有するページはありません</p>{% endif %}
+      {% include '../widget/page_list.html' with { pages: pageGroupRelations, pagePropertyName: 'targetPage' } %}
+
     </div>
   </div>
 </div>