auth.e2e-spec.ts 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import { DocumentNode } from 'graphql';
  2. import gql from 'graphql-tag';
  3. import {
  4. CreateAdministrator,
  5. CreateProductMutationArgs,
  6. CreateRole,
  7. LoginMutationArgs,
  8. Permission,
  9. UpdateProductMutationArgs,
  10. } from 'shared/generated-types';
  11. import { SUPER_ADMIN_USER_IDENTIFIER, SUPER_ADMIN_USER_PASSWORD } from 'shared/shared-constants';
  12. import {
  13. CREATE_ADMINISTRATOR,
  14. CREATE_ROLE,
  15. } from '../../admin-ui/src/app/data/definitions/administrator-definitions';
  16. import { ATTEMPT_LOGIN } from '../../admin-ui/src/app/data/definitions/auth-definitions';
  17. import {
  18. CREATE_PRODUCT,
  19. GET_PRODUCT_LIST,
  20. UPDATE_PRODUCT,
  21. } from '../../admin-ui/src/app/data/definitions/product-definitions';
  22. import { TEST_SETUP_TIMEOUT_MS } from './config/test-config';
  23. import { TestClient } from './test-client';
  24. import { TestServer } from './test-server';
  25. describe('Authorization & permissions', () => {
  26. const client = new TestClient();
  27. const server = new TestServer();
  28. beforeAll(async () => {
  29. const token = await server.init({
  30. productCount: 1,
  31. customerCount: 1,
  32. });
  33. await client.init();
  34. }, TEST_SETUP_TIMEOUT_MS);
  35. afterAll(async () => {
  36. await server.destroy();
  37. });
  38. describe('Anonymous user', () => {
  39. beforeAll(async () => {
  40. await client.asAnonymousUser();
  41. });
  42. it('can attempt login', async () => {
  43. await assertRequestAllowed<LoginMutationArgs>(ATTEMPT_LOGIN, {
  44. username: SUPER_ADMIN_USER_IDENTIFIER,
  45. password: SUPER_ADMIN_USER_PASSWORD,
  46. rememberMe: false,
  47. });
  48. });
  49. });
  50. describe('ReadCatalog', () => {
  51. beforeAll(async () => {
  52. await client.asSuperAdmin();
  53. const { identifier, password } = await createAdministratorWithPermissions('ReadCatalog', [
  54. Permission.ReadCatalog,
  55. ]);
  56. await client.asUserWithCredentials(identifier, password);
  57. });
  58. it('can read', async () => {
  59. await assertRequestAllowed(GET_PRODUCT_LIST);
  60. });
  61. it('cannot uppdate', async () => {
  62. await assertRequestForbidden<UpdateProductMutationArgs>(UPDATE_PRODUCT, {
  63. input: {
  64. id: '1',
  65. translations: [],
  66. },
  67. });
  68. });
  69. it('cannot create', async () => {
  70. await assertRequestForbidden<CreateProductMutationArgs>(CREATE_PRODUCT, {
  71. input: {
  72. translations: [],
  73. },
  74. });
  75. });
  76. });
  77. describe('CRUD on Customers', () => {
  78. beforeAll(async () => {
  79. await client.asSuperAdmin();
  80. const { identifier, password } = await createAdministratorWithPermissions('CRUDCustomer', [
  81. Permission.CreateCustomer,
  82. Permission.ReadCustomer,
  83. Permission.UpdateCustomer,
  84. Permission.DeleteCustomer,
  85. ]);
  86. await client.asUserWithCredentials(identifier, password);
  87. });
  88. it('can create', async () => {
  89. await assertRequestAllowed(
  90. gql`
  91. mutation CreateCustomer($input: CreateCustomerInput!) {
  92. createCustomer(input: $input) {
  93. id
  94. }
  95. }
  96. `,
  97. { input: { emailAddress: '', firstName: '', lastName: '' } },
  98. );
  99. });
  100. it('can read', async () => {
  101. await assertRequestAllowed(gql`
  102. query {
  103. customers {
  104. totalItems
  105. }
  106. }
  107. `);
  108. });
  109. });
  110. async function assertRequestAllowed<V>(operation: DocumentNode, variables?: V) {
  111. try {
  112. const status = await client.queryStatus(operation, variables);
  113. expect(status).toBe(200);
  114. } catch (e) {
  115. const status = getErrorStatusCode(e);
  116. if (!status) {
  117. fail(`Unexpected failure: ${e}`);
  118. } else {
  119. fail(`Operation should be allowed, got status ${getErrorStatusCode(e)}`);
  120. }
  121. }
  122. }
  123. async function assertRequestForbidden<V>(operation: DocumentNode, variables: V) {
  124. try {
  125. const status = await client.queryStatus(operation, variables);
  126. fail(`Should have thrown with 403 error, got ${status}`);
  127. } catch (e) {
  128. expect(getErrorStatusCode(e)).toBe(403);
  129. }
  130. }
  131. function getErrorStatusCode(err: any): number {
  132. return err.response.errors[0].message.statusCode;
  133. }
  134. async function createAdministratorWithPermissions(
  135. code: string,
  136. permissions: Permission[],
  137. ): Promise<{ identifier: string; password: string }> {
  138. const roleResult = await client.query<CreateRole.Mutation, CreateRole.Variables>(CREATE_ROLE, {
  139. input: {
  140. code,
  141. description: '',
  142. permissions,
  143. },
  144. });
  145. const role = roleResult.createRole;
  146. const identifier = `${code}@${Math.random()
  147. .toString(16)
  148. .substr(2, 8)}`;
  149. const password = `test`;
  150. const adminResult = await client.query<CreateAdministrator.Mutation, CreateAdministrator.Variables>(
  151. CREATE_ADMINISTRATOR,
  152. {
  153. input: {
  154. emailAddress: identifier,
  155. firstName: code,
  156. lastName: 'Admin',
  157. password,
  158. roleIds: [role.id],
  159. },
  160. },
  161. );
  162. const admin = adminResult.createAdministrator;
  163. return {
  164. identifier,
  165. password,
  166. };
  167. }
  168. });