Skip to content
Snippets Groups Projects
Unverified Commit 3135220d authored by Alexander Turinske's avatar Alexander Turinske
Browse files

Create threat monitoring alert details page

- create threat monitoring alert details route
- use shared alert_details code
- update page attribute for alert management
- temporarily disable threat monitoring alert details page
  alert status update
- add tests
parent 1206515e
No related branches found
No related tags found
No related merge requests found
Showing
with 144 additions and 7 deletions
Loading
Loading
@@ -83,6 +83,9 @@ export default {
alertId: {
default: '',
},
isThreatMonitoringPage: {
default: false,
},
projectId: {
default: '',
},
Loading
Loading
@@ -364,7 +367,11 @@ export default {
</alert-summary-row>
<alert-details-table :alert="alert" :loading="loading" />
</gl-tab>
<gl-tab :data-testid="$options.tabsConfig[1].id" :title="$options.tabsConfig[1].title">
<gl-tab
v-if="isThreatMonitoringPage"
:data-testid="$options.tabsConfig[1].id"
:title="$options.tabsConfig[1].title"
>
<alert-metrics :dashboard-url="alert.metricsDashboardUrl" />
</gl-tab>
<gl-tab :data-testid="$options.tabsConfig[2].id" :title="$options.tabsConfig[2].title">
Loading
Loading
Loading
Loading
@@ -19,6 +19,10 @@ export default {
projectId: {
default: '',
},
// TODO remove this limitation in https://gitlab.com/gitlab-org/gitlab/-/issues/296717
isThreatMonitoringPage: {
default: false,
},
},
props: {
alert: {
Loading
Loading
@@ -62,6 +66,7 @@ export default {
@alert-error="$emit('alert-error', $event)"
/>
<sidebar-status
v-if="!isThreatMonitoringPage"
:project-path="projectPath"
:alert="alert"
@toggle-sidebar="$emit('toggle-sidebar')"
Loading
Loading
Loading
Loading
@@ -6,13 +6,13 @@ import createDefaultClient from '~/lib/graphql';
import AlertDetails from './components/alert_details.vue';
import sidebarStatusQuery from './graphql/queries/alert_sidebar_status.query.graphql';
import createRouter from './router';
import { DEFAULT_PAGE, PAGE_CONFIG } from './constants';
import { PAGE_CONFIG } from './constants';
 
Vue.use(VueApollo);
 
export default (selector) => {
const domEl = document.querySelector(selector);
const { alertId, projectPath, projectIssuesPath, projectId, page = DEFAULT_PAGE } = domEl.dataset;
const { alertId, projectPath, projectIssuesPath, projectId, page } = domEl.dataset;
const router = createRouter();
 
const resolvers = {
Loading
Loading
@@ -52,16 +52,19 @@ export default (selector) => {
const provide = {
projectPath,
alertId,
page,
projectIssuesPath,
projectId,
};
 
if (page === DEFAULT_PAGE) {
if (page === 'OPERATIONS') {
const { TRACK_ALERTS_DETAILS_VIEWS_OPTIONS, TRACK_ALERT_STATUS_UPDATE_OPTIONS } = PAGE_CONFIG[
page
];
provide.trackAlertsDetailsViewsOptions = TRACK_ALERTS_DETAILS_VIEWS_OPTIONS;
provide.trackAlertStatusUpdateOptions = TRACK_ALERT_STATUS_UPDATE_OPTIONS;
} else {
provide.isThreatMonitoringPage = true;
}
 
// eslint-disable-next-line no-new
Loading
Loading
Loading
Loading
@@ -20,7 +20,8 @@ def alert_management_detail_data(project, alert_id)
'alert-id' => alert_id,
'project-path' => project.full_path,
'project-id' => project.id,
'project-issues-path' => project_issues_path(project)
'project-issues-path' => project_issues_path(project),
'page' => 'OPERATIONS'
}
end
 
Loading
Loading
import AlertDetails from '~/vue_shared/alert_details';
AlertDetails('#js-alert_details');
Loading
Loading
@@ -12,8 +12,9 @@ import {
import produce from 'immer';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import { convertToSnakeCase } from '~/lib/utils/text_utility';
import { joinPaths, visitUrl } from '~/lib/utils/url_utility';
import getAlertsQuery from '~/graphql_shared/queries/get_alerts.query.graphql';
import { DEFAULT_FILTERS, FIELDS, MESSAGES, PAGE_SIZE, STATUSES, DOMAIN } from './constants';
import { CSS, DEFAULT_FILTERS, FIELDS, MESSAGES, PAGE_SIZE, STATUSES, DOMAIN } from './constants';
import AlertFilters from './alert_filters.vue';
import AlertStatus from './alert_status.vue';
 
Loading
Loading
@@ -129,6 +130,15 @@ export default {
handleStatusUpdate() {
this.$apollo.queries.alerts.refetch();
},
navigateToAlertDetails({ iid }) {
return visitUrl(joinPaths(window.location.pathname, 'alerts', iid));
},
tbodyTrClass(item) {
return {
[CSS.tbodyTrClass]: !this.loading && !this.isEmpty,
'new-alert': item?.isNew,
};
},
},
};
</script>
Loading
Loading
@@ -164,10 +174,12 @@ export default {
:sort-direction="sortDirection"
:sort-desc.sync="sortDesc"
:sort-by.sync="sortBy"
:tbody-tr-class="tbodyTrClass"
thead-class="gl-border-b-solid gl-border-b-1 gl-border-b-gray-100"
sort-icon-left
responsive
show-empty
@row-clicked="navigateToAlertDetails"
@sort-changed="fetchSortedData"
>
<template #cell(startedAt)="{ item }">
Loading
Loading
Loading
Loading
@@ -20,6 +20,10 @@ export const STATUSES = {
IGNORED: s__('ThreatMonitoring|Dismissed'),
};
 
export const CSS = {
tbodyTrClass: 'gl-border-1 gl-border-t-solid gl-border-gray-100 gl-hover-cursor-pointer gl-hover-bg-blue-50 gl-hover-border-b-solid gl-hover-border-blue-200',
};
export const FIELDS = [
{
key: 'startedAt',
Loading
Loading
Loading
Loading
@@ -9,6 +9,10 @@ class ThreatMonitoringController < Projects::ApplicationController
 
feature_category :web_firewall
 
def alert_details
@alert_id = params[:id]
end
def edit
@environment = project.environments.find(params[:environment_id])
@policy_name = params[:id]
Loading
Loading
Loading
Loading
@@ -179,6 +179,7 @@ def sidebar_security_paths
projects/threat_monitoring#show
projects/threat_monitoring#new
projects/threat_monitoring#edit
projects/threat_monitoring#alert_details
projects/audit_events#index
]
end
Loading
Loading
# frozen_string_literal: true
 
module PolicyHelper
def threat_monitoring_alert_details_data(project, alert_id)
{
'alert-id' => alert_id,
'project-path' => project.full_path,
'project-id' => project.id,
'project-issues-path' => project_issues_path(project),
'page' => 'THREAT_MONITORING'
}
end
def policy_details(project, policy = nil, environment = nil)
return unless project
 
Loading
Loading
- add_to_breadcrumbs s_('ThreatMonitoring|Threat Monitoring'), project_threat_monitoring_path(@project)
- page_title s_('ThreatMonitoring|Alert Details')
#js-alert_details{ data: threat_monitoring_alert_details_data(@project, @alert_id) }
Loading
Loading
@@ -40,6 +40,7 @@
resources :subscriptions, only: [:create, :destroy]
 
resource :threat_monitoring, only: [:show], controller: :threat_monitoring do
get '/alerts/:id', to: 'threat_monitoring#alert_details'
resources :policies, only: [:new, :edit], controller: :threat_monitoring
end
 
Loading
Loading
Loading
Loading
@@ -235,4 +235,67 @@
end
end
end
describe 'GET threat monitoring alerts' do
subject { get :alert_details, params: { id: '5' } }
context 'with authorized user' do
before do
project.add_developer(user)
sign_in(user)
end
context 'when feature is available' do
before do
stub_licensed_features(threat_monitoring: true)
end
it 'renders the show template' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:alert_details)
end
end
context 'when feature is not available' do
before do
stub_licensed_features(threat_monitoring: false)
end
it 'returns 404' do
subject
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
context 'with unauthorized user' do
before do
sign_in(user)
end
context 'when feature is available' do
before do
stub_licensed_features(threat_monitoring: true)
end
it 'returns 404' do
subject
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
context 'with anonymous user' do
it 'returns 302' do
subject
expect(response).to have_gitlab_http_status(:found)
expect(response).to redirect_to(new_user_session_path)
end
end
end
end
Loading
Loading
@@ -56,4 +56,21 @@
end
end
end
describe '#policy_alert_details' do
let(:alert) { create(:alert_management_alert, project: project) }
context 'when a new alert is created' do
subject { helper.threat_monitoring_alert_details_data(project, alert.id) }
it 'returns expected policy data' do
expect(subject).to match({
'alert-id' => alert.id,
'project-path' => project.full_path,
'project-id' => project.id,
'project-issues-path' => project_issues_path(project),
'page' => 'THREAT_MONITORING'
})
end
end
end
end
Loading
Loading
@@ -113,7 +113,8 @@
'alert-id' => alert_id,
'project-path' => project_path,
'project-id' => project_id,
'project-issues-path' => issues_path
'project-issues-path' => issues_path,
'page' => 'OPERATIONS'
)
end
end
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment