page-grant.test.js 29 KB

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