foreman_openscap 4.3.1 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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