foreman_openscap 4.3.1 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/api/v2/compliance/arf_reports_controller.rb +0 -6
  3. data/app/controllers/api/v2/compliance/oval_policies_controller.rb +1 -1
  4. data/app/graphql/mutations/oval_contents/delete.rb +9 -0
  5. data/app/graphql/mutations/oval_policies/delete.rb +9 -0
  6. data/app/graphql/mutations/oval_policies/update.rb +15 -0
  7. data/app/graphql/types/oval_check.rb +11 -0
  8. data/app/graphql/types/oval_content.rb +2 -0
  9. data/app/graphql/types/oval_policy.rb +3 -0
  10. data/app/helpers/arf_report_dashboard_helper.rb +2 -4
  11. data/app/helpers/compliance_hosts_helper.rb +1 -1
  12. data/app/helpers/policies_helper.rb +1 -1
  13. data/app/models/concerns/foreman_openscap/host_extensions.rb +0 -6
  14. data/app/models/concerns/foreman_openscap/oval_facet_hostgroup_extensions.rb +15 -0
  15. data/app/models/foreman_openscap/oval_content.rb +2 -0
  16. data/app/services/foreman_openscap/client_config/base.rb +1 -0
  17. data/app/services/foreman_openscap/client_config/puppet.rb +6 -2
  18. data/app/services/foreman_openscap/oval/configure.rb +1 -1
  19. data/app/services/foreman_openscap/oval/setup.rb +5 -5
  20. data/app/services/foreman_openscap/oval/setup_check.rb +5 -2
  21. data/app/views/api/v2/compliance/oval_contents/destroy.json.rabl +3 -0
  22. data/app/views/arf_reports/_metrics.html.erb +4 -4
  23. data/app/views/compliance_hosts/show.html.erb +4 -6
  24. data/app/views/dashboard/_compliance_reports_breakdown_widget.html.erb +4 -3
  25. data/app/views/policy_dashboard/_policy_chart_widget.html.erb +3 -2
  26. data/db/migrate/20200117135424_migrate_port_overrides_to_int.rb +2 -1
  27. data/db/migrate/20201202110213_update_puppet_port_param_type.rb +2 -1
  28. data/db/migrate/20210819143316_drop_unused_tables.rb +6 -0
  29. data/lib/foreman_openscap/engine.rb +5 -7
  30. data/lib/foreman_openscap/version.rb +1 -1
  31. data/package.json +3 -6
  32. data/test/functional/api/v2/compliance/oval_reports_controller_test.rb +1 -1
  33. data/test/functional/api/v2/compliance/policies_controller_test.rb +2 -0
  34. data/test/graphql/mutations/oval_policies/delete_mutation_test.rb +63 -0
  35. data/test/graphql/queries/oval_content_query_test.rb +29 -0
  36. data/test/helpers/arf_report_dashboard_helper_test.rb +9 -10
  37. data/test/helpers/policy_dashboard_helper_test.rb +1 -1
  38. data/test/test_plugin_helper.rb +9 -4
  39. data/test/unit/policy_test.rb +1 -1
  40. data/test/unit/services/config_name_service_test.rb +1 -0
  41. data/test/unit/services/hostgroup_overrider_test.rb +2 -1
  42. data/test/unit/services/lookup_key_overrider_test.rb +4 -1
  43. data/test/unit/services/oval/setup_check_test.rb +37 -0
  44. data/webpack/components/ConfirmModal.js +63 -0
  45. data/webpack/components/ConfirmModal.scss +3 -0
  46. data/webpack/components/EditableInput.js +157 -0
  47. data/webpack/components/EditableInput.scss +3 -0
  48. data/webpack/components/EmptyState.js +12 -3
  49. data/webpack/components/IndexLayout.js +11 -4
  50. data/webpack/components/IndexTable/index.js +17 -18
  51. data/webpack/components/LinkButton.js +26 -0
  52. data/webpack/components/withDeleteModal.js +51 -0
  53. data/webpack/components/withLoading.js +41 -4
  54. data/webpack/graphql/mutations/deleteOvalContent.gql +9 -0
  55. data/webpack/graphql/mutations/deleteOvalPolicy.gql +9 -0
  56. data/webpack/graphql/mutations/updateOvalPolicy.gql +14 -0
  57. data/webpack/graphql/queries/currentUserAttributes.gql +11 -0
  58. data/webpack/graphql/queries/cves.gql +5 -0
  59. data/webpack/graphql/queries/hostgroups.gql +14 -0
  60. data/webpack/graphql/queries/ovalContent.gql +8 -0
  61. data/webpack/graphql/queries/ovalContents.gql +8 -0
  62. data/webpack/graphql/queries/ovalPolicies.gql +8 -0
  63. data/webpack/graphql/queries/ovalPolicy.gql +5 -0
  64. data/webpack/helpers/formFieldsHelper.js +63 -0
  65. data/webpack/helpers/mutationHelper.js +68 -0
  66. data/webpack/helpers/pathsHelper.js +5 -0
  67. data/webpack/helpers/permissionsHelper.js +42 -0
  68. data/webpack/helpers/toastHelper.js +3 -0
  69. data/webpack/routes/OvalContents/OvalContentsIndex/OvalContentsIndex.js +26 -0
  70. data/webpack/routes/OvalContents/OvalContentsIndex/OvalContentsTable.js +50 -5
  71. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsDestroy.fixtures.js +105 -0
  72. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsDestroy.test.js +124 -0
  73. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsIndex.fixtures.js +93 -77
  74. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsIndex.test.js +53 -6
  75. data/webpack/routes/OvalContents/OvalContentsIndex/index.js +7 -1
  76. data/webpack/routes/OvalContents/OvalContentsNew/OvalContentsNew.js +138 -0
  77. data/webpack/routes/OvalContents/OvalContentsNew/OvalContentsNew.scss +3 -0
  78. data/webpack/routes/OvalContents/OvalContentsNew/OvalContentsNewHelper.js +73 -0
  79. data/webpack/routes/OvalContents/OvalContentsNew/__tests__/OvalContentsNew.test.js +104 -0
  80. data/webpack/routes/OvalContents/OvalContentsNew/index.js +13 -0
  81. data/webpack/routes/OvalContents/OvalContentsShow/OvalContentsShow.js +62 -0
  82. data/webpack/routes/OvalContents/OvalContentsShow/OvalContentsShow.test.js +45 -0
  83. data/webpack/routes/OvalContents/OvalContentsShow/OvalContentsShowHelper.js +0 -0
  84. data/webpack/routes/OvalContents/OvalContentsShow/index.js +35 -0
  85. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/OvalPoliciesIndex.js +18 -2
  86. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/OvalPoliciesTable.js +16 -3
  87. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesDestroy.fixtures.js +101 -0
  88. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesDestroy.test.js +117 -0
  89. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesIndex.fixtures.js +71 -21
  90. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesIndex.test.js +34 -2
  91. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/index.js +7 -1
  92. data/webpack/routes/OvalPolicies/OvalPoliciesShow/CvesTab.js +1 -0
  93. data/webpack/routes/OvalPolicies/OvalPoliciesShow/DetailsTab.js +85 -0
  94. data/webpack/routes/OvalPolicies/OvalPoliciesShow/HostgroupsTab.js +49 -0
  95. data/webpack/routes/OvalPolicies/OvalPoliciesShow/HostgroupsTable.js +38 -0
  96. data/webpack/routes/OvalPolicies/OvalPoliciesShow/OvalPoliciesShow.js +15 -12
  97. data/webpack/routes/OvalPolicies/OvalPoliciesShow/OvalPoliciesShowHelper.js +77 -0
  98. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesEdit.fixtures.js +48 -0
  99. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesEdit.test.js +175 -0
  100. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesShow.fixtures.js +40 -4
  101. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesShow.test.js +64 -4
  102. data/webpack/routes/OvalPolicies/OvalPoliciesShow/index.js +4 -0
  103. data/webpack/routes/routes.js +14 -0
  104. data/webpack/testHelper.js +42 -2
  105. metadata +53 -7
