page-grant.test.ts 35 KB

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