page-grant.test.js 26 KB

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