@@ -0,0 +1,175 @@
1
+ import React from 'react';
2
+
3
+ import { render, screen, waitFor } from '@testing-library/react';
4
+ import '@testing-library/jest-dom';
5
+ import userEvent from '@testing-library/user-event';
6
+
7
+ import OvalPoliciesShow from '../';
8
+ import {
9
+ historyMock,
10
+ ovalPolicyId,
11
+ policyDetailMock,
12
+ ovalPolicy,
13
+ } from './OvalPoliciesShow.fixtures';
14
+ import {
15
+ policyUpdateMock,
16
+ policyUpdateErrorMock,
17
+ policyUpdateValidationMock,
18
+ updatedName,
19
+ } from './OvalPoliciesEdit.fixtures';
20
+ import { ovalPoliciesShowPath } from '../../../../helpers/pathsHelper';
21
+
22
+ import {
23
+ withMockedProvider,
24
+ tick,
25
+ withRouter,
26
+ withRedux,
27
+ } from '../../../../testHelper';
28
+
29
+ import * as toasts from '../../../../helpers/toastHelper';
30
+
31
+ const TestComponent = withRouter(
32
+ withRedux(withMockedProvider(OvalPoliciesShow))
33
+ );
34
+
35
+ describe('OvalPoliciesShow', () => {
36
+ it('should open and close inline edit for name', async () => {
37
+ render(
38
+ <TestComponent
39
+ history={historyMock}
40
+ match={{
41
+ params: { id: ovalPolicyId, tab: 'details' },
42
+ path: ovalPoliciesShowPath,
43
+ }}
44
+ mocks={policyDetailMock}
45
+ />
46
+ );
47
+ await waitFor(tick);
48
+ userEvent.click(screen.getByRole('button', { name: 'edit name' }));
49
+ userEvent.clear(screen.getByLabelText(/name text input/));
50
+ userEvent.type(screen.getByLabelText(/name text input/), 'foo');
51
+ expect(screen.getByLabelText(/name text input/)).toHaveAttribute(
52
+ 'value',
53
+ 'foo'
54
+ );
55
+ userEvent.click(
56
+ screen.getByRole('button', { name: 'cancel editing name' })
57
+ );
58
+ expect(screen.queryByText('foo')).not.toBeInTheDocument();
59
+ });
60
+ it('should update policy name', async () => {
61
+ const showToast = jest.fn();
62
+ jest.spyOn(toasts, 'showToast').mockImplementation(() => showToast);
63
+
64
+ const { container } = render(
65
+ <TestComponent
66
+ history={historyMock}
67
+ match={{
68
+ params: { id: ovalPolicyId, tab: 'details' },
69
+ path: ovalPoliciesShowPath,
70
+ }}
71
+ mocks={policyDetailMock.concat(policyUpdateMock)}
72
+ />
73
+ );
74
+ await waitFor(tick);
75
+ const editBtn = screen.getByRole('button', { name: 'edit name' });
76
+ expect(editBtn).toBeInTheDocument();
77
+ expect(
78
+ screen.queryByRole('button', { name: 'submit name' })
79
+ ).not.toBeInTheDocument();
80
+
81
+ userEvent.click(editBtn);
82
+ expect(
83
+ screen.queryByRole('button', { name: 'edit name' })
84
+ ).not.toBeInTheDocument();
85
+ const inputField = screen.getByLabelText(/name text input/);
86
+ const submitBtn = screen.getByRole('button', { name: 'submit name' });
87
+ const cancelBtn = screen.getByRole('button', {
88
+ name: 'cancel editing name',
89
+ });
90
+
91
+ userEvent.clear(inputField);
92
+ userEvent.type(inputField, updatedName);
93
+ userEvent.click(submitBtn);
94
+ expect(inputField).toBeDisabled();
95
+ expect(submitBtn).toBeDisabled();
96
+ expect(cancelBtn).toBeDisabled();
97
+ const spinner = container.querySelector('#edit-name-spinner');
98
+ expect(spinner).toBeInTheDocument();
99
+ await waitFor(tick);
100
+ expect(showToast).toHaveBeenCalledWith({
101
+ type: 'success',
102
+ message: 'OVAL policy was successfully updated.',
103
+ });
104
+
105
+ expect(inputField).not.toBeInTheDocument();
106
+ expect(editBtn).toBeInTheDocument();
107
+ expect(cancelBtn).not.toBeInTheDocument();
108
+ expect(
109
+ screen.queryByRole('button', { name: 'submit name' })
110
+ ).not.toBeInTheDocument();
111
+ await waitFor(tick);
112
+ expect(screen.getAllByText(updatedName).pop()).toBeInTheDocument();
113
+ });
114
+ it('should show unexpected errors', async () => {
115
+ const showToast = jest.fn();
116
+ jest.spyOn(toasts, 'showToast').mockImplementation(() => showToast);
117
+
118
+ render(
119
+ <TestComponent
120
+ history={historyMock}
121
+ match={{
122
+ params: { id: ovalPolicyId, tab: 'details' },
123
+ path: ovalPoliciesShowPath,
124
+ }}
125
+ mocks={policyDetailMock.concat(policyUpdateErrorMock)}
126
+ />
127
+ );
128
+ await waitFor(tick);
129
+ const editBtn = screen.getByRole('button', { name: 'edit name' });
130
+ userEvent.click(editBtn);
131
+ const inputField = screen.getByLabelText(/name text input/);
132
+ userEvent.clear(inputField);
133
+ userEvent.type(inputField, updatedName);
134
+ userEvent.click(screen.getByRole('button', { name: 'submit name' }));
135
+ await waitFor(tick);
136
+ expect(showToast).toHaveBeenCalledWith({
137
+ type: 'error',
138
+ message:
139
+ 'There was a following error when updating OVAL policy: This is an unexpected failure.',
140
+ });
141
+ expect(inputField).toBeInTheDocument();
142
+ expect(inputField).not.toBeDisabled();
143
+ expect(screen.getByText(ovalPolicy.name)).toBeInTheDocument();
144
+ });
145
+ it('should show validation errors', async () => {
146
+ const showToast = jest.fn();
147
+ jest.spyOn(toasts, 'showToast').mockImplementation(() => showToast);
148
+
149
+ const { container } = render(
150
+ <TestComponent
151
+ history={historyMock}
152
+ match={{
153
+ params: { id: ovalPolicyId, tab: 'details' },
154
+ path: ovalPoliciesShowPath,
155
+ }}
156
+ mocks={policyDetailMock.concat(policyUpdateValidationMock)}
157
+ />
158
+ );
159
+ await waitFor(tick);
160
+ const editBtn = screen.getByRole('button', { name: 'edit name' });
161
+ userEvent.click(editBtn);
162
+ const inputField = screen.getByLabelText(/name text input/);
163
+ userEvent.clear(inputField);
164
+ userEvent.type(inputField, updatedName);
165
+ userEvent.click(screen.getByRole('button', { name: 'submit name' }));
166
+ await waitFor(tick);
167
+ expect(inputField).toBeInTheDocument();
168
+ expect(inputField).not.toBeDisabled();
169
+ expect(
170
+ container.querySelector('#edit-name-spinner')
171
+ ).not.toBeInTheDocument();
172
+ expect(screen.getByText(ovalPolicy.name)).toBeInTheDocument();
173
+ expect(screen.getByText('has already been taken')).toBeInTheDocument();
174
+ });
175
+ });
@@ -1,11 +1,14 @@
1
- import { mockFactory } from '../../../../testHelper';
1
+ import { mockFactory, admin, intruder } from '../../../../testHelper';
2
2
  import ovalPolicyQuery from '../../../../graphql/queries/ovalPolicy.gql';
