page-grant.test.ts 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192
  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({
  106. name: 'DifferentTreeGroup',
  107. });
  108. // UserGroupRelations
  109. await UserGroupRelation.insertMany([
  110. {
  111. relatedGroup: groupParent._id,
  112. relatedUser: user1._id,
  113. },
  114. {
  115. relatedGroup: groupParent._id,
  116. relatedUser: user2._id,
  117. },
  118. {
  119. relatedGroup: groupChild._id,
  120. relatedUser: user1._id,
  121. },
  122. {
  123. relatedGroup: differentTreeGroup._id,
  124. relatedUser: user1._id,
  125. },
  126. ]);
  127. await ExternalUserGroup.insertMany([
  128. {
  129. _id: externalUserGroupIdParent,
  130. name: 'ExternalGroupParent',
  131. externalId: 'ExternalGroupParent',
  132. provider: ExternalGroupProviderType.ldap,
  133. parent: null,
  134. },
  135. {
  136. name: 'ExternalGroupChild',
  137. externalId: 'ExternalGroupChild',
  138. provider: ExternalGroupProviderType.ldap,
  139. parent: externalUserGroupIdParent,
  140. },
  141. ]);
  142. externalGroupParent = await ExternalUserGroup.findOne({
  143. name: 'ExternalGroupParent',
  144. });
  145. externalGroupChild = await ExternalUserGroup.findOne({
  146. name: 'ExternalGroupChild',
  147. });
  148. await ExternalUserGroupRelation.insertMany([
  149. {
  150. relatedGroup: externalGroupParent._id,
  151. relatedUser: user1._id,
  152. },
  153. {
  154. relatedGroup: externalGroupParent._id,
  155. relatedUser: user2._id,
  156. },
  157. {
  158. relatedGroup: externalGroupChild._id,
  159. relatedUser: user1._id,
  160. },
  161. ]);
  162. // Root page (Depth: 0)
  163. rootPage = await Page.findOne({ path: '/' });
  164. // Empty pages (Depth: 1)
  165. await Page.insertMany([
  166. {
  167. path: emptyPagePath1,
  168. grant: Page.GRANT_PUBLIC,
  169. isEmpty: true,
  170. parent: rootPage._id,
  171. },
  172. {
  173. path: emptyPagePath2,
  174. grant: Page.GRANT_PUBLIC,
  175. isEmpty: true,
  176. parent: rootPage._id,
  177. },
  178. {
  179. path: emptyPagePath3,
  180. grant: Page.GRANT_PUBLIC,
  181. isEmpty: true,
  182. parent: rootPage._id,
  183. },
  184. {
  185. path: pageRootPublicPath,
  186. grant: Page.GRANT_PUBLIC,
  187. creator: user1,
  188. lastUpdateUser: user1,
  189. grantedUsers: null,
  190. grantedGroups: [],
  191. parent: rootPage._id,
  192. },
  193. {
  194. path: pageRootGroupParentPath,
  195. grant: Page.GRANT_USER_GROUP,
  196. creator: user1,
  197. lastUpdateUser: user1,
  198. grantedUsers: null,
  199. grantedGroups: [
  200. { item: groupParent._id, type: GroupType.userGroup },
  201. { item: externalGroupParent._id, type: GroupType.externalUserGroup },
  202. ],
  203. parent: rootPage._id,
  204. },
  205. {
  206. path: pageMultipleGroupTreesAndUsersPath,
  207. grant: Page.GRANT_USER_GROUP,
  208. creator: user1,
  209. lastUpdateUser: user1,
  210. grantedUsers: null,
  211. grantedGroups: [
  212. { item: groupParent._id, type: GroupType.userGroup },
  213. { item: differentTreeGroup._id, type: GroupType.userGroup },
  214. ],
  215. parent: null,
  216. },
  217. ]);
  218. multipleGroupTreesAndUsersPage = await Page.findOne({
  219. path: pageMultipleGroupTreesAndUsersPath,
  220. });
  221. await Page.insertMany([
  222. // Root Page
  223. {
  224. path: rootPage,
  225. grant: Page.GRANT_PUBLIC,
  226. parent: null,
  227. },
  228. // OnlyMe v4
  229. {
  230. path: v4PageRootOnlyMePagePath,
  231. grant: Page.GRANT_OWNER,
  232. grantedUsers: [user1._id],
  233. parent: null,
  234. },
  235. // AnyoneWithTheLink v4
  236. {
  237. path: v4PageRootAnyoneWithTheLinkPagePath,
  238. grant: Page.GRANT_RESTRICTED,
  239. parent: null,
  240. },
  241. // OnlyInsideTheGroup v4
  242. {
  243. path: v4PageRootOnlyInsideTheGroupPagePath,
  244. grant: Page.GRANT_USER_GROUP,
  245. parent: null,
  246. grantedGroups: [
  247. { item: groupParent._id, type: GroupType.userGroup },
  248. { item: externalGroupParent._id, type: GroupType.externalUserGroup },
  249. ],
  250. },
  251. ]);
  252. rootPublicPage = await Page.findOne({ path: pageRootPublicPath });
  253. rootOnlyMePage = await Page.findOne({ path: v4PageRootOnlyMePagePath });
  254. rootOnlyInsideTheGroup = await Page.findOne({
  255. path: v4PageRootOnlyInsideTheGroupPagePath,
  256. });
  257. // Leaf pages (Depth: 2)
  258. await Page.insertMany([
  259. /*
  260. * Parent is public
  261. */
  262. {
  263. path: pagePublicOnlyMePath,
  264. grant: Page.GRANT_OWNER,
  265. parent: rootPublicPage._id,
  266. },
  267. {
  268. path: pagePublicAnyoneWithTheLinkPath,
  269. grant: Page.GRANT_RESTRICTED,
  270. parent: rootPublicPage._id,
  271. },
  272. {
  273. path: pagePublicOnlyInsideTheGroupPath,
  274. grant: Page.GRANT_USER_GROUP,
  275. parent: rootPublicPage._id,
  276. },
  277. /*
  278. * Parent is onlyMe
  279. */
  280. {
  281. path: pageOnlyMePublicPath,
  282. grant: Page.GRANT_PUBLIC,
  283. parent: rootOnlyMePage._id,
  284. },
  285. {
  286. path: pageOnlyMeAnyoneWithTheLinkPath,
  287. grant: Page.GRANT_RESTRICTED,
  288. parent: rootOnlyMePage._id,
  289. },
  290. {
  291. path: pageOnlyMeOnlyInsideTheGroupPath,
  292. grant: Page.GRANT_USER_GROUP,
  293. parent: rootOnlyMePage._id,
  294. },
  295. /*
  296. * Parent is OnlyInsideTheGroup
  297. */
  298. {
  299. path: pageOnlyInsideTheGroupPublicPath,
  300. grant: Page.GRANT_PUBLIC,
  301. parent: rootOnlyInsideTheGroup._id,
  302. },
  303. {
  304. path: pageOnlyInsideTheGroupOnlyMePath,
  305. grant: Page.GRANT_PUBLIC,
  306. parent: rootOnlyInsideTheGroup._id,
  307. },
  308. {
  309. path: pageOnlyInsideTheGroupAnyoneWithTheLinkPath,
  310. grant: Page.GRANT_PUBLIC,
  311. parent: rootOnlyInsideTheGroup._id,
  312. },
  313. ]);
  314. emptyPage1 = await Page.findOne({ path: emptyPagePath1 });
  315. emptyPage2 = await Page.findOne({ path: emptyPagePath2 });
  316. emptyPage3 = await Page.findOne({ path: emptyPagePath3 });
  317. // Leaf pages (Depth: 2)
  318. await Page.insertMany([
  319. {
  320. path: pageE1PublicPath,
  321. grant: Page.GRANT_PUBLIC,
  322. creator: user1,
  323. lastUpdateUser: user1,
  324. grantedUsers: null,
  325. grantedGroups: [],
  326. parent: emptyPage1._id,
  327. },
  328. {
  329. path: pageE2User1Path,
  330. grant: Page.GRANT_OWNER,
  331. creator: user1,
  332. lastUpdateUser: user1,
  333. grantedUsers: [user1._id],
  334. grantedGroups: [],
  335. parent: emptyPage2._id,
  336. },
  337. {
  338. path: pageE3GroupParentPath,
  339. grant: Page.GRANT_USER_GROUP,
  340. creator: user1,
  341. lastUpdateUser: user1,
  342. grantedUsers: null,
  343. grantedGroups: [
  344. { item: groupParent._id, type: GroupType.userGroup },
  345. { item: externalGroupParent._id, type: GroupType.externalUserGroup },
  346. ],
  347. parent: emptyPage3._id,
  348. },
  349. {
  350. path: pageE3GroupChildPath,
  351. grant: Page.GRANT_USER_GROUP,
  352. creator: user1,
  353. lastUpdateUser: user1,
  354. grantedUsers: null,
  355. grantedGroups: [
  356. { item: groupChild._id, type: GroupType.userGroup },
  357. { item: externalGroupChild._id, type: GroupType.externalUserGroup },
  358. ],
  359. parent: emptyPage3._id,
  360. },
  361. {
  362. path: pageE3User1Path,
  363. grant: Page.GRANT_OWNER,
  364. creator: user1,
  365. lastUpdateUser: user1,
  366. grantedUsers: [user1._id],
  367. grantedGroups: [],
  368. parent: emptyPage3._id,
  369. },
  370. ]);
  371. pageE1Public = await Page.findOne({ path: pageE1PublicPath });
  372. pageE2User1 = await Page.findOne({ path: pageE2User1Path });
  373. pageE3GroupParent = await Page.findOne({ path: pageE3GroupParentPath });
  374. pageE3GroupChild = await Page.findOne({ path: pageE3GroupChildPath });
  375. pageE3User1 = await Page.findOne({ path: pageE3User1Path });
  376. };
  377. const createDocumentsToTestGetPageGroupGrantData = async () => {
  378. await User.insertMany([
  379. { name: 'User3', username: 'User3', email: 'user3@example.com' },
  380. ]);
  381. user3 = await User.findOne({ username: 'User3' });
  382. groupGrantDataTestParentUserGroupId = new mongoose.Types.ObjectId();
  383. groupGrantDataTestChildUserGroupId = new mongoose.Types.ObjectId();
  384. await UserGroup.insertMany([
  385. {
  386. _id: groupGrantDataTestParentUserGroupId, // cannotGrant
  387. name: 'groupGrantDataTestParentGroup',
  388. parent: null,
  389. },
  390. {
  391. _id: groupGrantDataTestChildUserGroupId, // isGranted
  392. name: 'groupGrantDataTestChildGroup',
  393. parent: groupGrantDataTestParentUserGroupId,
  394. },
  395. ]);
  396. await UserGroupRelation.insertMany([
  397. {
  398. relatedGroup: groupGrantDataTestParentUserGroupId._id,
  399. relatedUser: user3._id,
  400. },
  401. {
  402. relatedGroup: groupGrantDataTestChildUserGroupId._id,
  403. relatedUser: user3._id,
  404. },
  405. ]);
  406. groupGrantDataTestExternalUserGroupId = new mongoose.Types.ObjectId();
  407. groupGrantDataTestExternalUserGroupId2 = new mongoose.Types.ObjectId();
  408. await ExternalUserGroup.insertMany([
  409. {
  410. _id: groupGrantDataTestExternalUserGroupId,
  411. name: 'groupGrantDataTestExternalGroup',
  412. externalId: 'groupGrantDataTestExternalGroup',
  413. provider: ExternalGroupProviderType.ldap,
  414. parent: null,
  415. },
  416. {
  417. _id: groupGrantDataTestExternalUserGroupId2,
  418. name: 'groupGrantDataTestExternalGroup2',
  419. externalId: 'groupGrantDataTestExternalGroup2',
  420. provider: ExternalGroupProviderType.ldap,
  421. parent: null,
  422. },
  423. ]);
  424. await ExternalUserGroupRelation.insertMany([
  425. {
  426. relatedGroup: groupGrantDataTestExternalUserGroupId._id,
  427. relatedUser: user3._id,
  428. },
  429. ]);
  430. const groupGrantDataTestParentPagePath = '/groupGrantDataTestParentPage';
  431. const groupGrantDataTestParentPageId = new mongoose.Types.ObjectId();
  432. groupGrantDataTestChildPagePath =
  433. '/groupGrantDataTestParentPage/groupGrantDataTestChildPagePath';
  434. await Page.insertMany([
  435. {
  436. _id: groupGrantDataTestParentPageId,
  437. path: groupGrantDataTestParentPagePath,
  438. grant: Page.GRANT_USER_GROUP,
  439. creator: user3._id,
  440. lastUpdateUser: user3._id,
  441. grantedUsers: null,
  442. grantedGroups: [
  443. {
  444. item: groupGrantDataTestChildUserGroupId._id,
  445. type: GroupType.userGroup,
  446. },
  447. {
  448. item: groupGrantDataTestExternalUserGroupId._id,
  449. type: GroupType.externalUserGroup,
  450. },
  451. {
  452. item: groupGrantDataTestExternalUserGroupId2._id,
  453. type: GroupType.externalUserGroup,
  454. },
  455. ],
  456. parent: rootPage._id,
  457. },
  458. {
  459. path: groupGrantDataTestChildPagePath,
  460. grant: Page.GRANT_USER_GROUP,
  461. creator: user3._id,
  462. lastUpdateUser: user3._id,
  463. grantedUsers: null,
  464. grantedGroups: [
  465. {
  466. item: groupGrantDataTestChildUserGroupId._id,
  467. type: GroupType.userGroup,
  468. },
  469. {
  470. item: groupGrantDataTestExternalUserGroupId2._id,
  471. type: GroupType.externalUserGroup,
  472. },
  473. ],
  474. parent: groupGrantDataTestParentPageId,
  475. },
  476. ]);
  477. };
  478. /*
  479. * prepare before all tests
  480. */
  481. beforeAll(async () => {
  482. crowi = await getInstance();
  483. pageGrantService = crowi.pageGrantService;
  484. User = mongoose.model('User');
  485. Page = mongoose.model('Page');
  486. rootPage = await Page.findOne({ path: '/' });
  487. await createDocumentsToTestIsGrantNormalized();
  488. await createDocumentsToTestGetPageGroupGrantData();
  489. });
  490. describe('Test isGrantNormalized method with shouldCheckDescendants false', () => {
  491. test('Should return true when Ancestor: root, Target: public', async () => {
  492. const targetPath = '/NEW';
  493. const grant = Page.GRANT_PUBLIC;
  494. const grantedUserIds = undefined;
  495. const grantedGroupIds = [];
  496. const shouldCheckDescendants = false;
  497. const result = await pageGrantService.isGrantNormalized(
  498. user1,
  499. targetPath,
  500. grant,
  501. grantedUserIds,
  502. grantedGroupIds,
  503. shouldCheckDescendants,
  504. );
  505. expect(result).toBe(true);
  506. });
  507. test('Should return true when Ancestor: root, Target: GroupParent', async () => {
  508. const targetPath = '/NEW_GroupParent';
  509. const grant = Page.GRANT_USER_GROUP;
  510. const grantedUserIds = undefined;
  511. const grantedGroupIds = [
  512. { item: groupParent._id, type: GroupType.userGroup },
  513. { item: externalGroupParent._id, type: GroupType.externalUserGroup },
  514. ];
  515. const shouldCheckDescendants = false;
  516. const result = await pageGrantService.isGrantNormalized(
  517. user1,
  518. targetPath,
  519. grant,
  520. grantedUserIds,
  521. grantedGroupIds,
  522. shouldCheckDescendants,
  523. );
  524. expect(result).toBe(true);
  525. });
  526. test('Should return true when Ancestor: under-root public, Target: public', async () => {
  527. const targetPath = `${pageRootPublicPath}/NEW`;
  528. const grant = Page.GRANT_PUBLIC;
  529. const grantedUserIds = undefined;
  530. const grantedGroupIds = [];
  531. const shouldCheckDescendants = false;
  532. const result = await pageGrantService.isGrantNormalized(
  533. user1,
  534. targetPath,
  535. grant,
  536. grantedUserIds,
  537. grantedGroupIds,
  538. shouldCheckDescendants,
  539. );
  540. expect(result).toBe(true);
  541. });
  542. test('Should return true when Ancestor: under-root GroupParent, Target: GroupParent', async () => {
  543. const targetPath = `${pageRootGroupParentPath}/NEW`;
  544. const grant = Page.GRANT_USER_GROUP;
  545. const grantedUserIds = undefined;
  546. const grantedGroupIds = [
  547. { item: groupParent._id, type: GroupType.userGroup },
  548. { item: externalGroupParent._id, type: GroupType.externalUserGroup },
  549. ];
  550. const shouldCheckDescendants = false;
  551. const result = await pageGrantService.isGrantNormalized(
  552. user1,
  553. targetPath,
  554. grant,
  555. grantedUserIds,
  556. grantedGroupIds,
  557. shouldCheckDescendants,
  558. );
  559. expect(result).toBe(true);
  560. });
  561. test('Should return true when Ancestor: public, Target: public', async () => {
  562. const targetPath = `${pageE1PublicPath}/NEW`;
  563. const grant = Page.GRANT_PUBLIC;
  564. const grantedUserIds = undefined;
  565. const grantedGroupIds = [];
  566. const shouldCheckDescendants = false;
  567. const result = await pageGrantService.isGrantNormalized(
  568. user1,
  569. targetPath,
  570. grant,
  571. grantedUserIds,
  572. grantedGroupIds,
  573. shouldCheckDescendants,
  574. );
  575. expect(result).toBe(true);
  576. });
  577. test('Should return true when Ancestor: owned by User1, Target: owned by User1', async () => {
  578. const targetPath = `${pageE2User1Path}/NEW`;
  579. const grant = Page.GRANT_OWNER;
  580. const grantedUserIds = [user1._id];
  581. const grantedGroupIds = [];
  582. const shouldCheckDescendants = false;
  583. const result = await pageGrantService.isGrantNormalized(
  584. user1,
  585. targetPath,
  586. grant,
  587. grantedUserIds,
  588. grantedGroupIds,
  589. shouldCheckDescendants,
  590. );
  591. expect(result).toBe(true);
  592. });
  593. test('Should return false when Ancestor: owned by GroupParent, Target: public', async () => {
  594. const targetPath = `${pageE3GroupParentPath}/NEW`;
  595. const grant = Page.GRANT_PUBLIC;
  596. const grantedUserIds = undefined;
  597. const grantedGroupIds = [];
  598. const shouldCheckDescendants = false;
  599. const result = await pageGrantService.isGrantNormalized(
  600. user1,
  601. targetPath,
  602. grant,
  603. grantedUserIds,
  604. grantedGroupIds,
  605. shouldCheckDescendants,
  606. );
  607. expect(result).toBe(false);
  608. });
  609. test('Should return false when Ancestor: owned by GroupChild, Target: GroupParent', async () => {
  610. const targetPath = `${pageE3GroupChildPath}/NEW`;
  611. const grant = Page.GRANT_USER_GROUP;
  612. const grantedUserIds = undefined;
  613. const grantedGroupIds = [
  614. { item: groupParent._id, type: GroupType.userGroup },
  615. { item: externalGroupParent._id, type: GroupType.externalUserGroup },
  616. ];
  617. const shouldCheckDescendants = false;
  618. const result = await pageGrantService.isGrantNormalized(
  619. user1,
  620. targetPath,
  621. grant,
  622. grantedUserIds,
  623. grantedGroupIds,
  624. shouldCheckDescendants,
  625. );
  626. expect(result).toBe(false);
  627. });
  628. });
  629. describe('Test isGrantNormalized method with shouldCheckDescendants true', () => {
  630. test('Should return true when Target: public, Descendant: public', async () => {
  631. const targetPath = emptyPagePath1;
  632. const grant = Page.GRANT_PUBLIC;
  633. const grantedUserIds = undefined;
  634. const grantedGroupIds = [];
  635. const shouldCheckDescendants = true;
  636. const result = await pageGrantService.isGrantNormalized(
  637. user1,
  638. targetPath,
  639. grant,
  640. grantedUserIds,
  641. grantedGroupIds,
  642. shouldCheckDescendants,
  643. );
  644. expect(result).toBe(true);
  645. });
  646. test('Should return true when Target: owned by User1, Descendant: User1 only', async () => {
  647. const targetPath = emptyPagePath2;
  648. const grant = Page.GRANT_OWNER;
  649. const grantedUserIds = [user1._id];
  650. const grantedGroupIds = [];
  651. const shouldCheckDescendants = true;
  652. const result = await pageGrantService.isGrantNormalized(
  653. user1,
  654. targetPath,
  655. grant,
  656. grantedUserIds,
  657. grantedGroupIds,
  658. shouldCheckDescendants,
  659. );
  660. expect(result).toBe(true);
  661. });
  662. test('Should return true when Target: owned by GroupParent, Descendant: GroupParent, GroupChild and User1', async () => {
  663. const targetPath = emptyPagePath3;
  664. const grant = Page.GRANT_USER_GROUP;
  665. const grantedUserIds = undefined;
  666. const grantedGroupIds = [
  667. { item: groupParent._id, type: GroupType.userGroup },
  668. { item: externalGroupParent._id, type: GroupType.externalUserGroup },
  669. ];
  670. const shouldCheckDescendants = true;
  671. const result = await pageGrantService.isGrantNormalized(
  672. user1,
  673. targetPath,
  674. grant,
  675. grantedUserIds,
  676. grantedGroupIds,
  677. shouldCheckDescendants,
  678. );
  679. expect(result).toBe(true);
  680. });
  681. test('Should return false when Target: owned by User1, Descendant: public', async () => {
  682. const targetPath = emptyPagePath1;
  683. const grant = Page.GRANT_OWNER;
  684. const grantedUserIds = [user1._id];
  685. const grantedGroupIds = [];
  686. const shouldCheckDescendants = true;
  687. const result = await pageGrantService.isGrantNormalized(
  688. user1,
  689. targetPath,
  690. grant,
  691. grantedUserIds,
  692. grantedGroupIds,
  693. shouldCheckDescendants,
  694. );
  695. expect(result).toBe(false);
  696. });
  697. });
  698. describe('Test validateGrantChange method', () => {
  699. test('Should return true when Target: completely owned by User1 (belongs to all groups)', async () => {
  700. const grant = Page.GRANT_PUBLIC;
  701. const grantedGroupIds = [];
  702. const result = await pageGrantService.validateGrantChange(
  703. user1,
  704. multipleGroupTreesAndUsersPage.grantedGroups,
  705. grant,
  706. grantedGroupIds,
  707. );
  708. expect(result).toBe(true);
  709. });
  710. test('Should return false when Target: partially owned by User2 (belongs to one of the groups), and change to public grant', async () => {
  711. const grant = Page.GRANT_PUBLIC;
  712. const grantedGroupIds = [];
  713. const result = await pageGrantService.validateGrantChange(
  714. user2,
  715. multipleGroupTreesAndUsersPage.grantedGroups,
  716. grant,
  717. grantedGroupIds,
  718. );
  719. expect(result).toBe(false);
  720. });
  721. test('Should return false when Target: partially owned by User2 (belongs to one of the groups), and change to owner grant', async () => {
  722. const grant = Page.GRANT_OWNER;
  723. const grantedGroupIds = [];
  724. const result = await pageGrantService.validateGrantChange(
  725. user2,
  726. multipleGroupTreesAndUsersPage.grantedGroups,
  727. grant,
  728. grantedGroupIds,
  729. );
  730. expect(result).toBe(false);
  731. });
  732. test('Should return false when Target: partially owned by User2 (belongs to one of the groups), and change to restricted grant', async () => {
  733. const grant = Page.GRANT_RESTRICTED;
  734. const grantedGroupIds = [];
  735. const result = await pageGrantService.validateGrantChange(
  736. user2,
  737. multipleGroupTreesAndUsersPage.grantedGroups,
  738. grant,
  739. grantedGroupIds,
  740. );
  741. expect(result).toBe(false);
  742. });
  743. test('Should return false when Target: partially owned by User2, and change to group grant without any groups of user2', async () => {
  744. const grant = Page.GRANT_USER_GROUP;
  745. const grantedGroupIds = [
  746. { item: differentTreeGroup._id, type: GroupType.userGroup },
  747. ];
  748. const result = await pageGrantService.validateGrantChange(
  749. user2,
  750. multipleGroupTreesAndUsersPage.grantedGroups,
  751. grant,
  752. grantedGroupIds,
  753. );
  754. expect(result).toBe(false);
  755. });
  756. });
  757. describe('Test for calcApplicableGrantData', () => {
  758. test('Only Public is Applicable in case of top page', async () => {
  759. const result = await pageGrantService.calcApplicableGrantData(
  760. rootPage,
  761. user1,
  762. );
  763. expect(result).toStrictEqual({
  764. [PageGrant.GRANT_PUBLIC]: null,
  765. });
  766. });
  767. // parent property of all private pages is null
  768. test('Any grant is allowed if parent is null', async () => {
  769. const userRelatedUserGroups =
  770. await UserGroupRelation.findAllGroupsForUser(user1);
  771. const userRelatedExternalUserGroups =
  772. await ExternalUserGroupRelation.findAllGroupsForUser(user1);
  773. const userRelatedGroups = [
  774. ...userRelatedUserGroups.map((group) => {
  775. return { type: GroupType.userGroup, item: group };
  776. }),
  777. ...userRelatedExternalUserGroups.map((group) => {
  778. return { type: GroupType.externalUserGroup, item: group };
  779. }),
  780. ];
  781. // OnlyMe
  782. const rootOnlyMePage = await Page.findOne({
  783. path: v4PageRootOnlyMePagePath,
  784. });
  785. const rootOnlyMePageRes = await pageGrantService.calcApplicableGrantData(
  786. rootOnlyMePage,
  787. user1,
  788. );
  789. expect(rootOnlyMePageRes).toStrictEqual({
  790. [PageGrant.GRANT_PUBLIC]: null,
  791. [PageGrant.GRANT_RESTRICTED]: null,
  792. [PageGrant.GRANT_OWNER]: null,
  793. [PageGrant.GRANT_USER_GROUP]: { applicableGroups: userRelatedGroups },
  794. });
  795. // AnyoneWithTheLink
  796. const rootAnyoneWithTheLinkPage = await Page.findOne({
  797. path: v4PageRootAnyoneWithTheLinkPagePath,
  798. });
  799. const anyoneWithTheLinkRes =
  800. await pageGrantService.calcApplicableGrantData(
  801. rootAnyoneWithTheLinkPage,
  802. user1,
  803. );
  804. expect(anyoneWithTheLinkRes).toStrictEqual({
  805. [PageGrant.GRANT_PUBLIC]: null,
  806. [PageGrant.GRANT_RESTRICTED]: null,
  807. [PageGrant.GRANT_OWNER]: null,
  808. [PageGrant.GRANT_USER_GROUP]: { applicableGroups: userRelatedGroups },
  809. });
  810. // OnlyInsideTheGroup
  811. const rootOnlyInsideTheGroupPage = await Page.findOne({
  812. path: v4PageRootOnlyInsideTheGroupPagePath,
  813. });
  814. const onlyInsideTheGroupRes =
  815. await pageGrantService.calcApplicableGrantData(
  816. rootOnlyInsideTheGroupPage,
  817. user1,
  818. );
  819. expect(onlyInsideTheGroupRes).toStrictEqual({
  820. [PageGrant.GRANT_PUBLIC]: null,
  821. [PageGrant.GRANT_RESTRICTED]: null,
  822. [PageGrant.GRANT_OWNER]: null,
  823. [PageGrant.GRANT_USER_GROUP]: { applicableGroups: userRelatedGroups },
  824. });
  825. });
  826. test('Any grant is allowed if parent is public', async () => {
  827. const userRelatedUserGroups =
  828. await UserGroupRelation.findAllGroupsForUser(user1);
  829. const userRelatedExternalUserGroups =
  830. await ExternalUserGroupRelation.findAllGroupsForUser(user1);
  831. const userRelatedGroups = [
  832. ...userRelatedUserGroups.map((group) => {
  833. return { type: GroupType.userGroup, item: group };
  834. }),
  835. ...userRelatedExternalUserGroups.map((group) => {
  836. return { type: GroupType.externalUserGroup, item: group };
  837. }),
  838. ];
  839. // OnlyMe
  840. const publicOnlyMePage = await Page.findOne({
  841. path: pagePublicOnlyMePath,
  842. });
  843. const publicOnlyMeRes = await pageGrantService.calcApplicableGrantData(
  844. publicOnlyMePage,
  845. user1,
  846. );
  847. expect(publicOnlyMeRes).toStrictEqual({
  848. [PageGrant.GRANT_PUBLIC]: null,
  849. [PageGrant.GRANT_RESTRICTED]: null,
  850. [PageGrant.GRANT_OWNER]: null,
  851. [PageGrant.GRANT_USER_GROUP]: { applicableGroups: userRelatedGroups },
  852. });
  853. // AnyoneWithTheLink
  854. const publicAnyoneWithTheLinkPage = await Page.findOne({
  855. path: pagePublicAnyoneWithTheLinkPath,
  856. });
  857. const publicAnyoneWithTheLinkRes =
  858. await pageGrantService.calcApplicableGrantData(
  859. publicAnyoneWithTheLinkPage,
  860. user1,
  861. );
  862. expect(publicAnyoneWithTheLinkRes).toStrictEqual({
  863. [PageGrant.GRANT_PUBLIC]: null,
  864. [PageGrant.GRANT_RESTRICTED]: null,
  865. [PageGrant.GRANT_OWNER]: null,
  866. [PageGrant.GRANT_USER_GROUP]: { applicableGroups: userRelatedGroups },
  867. });
  868. // OnlyInsideTheGroup
  869. const publicOnlyInsideTheGroupPage = await Page.findOne({
  870. path: pagePublicOnlyInsideTheGroupPath,
  871. });
  872. const publicOnlyInsideTheGroupRes =
  873. await pageGrantService.calcApplicableGrantData(
  874. publicOnlyInsideTheGroupPage,
  875. user1,
  876. );
  877. expect(publicOnlyInsideTheGroupRes).toStrictEqual({
  878. [PageGrant.GRANT_PUBLIC]: null,
  879. [PageGrant.GRANT_RESTRICTED]: null,
  880. [PageGrant.GRANT_OWNER]: null,
  881. [PageGrant.GRANT_USER_GROUP]: { applicableGroups: userRelatedGroups },
  882. });
  883. });
  884. test('Only "GRANT_OWNER" is allowed if the user is the parent page\'s grantUser', async () => {
  885. // Public
  886. const onlyMePublicPage = await Page.findOne({
  887. path: pageOnlyMePublicPath,
  888. });
  889. const onlyMePublicRes = await pageGrantService.calcApplicableGrantData(
  890. onlyMePublicPage,
  891. user1,
  892. );
  893. expect(onlyMePublicRes).toStrictEqual({
  894. [PageGrant.GRANT_RESTRICTED]: null,
  895. [PageGrant.GRANT_OWNER]: null,
  896. });
  897. // AnyoneWithTheLink
  898. const onlyMeAnyoneWithTheLinkPage = await Page.findOne({
  899. path: pageOnlyMeAnyoneWithTheLinkPath,
  900. });
  901. const onlyMeAnyoneWithTheLinkRes =
  902. await pageGrantService.calcApplicableGrantData(
  903. onlyMeAnyoneWithTheLinkPage,
  904. user1,
  905. );
  906. expect(onlyMeAnyoneWithTheLinkRes).toStrictEqual({
  907. [PageGrant.GRANT_RESTRICTED]: null,
  908. [PageGrant.GRANT_OWNER]: null,
  909. });
  910. // OnlyInsideTheGroup
  911. const publicOnlyInsideTheGroupPage = await Page.findOne({
  912. path: pageOnlyMeOnlyInsideTheGroupPath,
  913. });
  914. const publicOnlyInsideTheGroupRes =
  915. await pageGrantService.calcApplicableGrantData(
  916. publicOnlyInsideTheGroupPage,
  917. user1,
  918. );
  919. expect(publicOnlyInsideTheGroupRes).toStrictEqual({
  920. [PageGrant.GRANT_RESTRICTED]: null,
  921. [PageGrant.GRANT_OWNER]: null,
  922. });
  923. });
  924. test('"GRANT_OWNER" is not allowed if the user is not the parent page\'s grantUser', async () => {
  925. // Public
  926. const onlyMePublicPage = await Page.findOne({
  927. path: pageOnlyMePublicPath,
  928. });
  929. const onlyMePublicRes = await pageGrantService.calcApplicableGrantData(
  930. onlyMePublicPage,
  931. user2,
  932. );
  933. expect(onlyMePublicRes).toStrictEqual({
  934. [PageGrant.GRANT_RESTRICTED]: null,
  935. });
  936. // AnyoneWithTheLink
  937. const onlyMeAnyoneWithTheLinkPage = await Page.findOne({
  938. path: pageOnlyMeAnyoneWithTheLinkPath,
  939. });
  940. const onlyMeAnyoneWithTheLinkRes =
  941. await pageGrantService.calcApplicableGrantData(
  942. onlyMeAnyoneWithTheLinkPage,
  943. user2,
  944. );
  945. expect(onlyMeAnyoneWithTheLinkRes).toStrictEqual({
  946. [PageGrant.GRANT_RESTRICTED]: null,
  947. });
  948. // OnlyInsideTheGroup
  949. const publicOnlyInsideTheGroupPage = await Page.findOne({
  950. path: pageOnlyMeOnlyInsideTheGroupPath,
  951. });
  952. const publicOnlyInsideTheGroupRes =
  953. await pageGrantService.calcApplicableGrantData(
  954. publicOnlyInsideTheGroupPage,
  955. user2,
  956. );
  957. expect(publicOnlyInsideTheGroupRes).toStrictEqual({
  958. [PageGrant.GRANT_RESTRICTED]: null,
  959. });
  960. });
  961. test('"GRANT_USER_GROUP" is allowed if the parent\'s grant is GRANT_USER_GROUP and the user is included in the group', async () => {
  962. const userGroups =
  963. await UserGroupRelation.findGroupsWithDescendantsByGroupAndUser(
  964. groupParent,
  965. user1,
  966. );
  967. const externalUserGroups =
  968. await ExternalUserGroupRelation.findGroupsWithDescendantsByGroupAndUser(
  969. externalGroupParent,
  970. user1,
  971. );
  972. const applicableGroups = [
  973. ...userGroups.map((group) => {
  974. return { type: GroupType.userGroup, item: group };
  975. }),
  976. ...externalUserGroups.map((group) => {
  977. return { type: GroupType.externalUserGroup, item: group };
  978. }),
  979. ];
  980. // Public
  981. const onlyInsideGroupPublicPage = await Page.findOne({
  982. path: pageOnlyInsideTheGroupPublicPath,
  983. });
  984. const onlyInsideGroupPublicRes =
  985. await pageGrantService.calcApplicableGrantData(
  986. onlyInsideGroupPublicPage,
  987. user1,
  988. );
  989. expect(onlyInsideGroupPublicRes).toStrictEqual({
  990. [PageGrant.GRANT_RESTRICTED]: null,
  991. [PageGrant.GRANT_OWNER]: null,
  992. [PageGrant.GRANT_USER_GROUP]: { applicableGroups },
  993. });
  994. // OnlyMe
  995. const onlyInsideTheGroupOnlyMePage = await Page.findOne({
  996. path: pageOnlyInsideTheGroupOnlyMePath,
  997. });
  998. const onlyInsideTheGroupOnlyMeRes =
  999. await pageGrantService.calcApplicableGrantData(
  1000. onlyInsideTheGroupOnlyMePage,
  1001. user1,
  1002. );
  1003. expect(onlyInsideTheGroupOnlyMeRes).toStrictEqual({
  1004. [PageGrant.GRANT_RESTRICTED]: null,
  1005. [PageGrant.GRANT_OWNER]: null,
  1006. [PageGrant.GRANT_USER_GROUP]: { applicableGroups },
  1007. });
  1008. // AnyoneWithTheLink
  1009. const onlyInsideTheGroupAnyoneWithTheLinkPage = await Page.findOne({
  1010. path: pageOnlyInsideTheGroupAnyoneWithTheLinkPath,
  1011. });
  1012. const onlyInsideTheGroupAnyoneWithTheLinkRes =
  1013. await pageGrantService.calcApplicableGrantData(
  1014. onlyInsideTheGroupAnyoneWithTheLinkPage,
  1015. user1,
  1016. );
  1017. expect(onlyInsideTheGroupAnyoneWithTheLinkRes).toStrictEqual({
  1018. [PageGrant.GRANT_RESTRICTED]: null,
  1019. [PageGrant.GRANT_OWNER]: null,
  1020. [PageGrant.GRANT_USER_GROUP]: { applicableGroups },
  1021. });
  1022. });
  1023. });
  1024. describe('Test for getPageGroupGrantData', () => {
  1025. test('return expected group grant data', async () => {
  1026. const groupGrantDataTestChildPage = await Page.findOne({
  1027. path: groupGrantDataTestChildPagePath,
  1028. });
  1029. const result = await pageGrantService.getPageGroupGrantData(
  1030. groupGrantDataTestChildPage,
  1031. user3,
  1032. );
  1033. expect(result).toStrictEqual({
  1034. userRelatedGroups: [
  1035. {
  1036. id: groupGrantDataTestExternalUserGroupId.toString(),
  1037. name: 'groupGrantDataTestExternalGroup',
  1038. type: GroupType.externalUserGroup,
  1039. provider: ExternalGroupProviderType.ldap,
  1040. status: UserGroupPageGrantStatus.notGranted,
  1041. },
  1042. {
  1043. id: groupGrantDataTestChildUserGroupId.toString(),
  1044. name: 'groupGrantDataTestChildGroup',
  1045. type: GroupType.userGroup,
  1046. provider: undefined,
  1047. status: UserGroupPageGrantStatus.isGranted,
  1048. },
  1049. {
  1050. id: groupGrantDataTestParentUserGroupId.toString(),
  1051. name: 'groupGrantDataTestParentGroup',
  1052. type: GroupType.userGroup,
  1053. provider: undefined,
  1054. status: UserGroupPageGrantStatus.cannotGrant,
  1055. },
  1056. ],
  1057. nonUserRelatedGrantedGroups: [
  1058. {
  1059. id: groupGrantDataTestExternalUserGroupId2.toString(),
  1060. name: 'groupGrantDataTestExternalGroup2',
  1061. type: GroupType.externalUserGroup,
  1062. provider: ExternalGroupProviderType.ldap,
  1063. },
  1064. ],
  1065. });
  1066. });
  1067. test('return empty arrays when page is root', async () => {
  1068. const result = await pageGrantService.getPageGroupGrantData(
  1069. rootPage,
  1070. user1,
  1071. );
  1072. expect(result).toStrictEqual({
  1073. userRelatedGroups: [],
  1074. nonUserRelatedGrantedGroups: [],
  1075. });
  1076. });
  1077. });
  1078. });