page-grant.test.js 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836
  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 isGrantNormalized method with previousGrantedGroupIds given', () => {
  470. test('Should return true when Target: completely owned by User1 (belongs to all groups)', async() => {
  471. const targetPath = pageMultipleGroupTreesAndUsersPath;
  472. const grant = Page.GRANT_PUBLIC;
  473. const grantedUserIds = null;
  474. const grantedGroupIds = [];
  475. const shouldCheckDescendants = false;
  476. const result = await pageGrantService.isGrantNormalized(
  477. user1, targetPath, grant, grantedUserIds, grantedGroupIds, shouldCheckDescendants, false, multipleGroupTreesAndUsersPage.grantedGroups,
  478. );
  479. expect(result).toBe(true);
  480. });
  481. test('Should return false when Target: partially owned by User2 (belongs to one of the groups), and change to public grant', async() => {
  482. const targetPath = pageMultipleGroupTreesAndUsersPath;
  483. const grant = Page.GRANT_PUBLIC;
  484. const grantedUserIds = null;
  485. const grantedGroupIds = [];
  486. const shouldCheckDescendants = false;
  487. const result = await pageGrantService.isGrantNormalized(
  488. user2, targetPath, grant, grantedUserIds, grantedGroupIds, shouldCheckDescendants, false, multipleGroupTreesAndUsersPage.grantedGroups,
  489. );
  490. expect(result).toBe(false);
  491. });
  492. test('Should return false when Target: partially owned by User2 (belongs to one of the groups), and change to owner grant', async() => {
  493. const targetPath = pageMultipleGroupTreesAndUsersPath;
  494. const grant = Page.GRANT_OWNER;
  495. const grantedUserIds = [user2._id];
  496. const grantedGroupIds = [];
  497. const shouldCheckDescendants = false;
  498. const result = await pageGrantService.isGrantNormalized(
  499. user2, targetPath, grant, grantedUserIds, grantedGroupIds, shouldCheckDescendants, false, multipleGroupTreesAndUsersPage.grantedGroups,
  500. );
  501. expect(result).toBe(false);
  502. });
  503. test('Should return false when Target: partially owned by User2 (belongs to one of the groups), and change to restricted grant', async() => {
  504. const targetPath = pageMultipleGroupTreesAndUsersPath;
  505. const grant = Page.GRANT_RESTRICTED;
  506. const grantedUserIds = null;
  507. const grantedGroupIds = [];
  508. const shouldCheckDescendants = false;
  509. const result = await pageGrantService.isGrantNormalized(
  510. user2, targetPath, grant, grantedUserIds, grantedGroupIds, shouldCheckDescendants, false, multipleGroupTreesAndUsersPage.grantedGroups,
  511. );
  512. expect(result).toBe(false);
  513. });
  514. test('Should return false when Target: partially owned by User2, and change to group grant without any groups of user2', async() => {
  515. const targetPath = pageMultipleGroupTreesAndUsersPath;
  516. const grant = Page.GRANT_USER_GROUP;
  517. const grantedUserIds = null;
  518. const grantedGroupIds = [{ item: differentTreeGroup._id, type: GroupType.userGroup }];
  519. const shouldCheckDescendants = false;
  520. const result = await pageGrantService.isGrantNormalized(
  521. user2, targetPath, grant, grantedUserIds, grantedGroupIds, shouldCheckDescendants, false, multipleGroupTreesAndUsersPage.grantedGroups,
  522. );
  523. expect(result).toBe(false);
  524. });
  525. });
  526. describe('Test for calcApplicableGrantData', () => {
  527. test('Only Public is Applicable in case of top page', async() => {
  528. const result = await pageGrantService.calcApplicableGrantData(rootPage, user1);
  529. expect(result).toStrictEqual(
  530. {
  531. [PageGrant.GRANT_PUBLIC]: null,
  532. },
  533. );
  534. });
  535. // parent property of all private pages is null
  536. test('Any grant is allowed if parent is null', async() => {
  537. const userRelatedUserGroups = await UserGroupRelation.findAllGroupsForUser(user1);
  538. const userRelatedExternalUserGroups = await ExternalUserGroupRelation.findAllGroupsForUser(user1);
  539. const userRelatedGroups = [
  540. ...userRelatedUserGroups.map((group) => {
  541. return { type: GroupType.userGroup, item: group };
  542. }),
  543. ...userRelatedExternalUserGroups.map((group) => {
  544. return { type: GroupType.externalUserGroup, item: group };
  545. }),
  546. ];
  547. // OnlyMe
  548. const rootOnlyMePage = await Page.findOne({ path: v4PageRootOnlyMePagePath });
  549. const rootOnlyMePageRes = await pageGrantService.calcApplicableGrantData(rootOnlyMePage, user1);
  550. expect(rootOnlyMePageRes).toStrictEqual(
  551. {
  552. [PageGrant.GRANT_PUBLIC]: null,
  553. [PageGrant.GRANT_RESTRICTED]: null,
  554. [PageGrant.GRANT_OWNER]: null,
  555. [PageGrant.GRANT_USER_GROUP]: { applicableGroups: userRelatedGroups },
  556. },
  557. );
  558. // AnyoneWithTheLink
  559. const rootAnyoneWithTheLinkPage = await Page.findOne({ path: v4PageRootAnyoneWithTheLinkPagePath });
  560. const anyoneWithTheLinkRes = await pageGrantService.calcApplicableGrantData(rootAnyoneWithTheLinkPage, user1);
  561. expect(anyoneWithTheLinkRes).toStrictEqual(
  562. {
  563. [PageGrant.GRANT_PUBLIC]: null,
  564. [PageGrant.GRANT_RESTRICTED]: null,
  565. [PageGrant.GRANT_OWNER]: null,
  566. [PageGrant.GRANT_USER_GROUP]: { applicableGroups: userRelatedGroups },
  567. },
  568. );
  569. // OnlyInsideTheGroup
  570. const rootOnlyInsideTheGroupPage = await Page.findOne({ path: v4PageRootOnlyInsideTheGroupPagePath });
  571. const onlyInsideTheGroupRes = await pageGrantService.calcApplicableGrantData(rootOnlyInsideTheGroupPage, user1);
  572. expect(onlyInsideTheGroupRes).toStrictEqual(
  573. {
  574. [PageGrant.GRANT_PUBLIC]: null,
  575. [PageGrant.GRANT_RESTRICTED]: null,
  576. [PageGrant.GRANT_OWNER]: null,
  577. [PageGrant.GRANT_USER_GROUP]: { applicableGroups: userRelatedGroups },
  578. },
  579. );
  580. });
  581. test('Any grant is allowed if parent is public', async() => {
  582. const userRelatedUserGroups = await UserGroupRelation.findAllGroupsForUser(user1);
  583. const userRelatedExternalUserGroups = await ExternalUserGroupRelation.findAllGroupsForUser(user1);
  584. const userRelatedGroups = [
  585. ...userRelatedUserGroups.map((group) => {
  586. return { type: GroupType.userGroup, item: group };
  587. }),
  588. ...userRelatedExternalUserGroups.map((group) => {
  589. return { type: GroupType.externalUserGroup, item: group };
  590. }),
  591. ];
  592. // OnlyMe
  593. const publicOnlyMePage = await Page.findOne({ path: pagePublicOnlyMePath });
  594. const publicOnlyMeRes = await pageGrantService.calcApplicableGrantData(publicOnlyMePage, user1);
  595. expect(publicOnlyMeRes).toStrictEqual(
  596. {
  597. [PageGrant.GRANT_PUBLIC]: null,
  598. [PageGrant.GRANT_RESTRICTED]: null,
  599. [PageGrant.GRANT_OWNER]: null,
  600. [PageGrant.GRANT_USER_GROUP]: { applicableGroups: userRelatedGroups },
  601. },
  602. );
  603. // AnyoneWithTheLink
  604. const publicAnyoneWithTheLinkPage = await Page.findOne({ path: pagePublicAnyoneWithTheLinkPath });
  605. const publicAnyoneWithTheLinkRes = await pageGrantService.calcApplicableGrantData(publicAnyoneWithTheLinkPage, user1);
  606. expect(publicAnyoneWithTheLinkRes).toStrictEqual(
  607. {
  608. [PageGrant.GRANT_PUBLIC]: null,
  609. [PageGrant.GRANT_RESTRICTED]: null,
  610. [PageGrant.GRANT_OWNER]: null,
  611. [PageGrant.GRANT_USER_GROUP]: { applicableGroups: userRelatedGroups },
  612. },
  613. );
  614. // OnlyInsideTheGroup
  615. const publicOnlyInsideTheGroupPage = await Page.findOne({ path: pagePublicOnlyInsideTheGroupPath });
  616. const publicOnlyInsideTheGroupRes = await pageGrantService.calcApplicableGrantData(publicOnlyInsideTheGroupPage, user1);
  617. expect(publicOnlyInsideTheGroupRes).toStrictEqual(
  618. {
  619. [PageGrant.GRANT_PUBLIC]: null,
  620. [PageGrant.GRANT_RESTRICTED]: null,
  621. [PageGrant.GRANT_OWNER]: null,
  622. [PageGrant.GRANT_USER_GROUP]: { applicableGroups: userRelatedGroups },
  623. },
  624. );
  625. });
  626. test('Only "GRANT_OWNER" is allowed if the user is the parent page\'s grantUser', async() => {
  627. // Public
  628. const onlyMePublicPage = await Page.findOne({ path: pageOnlyMePublicPath });
  629. const onlyMePublicRes = await pageGrantService.calcApplicableGrantData(onlyMePublicPage, user1);
  630. expect(onlyMePublicRes).toStrictEqual(
  631. {
  632. [PageGrant.GRANT_RESTRICTED]: null,
  633. [PageGrant.GRANT_OWNER]: null,
  634. },
  635. );
  636. // AnyoneWithTheLink
  637. const onlyMeAnyoneWithTheLinkPage = await Page.findOne({ path: pageOnlyMeAnyoneWithTheLinkPath });
  638. const onlyMeAnyoneWithTheLinkRes = await pageGrantService.calcApplicableGrantData(onlyMeAnyoneWithTheLinkPage, user1);
  639. expect(onlyMeAnyoneWithTheLinkRes).toStrictEqual(
  640. {
  641. [PageGrant.GRANT_RESTRICTED]: null,
  642. [PageGrant.GRANT_OWNER]: null,
  643. },
  644. );
  645. // OnlyInsideTheGroup
  646. const publicOnlyInsideTheGroupPage = await Page.findOne({ path: pageOnlyMeOnlyInsideTheGroupPath });
  647. const publicOnlyInsideTheGroupRes = await pageGrantService.calcApplicableGrantData(publicOnlyInsideTheGroupPage, user1);
  648. expect(publicOnlyInsideTheGroupRes).toStrictEqual(
  649. {
  650. [PageGrant.GRANT_RESTRICTED]: null,
  651. [PageGrant.GRANT_OWNER]: null,
  652. },
  653. );
  654. });
  655. test('"GRANT_OWNER" is not allowed if the user is not the parent page\'s grantUser', async() => {
  656. // Public
  657. const onlyMePublicPage = await Page.findOne({ path: pageOnlyMePublicPath });
  658. const onlyMePublicRes = await pageGrantService.calcApplicableGrantData(onlyMePublicPage, user2);
  659. expect(onlyMePublicRes).toStrictEqual(
  660. {
  661. [PageGrant.GRANT_RESTRICTED]: null,
  662. },
  663. );
  664. // AnyoneWithTheLink
  665. const onlyMeAnyoneWithTheLinkPage = await Page.findOne({ path: pageOnlyMeAnyoneWithTheLinkPath });
  666. const onlyMeAnyoneWithTheLinkRes = await pageGrantService.calcApplicableGrantData(onlyMeAnyoneWithTheLinkPage, user2);
  667. expect(onlyMeAnyoneWithTheLinkRes).toStrictEqual(
  668. {
  669. [PageGrant.GRANT_RESTRICTED]: null,
  670. },
  671. );
  672. // OnlyInsideTheGroup
  673. const publicOnlyInsideTheGroupPage = await Page.findOne({ path: pageOnlyMeOnlyInsideTheGroupPath });
  674. const publicOnlyInsideTheGroupRes = await pageGrantService.calcApplicableGrantData(publicOnlyInsideTheGroupPage, user2);
  675. expect(publicOnlyInsideTheGroupRes).toStrictEqual(
  676. {
  677. [PageGrant.GRANT_RESTRICTED]: null,
  678. },
  679. );
  680. });
  681. test('"GRANT_USER_GROUP" is allowed if the parent\'s grant is GRANT_USER_GROUP and the user is included in the group', async() => {
  682. const userGroups = await UserGroupRelation.findGroupsWithDescendantsByGroupAndUser(groupParent, user1);
  683. const externalUserGroups = await ExternalUserGroupRelation.findGroupsWithDescendantsByGroupAndUser(externalGroupParent, user1);
  684. const applicableGroups = [
  685. ...userGroups.map((group) => {
  686. return { type: GroupType.userGroup, item: group };
  687. }),
  688. ...externalUserGroups.map((group) => {
  689. return { type: GroupType.externalUserGroup, item: group };
  690. }),
  691. ];
  692. // Public
  693. const onlyInsideGroupPublicPage = await Page.findOne({ path: pageOnlyInsideTheGroupPublicPath });
  694. const onlyInsideGroupPublicRes = await pageGrantService.calcApplicableGrantData(onlyInsideGroupPublicPage, user1);
  695. expect(onlyInsideGroupPublicRes).toStrictEqual(
  696. {
  697. [PageGrant.GRANT_RESTRICTED]: null,
  698. [PageGrant.GRANT_OWNER]: null,
  699. [PageGrant.GRANT_USER_GROUP]: { applicableGroups },
  700. },
  701. );
  702. // OnlyMe
  703. const onlyInsideTheGroupOnlyMePage = await Page.findOne({ path: pageOnlyInsideTheGroupOnlyMePath });
  704. const onlyInsideTheGroupOnlyMeRes = await pageGrantService.calcApplicableGrantData(onlyInsideTheGroupOnlyMePage, user1);
  705. expect(onlyInsideTheGroupOnlyMeRes).toStrictEqual(
  706. {
  707. [PageGrant.GRANT_RESTRICTED]: null,
  708. [PageGrant.GRANT_OWNER]: null,
  709. [PageGrant.GRANT_USER_GROUP]: { applicableGroups },
  710. },
  711. );
  712. // AnyoneWithTheLink
  713. const onlyInsideTheGroupAnyoneWithTheLinkPage = await Page.findOne({ path: pageOnlyInsideTheGroupAnyoneWithTheLinkPath });
  714. const onlyInsideTheGroupAnyoneWithTheLinkRes = await pageGrantService.calcApplicableGrantData(onlyInsideTheGroupAnyoneWithTheLinkPage, user1);
  715. expect(onlyInsideTheGroupAnyoneWithTheLinkRes).toStrictEqual(
  716. {
  717. [PageGrant.GRANT_RESTRICTED]: null,
  718. [PageGrant.GRANT_OWNER]: null,
  719. [PageGrant.GRANT_USER_GROUP]: { applicableGroups },
  720. },
  721. );
  722. });
  723. });
  724. });