3
3
  import cvesQuery from '../../../../graphql/queries/cves.gql';
4
+ import hostgroupsQuery from '../../../../graphql/queries/hostgroups.gql';
4
5
 
5
6
  const policyDetailMockFactory = mockFactory('ovalPolicy', ovalPolicyQuery);
6
7
  const cvesMockFactory = mockFactory('cves', cvesQuery);
8
+ const hostgroupsMockFactory = mockFactory('hostgroups', hostgroupsQuery);
7
9
 
8
- const ovalPolicy = {
10
+ export const ovalPolicy = {
11
+ __typename: 'ForemanOpenscap::OvalPolicy',
9
12
  id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsUG9saWN5LTM=',
10
13
  name: 'Third policy',
11
14
  period: 'weekly',
@@ -51,6 +54,20 @@ const cvesResult = {
51
54
  ],
52
55
  };
53
56
 
57
+ const hostgroupsResult = {
58
+ totalCount: 2,
59
+ nodes: [
60
+ {
61
+ id: 'MDE6SG9zdGdyb3VwLTQ=',
62
+ name: 'first hostgroup',
63
+ },
64
+ {
65
+ id: 'MDE6SG9zdGdyb3VwLTEy',
66
+ name: 'second hostgroup',
67
+ },
68
+ ],
69
+ };
70
+
54
71
  export const ovalPolicyId = 3;
55
72
 
56
73
  export const pushMock = jest.fn();
@@ -70,9 +87,28 @@ export const historyWithSearch = {
70
87
 
71
88
  export const policyDetailMock = policyDetailMockFactory(
72
89
  { id: ovalPolicy.id },
73
- ovalPolicy
90
+ ovalPolicy,
91
+ { currentUser: admin }
74
92
  );
93
+
94
+ export const policyUnauthorizedMock = policyDetailMockFactory(
95
+ { id: ovalPolicy.id },
96
+ ovalPolicy,
97
+ { currentUser: intruder }
98
+ );
99
+
75
100
  export const policyCvesMock = cvesMockFactory(
76
101
  { search: `oval_policy_id = ${ovalPolicyId}`, first: 5, last: 5 },
77
- cvesResult
102
+ cvesResult,
103
+ { currentUser: admin }
104
+ );
105
+ export const policyHostgroupsMock = hostgroupsMockFactory(
106
+ { search: `oval_policy_id = ${ovalPolicyId}`, first: 5, last: 5 },
107
+ hostgroupsResult,
108
+ { currentUser: admin }
109
+ );
110
+ export const policyHostgroupsDeniedMock = hostgroupsMockFactory(
111
+ { search: `oval_policy_id = ${ovalPolicyId}`, first: 5, last: 5 },
112
+ { totalCount: 0, nodes: [] },
113
+ { currentUser: intruder }
78
114
  );
@@ -12,17 +12,27 @@ import {
12
12
  resolvePath,
13
13
  } from '../../../../helpers/pathsHelper';
14
14
 
15
- import { withMockedProvider, tick, withRouter } from '../../../../testHelper';
15
+ import {
16
+ withRedux,
17
+ withMockedProvider,
18
+ tick,
19
+ withRouter,
20
+ } from '../../../../testHelper';
16
21
  import {
17
22
  policyDetailMock,
18
23
  historyMock,
19
24
  historyWithSearch,
20
25
  pushMock,
21
26
  policyCvesMock,
27
+ policyHostgroupsMock,
28
+ policyHostgroupsDeniedMock,
22
29
  ovalPolicyId,
30
+ policyUnauthorizedMock,
23
31
  } from './OvalPoliciesShow.fixtures';
24
32
 
25
- const TestComponent = withRouter(withMockedProvider(OvalPoliciesShow));
33
+ const TestComponent = withRedux(
34
+ withRouter(withMockedProvider(OvalPoliciesShow))
35
+ );
26
36
 
27
37
  describe('OvalPoliciesShow', () => {
28
38
  it('should load details by default and handle tab change', async () => {
@@ -36,7 +46,7 @@ describe('OvalPoliciesShow', () => {
36
46
  expect(screen.getByText('Loading')).toBeInTheDocument();
37
47
  await waitFor(tick);
38
48
  expect(screen.queryByText('Loading')).not.toBeInTheDocument();
39
- expect(screen.getByText('Third policy')).toBeInTheDocument();
49
+ expect(screen.getAllByText('Third policy').pop()).toBeInTheDocument();
40
50
  expect(screen.getByText('Weekly, on tuesday')).toBeInTheDocument();
41
51
  expect(screen.getByText('A very strict policy')).toBeInTheDocument();
42
52
  const activeTabHeader = container.querySelector(
@@ -67,6 +77,22 @@ describe('OvalPoliciesShow', () => {
67
77
  expect(screen.queryByText('Loading')).not.toBeInTheDocument();
68
78
  expect(screen.getByText('Weekly, on tuesday')).toBeInTheDocument();
69
79
  });
80
+ it('should not load the page when user does not have permissions', async () => {
81
+ render(
82
+ <TestComponent
83
+ history={historyMock}
84
+ match={{ params: { id: ovalPolicyId }, path: ovalPoliciesShowPath }}
85
+ mocks={policyUnauthorizedMock}
86
+ />
87
+ );
88
+ await waitFor(tick);
89
+ expect(screen.queryByText('Loading')).not.toBeInTheDocument();
90
+ expect(
91
+ screen.getByText(
92
+ 'You are not authorized to view the page. Request the following permissions from administrator: view_oval_policies.'
93
+ )
94
+ ).toBeInTheDocument();
95
+ });
70
96
  it('should load CVEs tab when specified in URL', async () => {
71
97
  const mocks = policyDetailMock.concat(policyCvesMock);
72
98
  render(
@@ -88,7 +114,7 @@ describe('OvalPoliciesShow', () => {
88
114
  it('should have button for scanning all hostgroups', async () => {
89
115
  const btnText = 'Scan All Hostgroups';
90
116
 
91
- const WithProvider = withMockedProvider(OvalPoliciesShow);
117
+ const WithProvider = withRedux(withMockedProvider(OvalPoliciesShow));
92
118
  const history = createMemoryHistory();
93
119
  history.push = jest.fn();
94
120
 
@@ -109,4 +135,38 @@ describe('OvalPoliciesShow', () => {
109
135
  '/job_invocations/new?feature=foreman_openscap_run_oval_scans&host_ids=hostgroup_id+%5E+%284+10+12+11%29&inputs%5Boval_policies%5D=3'
110
136
  );
111
137
  });
138
+ it('should load hostgroups tab when specified in URL', async () => {
139
+ const mocks = policyDetailMock.concat(policyHostgroupsMock);
140
+ render(
141
+ <TestComponent
142
+ history={historyWithSearch}
143
+ match={{
144
+ params: { id: ovalPolicyId, tab: 'hostgroups' },
145
+ path: ovalPoliciesShowPath,
146
+ }}
147
+ mocks={mocks}
148
+ />
149
+ );
150
+ expect(screen.getByText('Loading')).toBeInTheDocument();
151
+ await waitFor(tick);
152
+ await waitFor(tick);
153
+ expect(screen.queryByText('Loading')).not.toBeInTheDocument();
154
+ expect(screen.getByText('first hostgroup')).toBeInTheDocument();
155
+ });
156
+ it('should not show hostgroups for a user without permissions', async () => {
157
+ const mocks = policyDetailMock.concat(policyHostgroupsDeniedMock);
158
+ render(
159
+ <TestComponent
160
+ history={historyWithSearch}
161
+ match={{
162
+ params: { id: ovalPolicyId, tab: 'hostgroups' },
163
+ path: ovalPoliciesShowPath,
164
+ }}
165
+ mocks={mocks}
166
+ />
167
+ );
168
+ await waitFor(tick);
169
+ await waitFor(tick);
170
+ expect(screen.getByText('Permission denied')).toBeInTheDocument();
171
+ });
112
172
  });
@@ -1,8 +1,10 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { useQuery } from '@apollo/client';
4
+ import { useDispatch } from 'react-redux';
4
5
 
5
6
  import { translate as __ } from 'foremanReact/common/I18n';
7
+ import { showToast } from '../../../helpers/toastHelper';
6
8
 
7
9
  import OvalPoliciesShow from './OvalPoliciesShow';
8
10
  import { encodeId } from '../../../helpers/globalIdHelper';
@@ -24,6 +26,8 @@ const WrappedOvalPoliciesShow = props => {
24
26
  renameData={renameData}
25
27
  resultPath="ovalPolicy"
26
28
  emptyStateTitle={__('No OVAL Policy found')}
29
+ permissions={['view_oval_policies']}
30
+ showToast={showToast(useDispatch())}
27
31
  />
28
32
  );
29
33
  };
@@ -1,10 +1,14 @@
1
1
  import React from 'react';
2
2
  import OvalContentsIndex from './OvalContents/OvalContentsIndex';
3
+ import OvalContentsShow from './OvalContents/OvalContentsShow';
4
+ import OvalContentsNew from './OvalContents/OvalContentsNew';
3
5
  import OvalPoliciesIndex from './OvalPolicies/OvalPoliciesIndex';
4
6
  import OvalPoliciesShow from './OvalPolicies/OvalPoliciesShow';
5
7
 
6
8
  import {
7
9
  ovalContentsPath,
10
+ ovalContentsShowPath,
11
+ ovalContentsNewPath,
8
12
  ovalPoliciesPath,
9
13
  ovalPoliciesShowPath,
10
14
  } from '../helpers/pathsHelper';
@@ -15,6 +19,16 @@ export default [
15
19
  render: props => <OvalContentsIndex {...props} />,
16
20
  exact: true,
17
21
  },
22
+ {
23
+ path: ovalContentsNewPath,
24
+ render: props => <OvalContentsNew {...props} />,
25
+ exact: true,
26
+ },
27
+ {
28
+ path: ovalContentsShowPath,
29
+ render: props => <OvalContentsShow {...props} />,
30
+ exact: true,
31
+ },
18
32
  {
19
33
  path: ovalPoliciesPath,
20
34
  render: props => <OvalPoliciesIndex {...props} />,
@@ -1,8 +1,16 @@
1
1
  import React from 'react';
2
+ import { Provider } from 'react-redux';
3
+ import store from 'foremanReact/redux';
2
4
  import { MockedProvider } from '@apollo/react-testing';
3
5
  import { MemoryRouter } from 'react-router-dom';
4
6
  import { getForemanContext } from 'foremanReact/Root/Context/ForemanContext';
5
7
 
8
+ export const withRedux = Component => props => (
9
+ <Provider store={store}>
10
+ <Component {...props} />
11
+ </Provider>
12
+ );
13
+
6
14
  export const withRouter = Component => props => (
7
15
  <MemoryRouter>
8
16
  <Component {...props} />
@@ -24,7 +32,7 @@ export const withMockedProvider = Component => props => {
24
32
 
25
33
  return (
26
34
  <ForemanContext.Provider value={ctx}>
27
- <MockedProvider mocks={mocks} addTypename={false}>
35
+ <MockedProvider mocks={mocks}>
28
36
  <Component {...rest} />
29
37
  </MockedProvider>
30
38
  </ForemanContext.Provider>
@@ -40,10 +48,38 @@ export const historyMock = {
40
48
  },
41
49
  };
42
50
 
51
+ export const admin = {
52
+ __typename: 'User',
53
+ id: 'MDE6VXNlci00',
54
+ login: 'admin',
55
+ admin: true,
56
+ permissions: {
57
+ nodes: [],
58
+ },
59
+ };
60
+
61
+ export const userFactory = (login, permissions = []) => ({
62
+ __typename: 'User',
63
+ id: 'MDE6VXNlci01',
64
+ login,
65
+ admin: false,
66
+ permissions: {
67
+ nodes: permissions,
68
+ },
69
+ });
70
+
71
+ export const intruder = userFactory('intruder', [
72
+ {
73
+ __typename: 'Permission',
74
+ id: 'MDE6UGVybWlzc2lvbi0x',
75
+ name: 'view_architectures',
76
+ },
77
+ ]);
78
+
43
79
  export const mockFactory = (resultName, query) => (
44
80
  variables,
45
81
  modelResults,
46
- errors = []
82
+ { errors = [], currentUser = null } = {}
47
83
  ) => {
48
84
  const mock = {
49
85
  request: {
@@ -60,5 +96,9 @@ export const mockFactory = (resultName, query) => (
60
96
  if (errors.length !== 0) {
61
97
  mock.result.errors = errors;
62
98
  }
99
+
100
+ if (currentUser) {
101
+ mock.result.data.currentUser = currentUser;
102
+ }
63
103
  return [mock];
64
104
  };
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_openscap
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.3.1
4
+ version: 5.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - slukasik@redhat.com
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-21 00:00:00.000000000 Z
11
+ date: 2021-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -72,7 +72,11 @@ files:
72
72
  - app/controllers/policy_dashboard_controller.rb
73
73
  - app/controllers/scap_contents_controller.rb
74
74
  - app/controllers/tailoring_files_controller.rb
75
+ - app/graphql/mutations/oval_contents/delete.rb
76
+ - app/graphql/mutations/oval_policies/delete.rb
77
+ - app/graphql/mutations/oval_policies/update.rb
75
78
  - app/graphql/types/cve.rb
79
+ - app/graphql/types/oval_check.rb
76
80
  - app/graphql/types/oval_content.rb
77
81
  - app/graphql/types/oval_policy.rb
78
82
  - app/helpers/arf_report_dashboard_helper.rb
@@ -152,6 +156,7 @@ files:
152
156
  - app/views/api/v2/compliance/common/_org.json.rabl
153
157
  - app/views/api/v2/compliance/oval_contents/base.json.rabl
154
158
  - app/views/api/v2/compliance/oval_contents/create.json.rabl
159
+ - app/views/api/v2/compliance/oval_contents/destroy.json.rabl
155
160
  - app/views/api/v2/compliance/oval_contents/index.json.rabl
156
161
  - app/views/api/v2/compliance/oval_contents/show.json.rabl
157
162
  - app/views/api/v2/compliance/oval_contents/sync.json.rabl
@@ -300,6 +305,7 @@ files:
300
305
  - db/migrate/20201217130800_add_has_errata_to_cve.rb
301
306
  - db/migrate/20201217161511_add_url_to_oval_content.rb
302
307
  - db/migrate/20210409095625_add_oval_policy_reference_to_cve.rb
308
+ - db/migrate/20210819143316_drop_unused_tables.rb
303
309
  - db/seeds.d/75-job_templates.rb
304
310
  - db/seeds.d/openscap_feature.rb
305
311
  - db/seeds.d/openscap_policy_notification.rb
@@ -386,6 +392,8 @@ files:
386
392
  - test/functional/arf_reports_controller_test.rb
387
393
  - test/functional/openscap_proxies_controller_test.rb
388
394
  - test/functional/tailoring_files_controller_test.rb
395
+ - test/graphql/mutations/oval_policies/delete_mutation_test.rb
396
+ - test/graphql/queries/oval_content_query_test.rb
389
397
  - test/graphql/queries/oval_contents_query_test.rb
390
398
  - test/graphql/queries/oval_policies_query_test.rb
391
399
  - test/helpers/arf_report_dashboard_helper_test.rb
@@ -409,15 +417,21 @@ files:
409
417
  - test/unit/services/hostgroup_overrider_test.rb
410
418
  - test/unit/services/lookup_key_overrider_test.rb
411
419
  - test/unit/services/oval/cves_test.rb
420
+ - test/unit/services/oval/setup_check_test.rb
412
421
  - test/unit/services/oval/setup_test.rb
413
422
  - test/unit/services/report_dashboard/data_test.rb
414
423
  - test/unit/services/tailoring_files_proxy_check_test.rb
415
424
  - test/unit/tailoring_file_test.rb
425
+ - webpack/components/ConfirmModal.js
426
+ - webpack/components/ConfirmModal.scss
427
+ - webpack/components/EditableInput.js
428
+ - webpack/components/EditableInput.scss
416
429
  - webpack/components/EmptyState.js
417
430
  - webpack/components/IndexLayout.js
418
431
  - webpack/components/IndexLayout.scss
419
432
  - webpack/components/IndexTable/IndexTableHelper.js
420
433
  - webpack/components/IndexTable/index.js
434
+ - webpack/components/LinkButton.js
421
435
  - webpack/components/RuleSeverity/RuleSeverity.scss
422
436
  - webpack/components/RuleSeverity/RuleSeverity.test.js
423
437
  - webpack/components/RuleSeverity/__snapshots__/RuleSeverity.test.js.snap
@@ -427,32 +441,61 @@ files:
427
441
  - webpack/components/RuleSeverity/i_severity-med.svg
428
442
  - webpack/components/RuleSeverity/i_unknown.svg
429
443
  - webpack/components/RuleSeverity/index.js
444
+ - webpack/components/withDeleteModal.js
430
445
  - webpack/components/withLoading.js
431
446
  - webpack/global_index.js
447
+ - webpack/graphql/mutations/deleteOvalContent.gql
448
+ - webpack/graphql/mutations/deleteOvalPolicy.gql
449
+ - webpack/graphql/mutations/updateOvalPolicy.gql
450
+ - webpack/graphql/queries/currentUserAttributes.gql
432
451
  - webpack/graphql/queries/cves.gql
452
+ - webpack/graphql/queries/hostgroups.gql
453
+ - webpack/graphql/queries/ovalContent.gql
433
454
  - webpack/graphql/queries/ovalContents.gql
434
455
  - webpack/graphql/queries/ovalPolicies.gql
435
456
  - webpack/graphql/queries/ovalPolicy.gql
436
457
  - webpack/helpers/commonHelper.js
458
+ - webpack/helpers/formFieldsHelper.js
437
459
  - webpack/helpers/globalIdHelper.js
460
+ - webpack/helpers/mutationHelper.js
438
461
  - webpack/helpers/pageParamsHelper.js
439
462
  - webpack/helpers/pathsHelper.js
463
+ - webpack/helpers/permissionsHelper.js
440
464
  - webpack/helpers/tableHelper.js
465
+ - webpack/helpers/toastHelper.js
441
466
  - webpack/index.js
442
467
  - webpack/routes/OvalContents/OvalContentsIndex/OvalContentsIndex.js
443
468
  - webpack/routes/OvalContents/OvalContentsIndex/OvalContentsTable.js
469
+ - webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsDestroy.fixtures.js
470
+ - webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsDestroy.test.js
444
471
  - webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsIndex.fixtures.js
445
472
  - webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsIndex.test.js
446
473
  - webpack/routes/OvalContents/OvalContentsIndex/index.js
474
+ - webpack/routes/OvalContents/OvalContentsNew/OvalContentsNew.js
475
+ - webpack/routes/OvalContents/OvalContentsNew/OvalContentsNew.scss
476
+ - webpack/routes/OvalContents/OvalContentsNew/OvalContentsNewHelper.js
477
+ - webpack/routes/OvalContents/OvalContentsNew/__tests__/OvalContentsNew.test.js
478
+ - webpack/routes/OvalContents/OvalContentsNew/index.js
479
+ - webpack/routes/OvalContents/OvalContentsShow/OvalContentsShow.js
480
+ - webpack/routes/OvalContents/OvalContentsShow/OvalContentsShow.test.js
481
+ - webpack/routes/OvalContents/OvalContentsShow/OvalContentsShowHelper.js
482
+ - webpack/routes/OvalContents/OvalContentsShow/index.js
447
483
  - webpack/routes/OvalPolicies/OvalPoliciesIndex/OvalPoliciesIndex.js
448
484
  - webpack/routes/OvalPolicies/OvalPoliciesIndex/OvalPoliciesTable.js
485
+ - webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesDestroy.fixtures.js
486
+ - webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesDestroy.test.js
449
487
  - webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesIndex.fixtures.js
450
488
  - webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesIndex.test.js
451
489
  - webpack/routes/OvalPolicies/OvalPoliciesIndex/index.js
452
490
  - webpack/routes/OvalPolicies/OvalPoliciesShow/CvesTab.js
453
491
  - webpack/routes/OvalPolicies/OvalPoliciesShow/CvesTable.js
492
+ - webpack/routes/OvalPolicies/OvalPoliciesShow/DetailsTab.js
493
+ - webpack/routes/OvalPolicies/OvalPoliciesShow/HostgroupsTab.js
494
+ - webpack/routes/OvalPolicies/OvalPoliciesShow/HostgroupsTable.js
454
495
  - webpack/routes/OvalPolicies/OvalPoliciesShow/OvalPoliciesShow.js
455
496
  - webpack/routes/OvalPolicies/OvalPoliciesShow/OvalPoliciesShowHelper.js
497
+ - webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesEdit.fixtures.js
498
+ - webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesEdit.test.js
456
499
  - webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesShow.fixtures.js
457
500
  - webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesShow.test.js
458
501
  - webpack/routes/OvalPolicies/OvalPoliciesShow/index.js
@@ -500,7 +543,6 @@ test_files:
500
543
  - test/files/tailoring_files/ssg-firefox-ds-tailoring-2.xml
501
544
  - test/files/tailoring_files/ssg-firefox-ds-tailoring.xml
502
545
  - test/files/oval_contents/ansible-2.9.oval.xml.bz2
503
- - test/functional/api/v2/compliance/policies_controller_test.rb
504
546
  - test/functional/api/v2/compliance/scap_content_profiles_controller_test.rb
505
547
  - test/functional/api/v2/compliance/scap_contents_controller_test.rb
506
548
  - test/functional/api/v2/compliance/tailoring_files_controller_test.rb
@@ -508,6 +550,7 @@ test_files:
508
550
  - test/functional/api/v2/compliance/oval_contents_controller_test.rb
509
551
  - test/functional/api/v2/compliance/oval_policies_controller_test.rb
510
552
  - test/functional/api/v2/compliance/oval_reports_controller_test.rb
553
+ - test/functional/api/v2/compliance/policies_controller_test.rb
511
554
  - test/functional/api/v2/hosts_controller_test.rb
512
555
  - test/functional/arf_reports_controller_test.rb
513
556
  - test/functional/openscap_proxies_controller_test.rb
@@ -524,19 +567,22 @@ test_files:
524
567
  - test/unit/openscap_host_test.rb
525
568
  - test/unit/policy_mailer_test.rb
526
569
  - test/unit/scap_content_test.rb
527
- - test/unit/services/config_name_service_test.rb
528
- - test/unit/services/hostgroup_overrider_test.rb
529
- - test/unit/services/lookup_key_overrider_test.rb
530
570
  - test/unit/services/report_dashboard/data_test.rb
531
571
  - test/unit/services/tailoring_files_proxy_check_test.rb
532
572
  - test/unit/services/oval/cves_test.rb
533
573
  - test/unit/services/oval/setup_test.rb
574
+ - test/unit/services/oval/setup_check_test.rb
575
+ - test/unit/services/config_name_service_test.rb
576
+ - test/unit/services/lookup_key_overrider_test.rb
577
+ - test/unit/services/hostgroup_overrider_test.rb
534
578
  - test/unit/tailoring_file_test.rb
535
- - test/unit/policy_test.rb
536
579
  - test/unit/oval_host_test.rb
537
580
  - test/unit/oval_policy_test.rb
538
581
  - test/unit/oval_status_test.rb
582
+ - test/unit/policy_test.rb
539
583
  - test/fixtures/cve_fixtures.rb
540
584
  - test/graphql/queries/oval_contents_query_test.rb
541
585
  - test/graphql/queries/oval_policies_query_test.rb
586
+ - test/graphql/queries/oval_content_query_test.rb
587
+ - test/graphql/mutations/oval_policies/delete_mutation_test.rb
542
588
  - test/test_plugin_helper.rb