page-grant.test.ts 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964
  1. import { GroupType, PageGrant } from '@growi/core';
  2. import mongoose from 'mongoose';
  3. import { ExternalGroupProviderType } from '../../../src/features/external-user-group/interfaces/external-user-group';
  4. import ExternalUserGroup from '../../../src/features/external-user-group/server/models/external-user-group';
  5. import ExternalUserGroupRelation from '../../../src/features/external-user-group/server/models/external-user-group-relation';
  6. import { UserGroupPageGrantStatus } from '../../../src/interfaces/page';
  7. import UserGroup from '../../../src/server/models/user-group';
  8. import UserGroupRelation from '../../../src/server/models/user-group-relation';
  9. import type { IPageGrantService } from '../../../src/server/service/page-grant';
  10. import { getInstance } from '../setup-crowi';
  11. /*
  12. * There are 3 grant types to test.
  13. * GRANT_PUBLIC, GRANT_OWNER, GRANT_USER_GROUP
  14. */
  15. describe('PageGrantService', () => {
  16. /*
  17. * models
  18. */
  19. let User;
  20. let Page;
  21. /*
  22. * global instances
  23. */
  24. let crowi;
  25. let pageGrantService: IPageGrantService;
  26. let user1;
  27. let user2;
  28. let groupParent;
  29. let groupChild;
  30. let differentTreeGroup;
  31. let externalGroupParent;
  32. let externalGroupChild;
  33. const userGroupIdParent = new mongoose.Types.ObjectId();
  34. const externalUserGroupIdParent = new mongoose.Types.ObjectId();
  35. let rootPage;
  36. let rootPublicPage;
  37. let rootOnlyMePage;
  38. let rootOnlyInsideTheGroup;
  39. let emptyPage1;
  40. let emptyPage2;
  41. let emptyPage3;
  42. const emptyPagePath1 = '/E1';
  43. const emptyPagePath2 = '/E2';
  44. const emptyPagePath3 = '/E3';
  45. let multipleGroupTreesAndUsersPage;
  46. let pageRootPublic;
  47. let pageRootGroupParent;
  48. const pageRootPublicPath = '/Public';
  49. const pageRootGroupParentPath = '/GroupParent';
  50. const pageMultipleGroupTreesAndUsersPath = '/MultipleGroupTreesAndUsers';
  51. const v4PageRootOnlyMePagePath = '/v4OnlyMe';
  52. const v4PageRootAnyoneWithTheLinkPagePath = '/v4AnyoneWithTheLink';
  53. const v4PageRootOnlyInsideTheGroupPagePath = '/v4OnlyInsideTheGroup';
  54. const pagePublicOnlyMePath = `${pageRootPublicPath}/OnlyMe`;
  55. const pagePublicAnyoneWithTheLinkPath = `${pageRootPublicPath}/AnyoneWithTheLink`;
  56. const pagePublicOnlyInsideTheGroupPath = `${pageRootPublicPath}/OnlyInsideTheGroup`;
  57. const pageOnlyMePublicPath = `${v4PageRootOnlyMePagePath}/Public`;
  58. const pageOnlyMeAnyoneWithTheLinkPath = `${v4PageRootOnlyMePagePath}/AnyoneWithTheLink`;
  59. const pageOnlyMeOnlyInsideTheGroupPath = `${v4PageRootOnlyMePagePath}/OnlyInsideTheGroup`;
  60. const pageOnlyInsideTheGroupPublicPath = `${v4PageRootOnlyInsideTheGroupPagePath}/Public`;
  61. const pageOnlyInsideTheGroupOnlyMePath = `${v4PageRootOnlyInsideTheGroupPagePath}/OnlyMe`;
  62. const pageOnlyInsideTheGroupAnyoneWithTheLinkPath = `${v4PageRootOnlyInsideTheGroupPagePath}/AnyoneWithTheLink`;
  63. let pageE1Public;
  64. let pageE2User1;
  65. let pageE3GroupParent;
  66. let pageE3GroupChild;
  67. let pageE3User1;
  68. const pageE1PublicPath = '/E1/Public';
  69. const pageE2User1Path = '/E2/User1';
  70. const pageE3GroupParentPath = '/E3/GroupParent';
  71. const pageE3GroupChildPath = '/E3/GroupChild';
  72. const pageE3User1Path = '/E3/User1';
  73. // getPageGroupGrantData test data
  74. let user3;
  75. let groupGrantDataTestChildPagePath;
  76. let groupGrantDataTestParentUserGroupId;
  77. let groupGrantDataTestChildUserGroupId;
  78. let groupGrantDataTestExternalUserGroupId;
  79. let groupGrantDataTestExternalUserGroupId2;
  80. const createDocumentsToTestIsGrantNormalized = async() => {
  81. // Users
  82. await User.insertMany([
  83. { name: 'User1', username: 'User1', email: 'user1@example.com' },
  84. { name: 'User2', username: 'User2', email: 'user2@example.com' },
  85. ]);
  86. user1 = await User.findOne({ username: 'User1' });
  87. user2 = await User.findOne({ username: 'User2' });
  88. await UserGroup.insertMany([
  89. {
  90. _id: userGroupIdParent,
  91. name: 'GroupParent',
  92. parent: null,
  93. },
  94. {
  95. name: 'GroupChild',
  96. parent: userGroupIdParent,
  97. },
  98. {
  99. name: 'DifferentTreeGroup',
  100. parent: null,
  101. },
  102. ]);
  103. groupParent = await UserGroup.findOne({ name: 'GroupParent' });
  104. groupChild = await UserGroup.findOne({ name: 'GroupChild' });
  105. differentTreeGroup = await UserGroup.findOne({ name: 'DifferentTreeGroup' });
  106. // UserGroupRelations
  107. await UserGroupRelation.insertMany([
  108. {
  109. relatedGroup: groupParent._id,
  110. relatedUser: user1._id,
  111. },
  112. {
  113. relatedGroup: groupParent._id,
  114. relatedUser: user2._id,
  115. },
  116. {
  117. relatedGroup: groupChild._id,
  118. relatedUser: user1._id,
  119. },
  120. {
  121. relatedGroup: differentTreeGroup._id,
  122. relatedUser: user1._id,
  123. },
  124. ]);
  125. await ExternalUserGroup.insertMany([
  126. {
  127. _id: externalUserGroupIdParent,
  128. name: 'ExternalGroupParent',
  129. externalId: 'ExternalGroupParent',
  130. provider: ExternalGroupProviderType.ldap,
  131. parent: null,
  132. },
  133. {
  134. name: 'ExternalGroupChild',
  135. externalId: 'ExternalGroupChild',
  136. provider: ExternalGroupProviderType.ldap,
  137. parent: externalUserGroupIdParent,
  138. },
  139. ]);
  140. externalGroupParent = await ExternalUserGroup.findOne({ name: 'ExternalGroupParent' });
  141. externalGroupChild = await ExternalUserGroup.findOne({ name: 'ExternalGroupChild' });
  142. await ExternalUserGroupRelation.insertMany([
  143. {
  144. relatedGroup: externalGroupParent._id,
  145. relatedUser: user1._id,
  146. },
  147. {
  148. relatedGroup: externalGroupParent._id,
  149. relatedUser: user2._id,
  150. },
  151. {
  152. relatedGroup: externalGroupChild._id,
  153. relatedUser: user1._id,
  154. },
  155. ]);
  156. // Root page (Depth: 0)
  157. rootPage = await Page.findOne({ path: '/' });
  158. // Empty pages (Depth: 1)
  159. await Page.insertMany([
  160. {
  161. path: emptyPagePath1,
  162. grant: Page.GRANT_PUBLIC,
  163. isEmpty: true,
  164. parent: rootPage._id,
  165. },
  166. {
  167. path: emptyPagePath2,
  168. grant: Page.GRANT_PUBLIC,
  169. isEmpty: true,
  170. parent: rootPage._id,
  171. },
  172. {
  173. path: emptyPagePath3,
  174. grant: Page.GRANT_PUBLIC,
  175. isEmpty: true,
  176. parent: rootPage._id,
  177. },
  178. {
  179. path: pageRootPublicPath,
  180. grant: Page.GRANT_PUBLIC,
  181. creator: user1,
  182. lastUpdateUser: user1,
  183. grantedUsers: null,
  184. grantedGroups: [],
  185. parent: rootPage._id,
  186. },
  187. {
  188. path: pageRootGroupParentPath,
  189. grant: Page.GRANT_USER_GROUP,
  190. creator: user1,
  191. lastUpdateUser: user1,
  192. grantedUsers: null,
  193. grantedGroups: [{ item: groupParent._id, type: GroupType.userGroup }, { item: externalGroupParent._id, type: GroupType.externalUserGroup }],
  194. parent: rootPage._id,
  195. },
  196. {
  197. path: pageMultipleGroupTreesAndUsersPath,
  198. grant: Page.GRANT_USER_GROUP,
  199. creator: user1,
  200. lastUpdateUser: user1,
  201. grantedUsers: null,
  202. grantedGroups: [{ item: groupParent._id, type: GroupType.userGroup }, { item: differentTreeGroup._id, type: GroupType.userGroup }],
  203. parent: null,
  204. },
  205. ]);
  206. multipleGroupTreesAndUsersPage = await Page.findOne({ path: pageMultipleGroupTreesAndUsersPath });
  207. await Page.insertMany([
  208. // Root Page
  209. {
  210. path: rootPage,
  211. grant: Page.GRANT_PUBLIC,
  212. parent: null,
  213. },
  214. // OnlyMe v4
  215. {
  216. path: v4PageRootOnlyMePagePath,
  217. grant: Page.GRANT_OWNER,
  218. grantedUsers: [user1._id],
  219. parent: null,
  220. },
  221. // AnyoneWithTheLink v4
  222. {
  223. path: v4PageRootAnyoneWithTheLinkPagePath,
  224. grant: Page.GRANT_RESTRICTED,
  225. parent: null,
  226. },
  227. // OnlyInsideTheGroup v4
  228. {
  229. path: v4PageRootOnlyInsideTheGroupPagePath,
  230. grant: Page.GRANT_USER_GROUP,
  231. parent: null,
  232. grantedGroups: [{ item: groupParent._id, type: GroupType.userGroup }, { item: externalGroupParent._id, type: GroupType.externalUserGroup }],
  233. },
  234. ]);
  235. rootPublicPage = await Page.findOne({ path: pageRootPublicPath });
  236. rootOnlyMePage = await Page.findOne({ path: v4PageRootOnlyMePagePath });
  237. rootOnlyInsideTheGroup = await Page.findOne({ path: v4PageRootOnlyInsideTheGroupPagePath });
  238. // Leaf pages (Depth: 2)
  239. await Page.insertMany([
  240. /*
  241. * Parent is public
  242. */
  243. {
  244. path: pagePublicOnlyMePath,
  245. grant: Page.GRANT_OWNER,
  246. parent: rootPublicPage._id,
  247. },
  248. {
  249. path: pagePublicAnyoneWithTheLinkPath,
  250. grant: Page.GRANT_RESTRICTED,
  251. parent: rootPublicPage._id,
  252. },
  253. {
  254. path: pagePublicOnlyInsideTheGroupPath,
  255. grant: Page.GRANT_USER_GROUP,
  256. parent: rootPublicPage._id,
  257. },
  258. /*
  259. * Parent is onlyMe
  260. */
  261. {
  262. path: pageOnlyMePublicPath,
  263. grant: Page.GRANT_PUBLIC,
  264. parent: rootOnlyMePage._id,
  265. },
  266. {
  267. path: pageOnlyMeAnyoneWithTheLinkPath,
  268. grant: Page.GRANT_RESTRICTED,
  269. parent: rootOnlyMePage._id,
  270. },
  271. {
  272. path: pageOnlyMeOnlyInsideTheGroupPath,
  273. grant: Page.GRANT_USER_GROUP,
  274. parent: rootOnlyMePage._id,
  275. },
  276. /*
  277. * Parent is OnlyInsideTheGroup
  278. */
  279. {
  280. path: pageOnlyInsideTheGroupPublicPath,
  281. grant: Page.GRANT_PUBLIC,
  282. parent: rootOnlyInsideTheGroup._id,
  283. },
  284. {
  285. path: pageOnlyInsideTheGroupOnlyMePath,
  286. grant: Page.GRANT_PUBLIC,
  287. parent: rootOnlyInsideTheGroup._id,
  288. },
  289. {
  290. path: pageOnlyInsideTheGroupAnyoneWithTheLinkPath,
  291. grant: Page.GRANT_PUBLIC,
  292. parent: rootOnlyInsideTheGroup._id,
  293. },
  294. ]);
  295. emptyPage1 = await Page.findOne({ path: emptyPagePath1 });
  296. emptyPage2 = await Page.findOne({ path: emptyPagePath2 });
  297. emptyPage3 = await Page.findOne({ path: emptyPagePath3 });
  298. // Leaf pages (Depth: 2)
  299. await Page.insertMany([
  300. {
  301. path: pageE1PublicPath,
  302. grant: Page.GRANT_PUBLIC,
  303. creator: user1,
  304. lastUpdateUser: user1,
  305. grantedUsers: null,
  306. grantedGroups: [],
  307. parent: emptyPage1._id,
  308. },
  309. {
  310. path: pageE2User1Path,
  311. grant: Page.GRANT_OWNER,
  312. creator: user1,
  313. lastUpdateUser: user1,
  314. grantedUsers: [user1._id],
  315. grantedGroups: [],
  316. parent: emptyPage2._id,
  317. },
  318. {
  319. path: pageE3GroupParentPath,
  320. grant: Page.GRANT_USER_GROUP,
  321. creator: user1,
  322. lastUpdateUser: user1,
  323. grantedUsers: null,
  324. grantedGroups: [{ item: groupParent._id, type: GroupType.userGroup }, { item: externalGroupParent._id, type: GroupType.externalUserGroup }],
  325. parent: emptyPage3._id,
  326. },
  327. {
  328. path: pageE3GroupChildPath,
  329. grant: Page.GRANT_USER_GROUP,
  330. creator: user1,
  331. lastUpdateUser: user1,
  332. grantedUsers: null,
  333. grantedGroups: [{ item: groupChild._id, type: GroupType.userGroup }, { item: externalGroupChild._id, type: GroupType.externalUserGroup }],
  334. parent: emptyPage3._id,
  335. },
  336. {
  337. path: pageE3User1Path,
  338. grant: Page.GRANT_OWNER,
  339. creator: user1,
  340. lastUpdateUser: user1,
  341. grantedUsers: [user1._id],
  342. grantedGroups: [],
  343. parent: emptyPage3._id,
  344. },
  345. ]);
  346. pageE1Public = await Page.findOne({ path: pageE1PublicPath });
  347. pageE2User1 = await Page.findOne({ path: pageE2User1Path });
  348. pageE3GroupParent = await Page.findOne({ path: pageE3GroupParentPath });
  349. pageE3GroupChild = await Page.findOne({ path: pageE3GroupChildPath });
  350. pageE3User1 = await Page.findOne({ path: pageE3User1Path });
  351. };
  352. const createDocumentsToTestGetPageGroupGrantData = async() => {
  353. await User.insertMany([
  354. { name: 'User3', username: 'User3', email: 'user3@example.com' },
  355. ]);
  356. user3 = await User.findOne({ username: 'User3' });
  357. groupGrantDataTestParentUserGroupId = new mongoose.Types.ObjectId();
  358. groupGrantDataTestChildUserGroupId = new mongoose.Types.ObjectId();
  359. await UserGroup.insertMany([
  360. {
  361. _id: groupGrantDataTestParentUserGroupId, // cannotGrant
  362. name: 'groupGrantDataTestParentGroup',
  363. parent: null,
  364. },
  365. {
  366. _id: groupGrantDataTestChildUserGroupId, // isGranted
  367. name: 'groupGrantDataTestChildGroup',
  368. parent: groupGrantDataTestParentUserGroupId,
  369. },
  370. ]);
  371. await UserGroupRelation.insertMany([
  372. {
  373. relatedGroup: groupGrantDataTestParentUserGroupId._id,
  374. relatedUser: user3._id,
  375. },
  376. {
  377. relatedGroup: groupGrantDataTestChildUserGroupId._id,
  378. relatedUser: user3._id,
  379. },
  380. ]);
  381. groupGrantDataTestExternalUserGroupId = new mongoose.Types.ObjectId();
  382. groupGrantDataTestExternalUserGroupId2 = new mongoose.Types.ObjectId();
  383. await ExternalUserGroup.insertMany([
  384. {
  385. _id: groupGrantDataTestExternalUserGroupId,
  386. name: 'groupGrantDataTestExternalGroup',
  387. externalId: 'groupGrantDataTestExternalGroup',
  388. provider: ExternalGroupProviderType.ldap,
  389. parent: null,
  390. },
  391. {
  392. _id: groupGrantDataTestExternalUserGroupId2,
  393. name: 'groupGrantDataTestExternalGroup2',
  394. externalId: 'groupGrantDataTestExternalGroup2',
  395. provider: ExternalGroupProviderType.ldap,
  396. parent: null,
  397. },
  398. ]);
  399. await ExternalUserGroupRelation.insertMany([
  400. {
  401. relatedGroup: groupGrantDataTestExternalUserGroupId._id,
  402. relatedUser: user3._id,
  403. },
  404. ]);
  405. const groupGrantDataTestParentPagePath = '/groupGrantDataTestParentPage';
  406. const groupGrantDataTestParentPageId = new mongoose.Types.ObjectId();
  407. groupGrantDataTestChildPagePath = '/groupGrantDataTestParentPage/groupGrantDataTestChildPagePath';
  408. await Page.insertMany([
  409. {
  410. _id: groupGrantDataTestParentPageId,
  411. path: groupGrantDataTestParentPagePath,
  412. grant: Page.GRANT_USER_GROUP,
  413. creator: user3._id,
  414. lastUpdateUser: user3._id,
  415. grantedUsers: null,
  416. grantedGroups: [
  417. { item: groupGrantDataTestChildUserGroupId._id, type: GroupType.userGroup },
  418. { item: groupGrantDataTestExternalUserGroupId._id, type: GroupType.externalUserGroup },
  419. { item: groupGrantDataTestExternalUserGroupId2._id, type: GroupType.externalUserGroup },
  420. ],
  421. parent: rootPage._id,
  422. },
  423. {
  424. path: groupGrantDataTestChildPagePath,
  425. grant: Page.GRANT_USER_GROUP,
  426. creator: user3._id,
  427. lastUpdateUser: user3._id,
  428. grantedUsers: null,
  429. grantedGroups: [
  430. { item: groupGrantDataTestChildUserGroupId._id, type: GroupType.userGroup },
  431. { item: groupGrantDataTestExternalUserGroupId2._id, type: GroupType.externalUserGroup },
  432. ],
  433. parent: groupGrantDataTestParentPageId,
  434. },
  435. ]);
  436. };
  437. /*
  438. * prepare before all tests
  439. */
  440. beforeAll(async() => {
  441. crowi = await getInstance();
  442. pageGrantService = crowi.pageGrantService;
  443. User = mongoose.model('User');
  444. Page = mongoose.model('Page');
  445. rootPage = await Page.findOne({ path: '/' });
  446. await createDocumentsToTestIsGrantNormalized();
  447. await createDocumentsToTestGetPageGroupGrantData();
  448. });
  449. describe('Test isGrantNormalized method with shouldCheckDescendants false', () => {
  450. test('Should return true when Ancestor: root, Target: public', async() => {
  451. const targetPath = '/NEW';
  452. const grant = Page.GRANT_PUBLIC;
  453. const grantedUserIds = undefined;
  454. const grantedGroupIds = [];
  455. const shouldCheckDescendants = false;
  456. const result = await pageGrantService.isGrantNormalized(user1, targetPath, grant, grantedUserIds, grantedGroupIds, shouldCheckDescendants);
  457. expect(result).toBe(true);
  458. });
  459. test('Should return true when Ancestor: root, Target: GroupParent', async() => {
  460. const targetPath = '/NEW_GroupParent';
  461. const grant = Page.GRANT_USER_GROUP;
  462. const grantedUserIds = undefined;
  463. const grantedGroupIds = [{ item: groupParent._id, type: GroupType.userGroup }, { item: externalGroupParent._id, type: GroupType.externalUserGroup }];
  464. const shouldCheckDescendants = false;
  465. const result = await pageGrantService.isGrantNormalized(user1, targetPath, grant, grantedUserIds, grantedGroupIds, shouldCheckDescendants);
  466. expect(result).toBe(true);
  467. });
  468. test('Should return true when Ancestor: under-root public, Target: public', async() => {
  469. const targetPath = `${pageRootPublicPath}/NEW`;
  470. const grant = Page.GRANT_PUBLIC;
  471. const grantedUserIds = undefined;
  472. const grantedGroupIds = [];
  473. const shouldCheckDescendants = false;
  474. const result = await pageGrantService.isGrantNormalized(user1, targetPath, grant, grantedUserIds, grantedGroupIds, shouldCheckDescendants);
  475. expect(result).toBe(true);
  476. });
  477. test('Should return true when Ancestor: under-root GroupParent, Target: GroupParent', async() => {
  478. const targetPath = `${pageRootGroupParentPath}/NEW`;
  479. const grant = Page.GRANT_USER_GROUP;
  480. const grantedUserIds = undefined;
  481. const grantedGroupIds = [{ item: groupParent._id, type: GroupType.userGroup }, { item: externalGroupParent._id, type: GroupType.externalUserGroup }];
  482. const shouldCheckDescendants = false;
  483. const result = await pageGrantService.isGrantNormalized(user1, targetPath, grant, grantedUserIds, grantedGroupIds, shouldCheckDescendants);
  484. expect(result).toBe(true);
  485. });
  486. test('Should return true when Ancestor: public, Target: public', async() => {
  487. const targetPath = `${pageE1PublicPath}/NEW`;
  488. const grant = Page.GRANT_PUBLIC;
  489. const grantedUserIds = undefined;
  490. const grantedGroupIds = [];
  491. const shouldCheckDescendants = false;
  492. const result = await pageGrantService.isGrantNormalized(user1, targetPath, grant, grantedUserIds, grantedGroupIds, shouldCheckDescendants);
  493. expect(result).toBe(true);
  494. });
  495. test('Should return true when Ancestor: owned by User1, Target: owned by User1', async() => {
  496. const targetPath = `${pageE2User1Path}/NEW`;
  497. const grant = Page.GRANT_OWNER;
  498. const grantedUserIds = [user1._id];
  499. const grantedGroupIds = [];
  500. const shouldCheckDescendants = false;
  501. const result = await pageGrantService.isGrantNormalized(user1, targetPath, grant, grantedUserIds, grantedGroupIds, shouldCheckDescendants);
  502. expect(result).toBe(true);
  503. });
  504. test('Should return false when Ancestor: owned by GroupParent, Target: public', async() => {
  505. const targetPath = `${pageE3GroupParentPath}/NEW`;
  506. const grant = Page.GRANT_PUBLIC;
  507. const grantedUserIds = undefined;
  508. const grantedGroupIds = [];
  509. const shouldCheckDescendants = false;
  510. const result = await pageGrantService.isGrantNormalized(user1, targetPath, grant, grantedUserIds, grantedGroupIds, shouldCheckDescendants);
  511. expect(result).toBe(false);
  512. });
  513. test('Should return false when Ancestor: owned by GroupChild, Target: GroupParent', async() => {
  514. const targetPath = `${pageE3GroupChildPath}/NEW`;
  515. const grant = Page.GRANT_USER_GROUP;
  516. const grantedUserIds = undefined;
  517. const grantedGroupIds = [{ item: groupParent._id, type: GroupType.userGroup }, { item: externalGroupParent._id, type: GroupType.externalUserGroup }];
  518. const shouldCheckDescendants = false;
  519. const result = await pageGrantService.isGrantNormalized(user1, targetPath, grant, grantedUserIds, grantedGroupIds, shouldCheckDescendants);
  520. expect(result).toBe(false);
  521. });
  522. });
  523. describe('Test isGrantNormalized method with shouldCheckDescendants true', () => {
  524. test('Should return true when Target: public, Descendant: public', async() => {
  525. const targetPath = emptyPagePath1;
  526. const grant = Page.GRANT_PUBLIC;
  527. const grantedUserIds = undefined;
  528. const grantedGroupIds = [];
  529. const shouldCheckDescendants = true;
  530. const result = await pageGrantService.isGrantNormalized(user1, targetPath, grant, grantedUserIds, grantedGroupIds, shouldCheckDescendants);
  531. expect(result).toBe(true);
  532. });
  533. test('Should return true when Target: owned by User1, Descendant: User1 only', async() => {
  534. const targetPath = emptyPagePath2;
  535. const grant = Page.GRANT_OWNER;
  536. const grantedUserIds = [user1._id];
  537. const grantedGroupIds = [];
  538. const shouldCheckDescendants = true;
  539. const result = await pageGrantService.isGrantNormalized(user1, targetPath, grant, grantedUserIds, grantedGroupIds, shouldCheckDescendants);
  540. expect(result).toBe(true);
  541. });
  542. test('Should return true when Target: owned by GroupParent, Descendant: GroupParent, GroupChild and User1', async() => {
  543. const targetPath = emptyPagePath3;
  544. const grant = Page.GRANT_USER_GROUP;
  545. const grantedUserIds = undefined;
  546. const grantedGroupIds = [{ item: groupParent._id, type: GroupType.userGroup }, { item: externalGroupParent._id, type: GroupType.externalUserGroup }];
  547. const shouldCheckDescendants = true;
  548. const result = await pageGrantService.isGrantNormalized(user1, targetPath, grant, grantedUserIds, grantedGroupIds, shouldCheckDescendants);
  549. expect(result).toBe(true);
  550. });
  551. test('Should return false when Target: owned by User1, Descendant: public', async() => {
  552. const targetPath = emptyPagePath1;
  553. const grant = Page.GRANT_OWNER;
  554. const grantedUserIds = [user1._id];
  555. const grantedGroupIds = [];
  556. const shouldCheckDescendants = true;
  557. const result = await pageGrantService.isGrantNormalized(user1, targetPath, grant, grantedUserIds, grantedGroupIds, shouldCheckDescendants);
  558. expect(result).toBe(false);
  559. });
  560. });
  561. describe('Test validateGrantChange method', () => {
  562. test('Should return true when Target: completely owned by User1 (belongs to all groups)', async() => {
  563. const grant = Page.GRANT_PUBLIC;
  564. const grantedGroupIds = [];
  565. const result = await pageGrantService.validateGrantChange(
  566. user1, multipleGroupTreesAndUsersPage.grantedGroups, grant, grantedGroupIds,
  567. );
  568. expect(result).toBe(true);
  569. });
  570. test('Should return false when Target: partially owned by User2 (belongs to one of the groups), and change to public grant', async() => {
  571. const grant = Page.GRANT_PUBLIC;
  572. const grantedGroupIds = [];
  573. const result = await pageGrantService.validateGrantChange(
  574. user2, multipleGroupTreesAndUsersPage.grantedGroups, grant, grantedGroupIds,
  575. );
  576. expect(result).toBe(false);
  577. });
  578. test('Should return false when Target: partially owned by User2 (belongs to one of the groups), and change to owner grant', async() => {
  579. const grant = Page.GRANT_OWNER;
  580. const grantedGroupIds = [];
  581. const result = await pageGrantService.validateGrantChange(
  582. user2, multipleGroupTreesAndUsersPage.grantedGroups, grant, grantedGroupIds,
  583. );
  584. expect(result).toBe(false);
  585. });
  586. test('Should return false when Target: partially owned by User2 (belongs to one of the groups), and change to restricted grant', async() => {
  587. const grant = Page.GRANT_RESTRICTED;
  588. const grantedGroupIds = [];
  589. const result = await pageGrantService.validateGrantChange(
  590. user2, multipleGroupTreesAndUsersPage.grantedGroups, grant, grantedGroupIds,
  591. );
  592. expect(result).toBe(false);
  593. });
  594. test('Should return false when Target: partially owned by User2, and change to group grant without any groups of user2', async() => {
  595. const grant = Page.GRANT_USER_GROUP;
  596. const grantedGroupIds = [{ item: differentTreeGroup._id, type: GroupType.userGroup }];
  597. const result = await pageGrantService.validateGrantChange(
  598. user2, multipleGroupTreesAndUsersPage.grantedGroups, grant, grantedGroupIds,
  599. );
  600. expect(result).toBe(false);
  601. });
  602. });
  603. describe('Test for calcApplicableGrantData', () => {
  604. test('Only Public is Applicable in case of top page', async() => {
  605. const result = await pageGrantService.calcApplicableGrantData(rootPage, user1);
  606. expect(result).toStrictEqual(
  607. {
  608. [PageGrant.GRANT_PUBLIC]: null,
  609. },
  610. );
  611. });
  612. // parent property of all private pages is null
  613. test('Any grant is allowed if parent is null', async() => {
  614. const userRelatedUserGroups = await UserGroupRelation.findAllGroupsForUser(user1);
  615. const userRelatedExternalUserGroups = await ExternalUserGroupRelation.findAllGroupsForUser(user1);
  616. const userRelatedGroups = [
  617. ...userRelatedUserGroups.map((group) => {
  618. return { type: GroupType.userGroup, item: group };
  619. }),
  620. ...userRelatedExternalUserGroups.map((group) => {
  621. return { type: GroupType.externalUserGroup, item: group };
  622. }),
  623. ];
  624. // OnlyMe
  625. const rootOnlyMePage = await Page.findOne({ path: v4PageRootOnlyMePagePath });
  626. const rootOnlyMePageRes = await pageGrantService.calcApplicableGrantData(rootOnlyMePage, user1);
  627. expect(rootOnlyMePageRes).toStrictEqual(
  628. {
  629. [PageGrant.GRANT_PUBLIC]: null,
  630. [PageGrant.GRANT_RESTRICTED]: null,
  631. [PageGrant.GRANT_OWNER]: null,
  632. [PageGrant.GRANT_USER_GROUP]: { applicableGroups: userRelatedGroups },
  633. },
  634. );
  635. // AnyoneWithTheLink
  636. const rootAnyoneWithTheLinkPage = await Page.findOne({ path: v4PageRootAnyoneWithTheLinkPagePath });
  637. const anyoneWithTheLinkRes = await pageGrantService.calcApplicableGrantData(rootAnyoneWithTheLinkPage, user1);
  638. expect(anyoneWithTheLinkRes).toStrictEqual(
  639. {
  640. [PageGrant.GRANT_PUBLIC]: null,
  641. [PageGrant.GRANT_RESTRICTED]: null,
  642. [PageGrant.GRANT_OWNER]: null,
  643. [PageGrant.GRANT_USER_GROUP]: { applicableGroups: userRelatedGroups },
  644. },
  645. );
  646. // OnlyInsideTheGroup
  647. const rootOnlyInsideTheGroupPage = await Page.findOne({ path: v4PageRootOnlyInsideTheGroupPagePath });
  648. const onlyInsideTheGroupRes = await pageGrantService.calcApplicableGrantData(rootOnlyInsideTheGroupPage, user1);
  649. expect(onlyInsideTheGroupRes).toStrictEqual(
  650. {
  651. [PageGrant.GRANT_PUBLIC]: null,
  652. [PageGrant.GRANT_RESTRICTED]: null,
  653. [PageGrant.GRANT_OWNER]: null,
  654. [PageGrant.GRANT_USER_GROUP]: { applicableGroups: userRelatedGroups },
  655. },
  656. );
  657. });
  658. test('Any grant is allowed if parent is public', async() => {
  659. const userRelatedUserGroups = await UserGroupRelation.findAllGroupsForUser(user1);
  660. const userRelatedExternalUserGroups = await ExternalUserGroupRelation.findAllGroupsForUser(user1);
  661. const userRelatedGroups = [
  662. ...userRelatedUserGroups.map((group) => {
  663. return { type: GroupType.userGroup, item: group };
  664. }),
  665. ...userRelatedExternalUserGroups.map((group) => {
  666. return { type: GroupType.externalUserGroup, item: group };
  667. }),
  668. ];
  669. // OnlyMe
  670. const publicOnlyMePage = await Page.findOne({ path: pagePublicOnlyMePath });
  671. const publicOnlyMeRes = await pageGrantService.calcApplicableGrantData(publicOnlyMePage, user1);
  672. expect(publicOnlyMeRes).toStrictEqual(
  673. {
  674. [PageGrant.GRANT_PUBLIC]: null,
  675. [PageGrant.GRANT_RESTRICTED]: null,
  676. [PageGrant.GRANT_OWNER]: null,
  677. [PageGrant.GRANT_USER_GROUP]: { applicableGroups: userRelatedGroups },
  678. },
  679. );
  680. // AnyoneWithTheLink
  681. const publicAnyoneWithTheLinkPage = await Page.findOne({ path: pagePublicAnyoneWithTheLinkPath });
  682. const publicAnyoneWithTheLinkRes = await pageGrantService.calcApplicableGrantData(publicAnyoneWithTheLinkPage, user1);
  683. expect(publicAnyoneWithTheLinkRes).toStrictEqual(
  684. {
  685. [PageGrant.GRANT_PUBLIC]: null,
  686. [PageGrant.GRANT_RESTRICTED]: null,
  687. [PageGrant.GRANT_OWNER]: null,
  688. [PageGrant.GRANT_USER_GROUP]: { applicableGroups: userRelatedGroups },
  689. },
  690. );
  691. // OnlyInsideTheGroup
  692. const publicOnlyInsideTheGroupPage = await Page.findOne({ path: pagePublicOnlyInsideTheGroupPath });
  693. const publicOnlyInsideTheGroupRes = await pageGrantService.calcApplicableGrantData(publicOnlyInsideTheGroupPage, user1);
  694. expect(publicOnlyInsideTheGroupRes).toStrictEqual(
  695. {
  696. [PageGrant.GRANT_PUBLIC]: null,
  697. [PageGrant.GRANT_RESTRICTED]: null,
  698. [PageGrant.GRANT_OWNER]: null,
  699. [PageGrant.GRANT_USER_GROUP]: { applicableGroups: userRelatedGroups },
  700. },
  701. );
  702. });
  703. test('Only "GRANT_OWNER" is allowed if the user is the parent page\'s grantUser', async() => {
  704. // Public
  705. const onlyMePublicPage = await Page.findOne({ path: pageOnlyMePublicPath });
  706. const onlyMePublicRes = await pageGrantService.calcApplicableGrantData(onlyMePublicPage, user1);
  707. expect(onlyMePublicRes).toStrictEqual(
  708. {
  709. [PageGrant.GRANT_RESTRICTED]: null,
  710. [PageGrant.GRANT_OWNER]: null,
  711. },
  712. );
  713. // AnyoneWithTheLink
  714. const onlyMeAnyoneWithTheLinkPage = await Page.findOne({ path: pageOnlyMeAnyoneWithTheLinkPath });
  715. const onlyMeAnyoneWithTheLinkRes = await pageGrantService.calcApplicableGrantData(onlyMeAnyoneWithTheLinkPage, user1);
  716. expect(onlyMeAnyoneWithTheLinkRes).toStrictEqual(
  717. {
  718. [PageGrant.GRANT_RESTRICTED]: null,
  719. [PageGrant.GRANT_OWNER]: null,
  720. },
  721. );
  722. // OnlyInsideTheGroup
  723. const publicOnlyInsideTheGroupPage = await Page.findOne({ path: pageOnlyMeOnlyInsideTheGroupPath });
  724. const publicOnlyInsideTheGroupRes = await pageGrantService.calcApplicableGrantData(publicOnlyInsideTheGroupPage, user1);
  725. expect(publicOnlyInsideTheGroupRes).toStrictEqual(
  726. {
  727. [PageGrant.GRANT_RESTRICTED]: null,
  728. [PageGrant.GRANT_OWNER]: null,
  729. },
  730. );
  731. });
  732. test('"GRANT_OWNER" is not allowed if the user is not the parent page\'s grantUser', async() => {
  733. // Public
  734. const onlyMePublicPage = await Page.findOne({ path: pageOnlyMePublicPath });
  735. const onlyMePublicRes = await pageGrantService.calcApplicableGrantData(onlyMePublicPage, user2);
  736. expect(onlyMePublicRes).toStrictEqual(
  737. {
  738. [PageGrant.GRANT_RESTRICTED]: null,
  739. },
  740. );
  741. // AnyoneWithTheLink
  742. const onlyMeAnyoneWithTheLinkPage = await Page.findOne({ path: pageOnlyMeAnyoneWithTheLinkPath });
  743. const onlyMeAnyoneWithTheLinkRes = await pageGrantService.calcApplicableGrantData(onlyMeAnyoneWithTheLinkPage, user2);
  744. expect(onlyMeAnyoneWithTheLinkRes).toStrictEqual(
  745. {
  746. [PageGrant.GRANT_RESTRICTED]: null,
  747. },
  748. );
  749. // OnlyInsideTheGroup
  750. const publicOnlyInsideTheGroupPage = await Page.findOne({ path: pageOnlyMeOnlyInsideTheGroupPath });
  751. const publicOnlyInsideTheGroupRes = await pageGrantService.calcApplicableGrantData(publicOnlyInsideTheGroupPage, user2);
  752. expect(publicOnlyInsideTheGroupRes).toStrictEqual(
  753. {
  754. [PageGrant.GRANT_RESTRICTED]: null,
  755. },
  756. );
  757. });
  758. test('"GRANT_USER_GROUP" is allowed if the parent\'s grant is GRANT_USER_GROUP and the user is included in the group', async() => {
  759. const userGroups = await UserGroupRelation.findGroupsWithDescendantsByGroupAndUser(groupParent, user1);
  760. const externalUserGroups = await ExternalUserGroupRelation.findGroupsWithDescendantsByGroupAndUser(externalGroupParent, user1);
  761. const applicableGroups = [
  762. ...userGroups.map((group) => {
  763. return { type: GroupType.userGroup, item: group };
  764. }),
  765. ...externalUserGroups.map((group) => {
  766. return { type: GroupType.externalUserGroup, item: group };
  767. }),
  768. ];
  769. // Public
  770. const onlyInsideGroupPublicPage = await Page.findOne({ path: pageOnlyInsideTheGroupPublicPath });
  771. const onlyInsideGroupPublicRes = await pageGrantService.calcApplicableGrantData(onlyInsideGroupPublicPage, user1);
  772. expect(onlyInsideGroupPublicRes).toStrictEqual(
  773. {
  774. [PageGrant.GRANT_RESTRICTED]: null,
  775. [PageGrant.GRANT_OWNER]: null,
  776. [PageGrant.GRANT_USER_GROUP]: { applicableGroups },
  777. },
  778. );
  779. // OnlyMe
  780. const onlyInsideTheGroupOnlyMePage = await Page.findOne({ path: pageOnlyInsideTheGroupOnlyMePath });
  781. const onlyInsideTheGroupOnlyMeRes = await pageGrantService.calcApplicableGrantData(onlyInsideTheGroupOnlyMePage, user1);
  782. expect(onlyInsideTheGroupOnlyMeRes).toStrictEqual(
  783. {
  784. [PageGrant.GRANT_RESTRICTED]: null,
  785. [PageGrant.GRANT_OWNER]: null,
  786. [PageGrant.GRANT_USER_GROUP]: { applicableGroups },
  787. },
  788. );
  789. // AnyoneWithTheLink
  790. const onlyInsideTheGroupAnyoneWithTheLinkPage = await Page.findOne({ path: pageOnlyInsideTheGroupAnyoneWithTheLinkPath });
  791. const onlyInsideTheGroupAnyoneWithTheLinkRes = await pageGrantService.calcApplicableGrantData(onlyInsideTheGroupAnyoneWithTheLinkPage, user1);
  792. expect(onlyInsideTheGroupAnyoneWithTheLinkRes).toStrictEqual(
  793. {
  794. [PageGrant.GRANT_RESTRICTED]: null,
  795. [PageGrant.GRANT_OWNER]: null,
  796. [PageGrant.GRANT_USER_GROUP]: { applicableGroups },
  797. },
  798. );
  799. });
  800. });
  801. describe('Test for getPageGroupGrantData', () => {
  802. test('return expected group grant data', async() => {
  803. const groupGrantDataTestChildPage = await Page.findOne({ path: groupGrantDataTestChildPagePath });
  804. const result = await pageGrantService.getPageGroupGrantData(groupGrantDataTestChildPage, user3);
  805. expect(result).toStrictEqual({
  806. userRelatedGroups: [
  807. {
  808. id: groupGrantDataTestExternalUserGroupId.toString(),
  809. name: 'groupGrantDataTestExternalGroup',
  810. type: GroupType.externalUserGroup,
  811. provider: ExternalGroupProviderType.ldap,
  812. status: UserGroupPageGrantStatus.notGranted,
  813. },
  814. {
  815. id: groupGrantDataTestChildUserGroupId.toString(),
  816. name: 'groupGrantDataTestChildGroup',
  817. type: GroupType.userGroup,
  818. provider: undefined,
  819. status: UserGroupPageGrantStatus.isGranted,
  820. },
  821. {
  822. id: groupGrantDataTestParentUserGroupId.toString(),
  823. name: 'groupGrantDataTestParentGroup',
  824. type: GroupType.userGroup,
  825. provider: undefined,
  826. status: UserGroupPageGrantStatus.cannotGrant,
  827. },
  828. ],
  829. nonUserRelatedGrantedGroups: [
  830. {
  831. id: groupGrantDataTestExternalUserGroupId2.toString(),
  832. name: 'groupGrantDataTestExternalGroup2',
  833. type: GroupType.externalUserGroup,
  834. provider: ExternalGroupProviderType.ldap,
  835. },
  836. ],
  837. });
  838. });
  839. test('return empty arrays when page is root', async() => {
  840. const result = await pageGrantService.getPageGroupGrantData(rootPage, user1);
  841. expect(result).toStrictEqual({
  842. userRelatedGroups: [],
  843. nonUserRelatedGrantedGroups: [],
  844. });
  845. });
  846. });
  847. });