Skip to content

Commit

Permalink
Adopt Jira
Browse files Browse the repository at this point in the history
  • Loading branch information
cnasikas committed Apr 22, 2020
1 parent 7d3d0f5 commit ef46abf
Show file tree
Hide file tree
Showing 20 changed files with 200 additions and 383 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export const withConnectorFlyout = <T extends ActionConnector>({
name="apiUrl"
value={apiUrl || ''} // Needed to prevent uncontrolled input error when value is undefined
data-test-subj="apiUrlFromInput"
placeholder="https://<instance>.service-now.com"
placeholder="https://<site-url>"
onChange={handleOnChangeActionConfig.bind(null, 'apiUrl')}
onBlur={handleOnBlurActionConfig.bind(null, 'apiUrl')}
/>
Expand Down
2 changes: 1 addition & 1 deletion x-pack/legacy/plugins/siem/public/lib/connectors/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { CasesConfigurationMapping } from '../../containers/case/configure/types

import { Connector } from './types';
import { connector as serviceNowConnectorConfig } from './servicenow/config';
import { connector as resilientConnectorConfig } from './resilient/config';
import { connector as resilientConnectorConfig } from './jira/config';

export const connectorsConfiguration: Record<string, Connector> = {
'.servicenow': serviceNowConnectorConfig,
Expand Down
2 changes: 1 addition & 1 deletion x-pack/legacy/plugins/siem/public/lib/connectors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
*/

export { getActionType as serviceNowActionType } from './servicenow';
export { getActionType as resilientActionType } from './resilient';
export { getActionType as resilientActionType } from './jira';
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@

import { Connector } from '../types';

import { RESILIENT_TITLE } from './translations';
import { JIRA_TITLE } from './translations';
import logo from './logo.svg';

export const connector: Connector = {
id: '.resilient',
name: RESILIENT_TITLE,
id: '.jira',
name: JIRA_TITLE,
logo,
enabled: true,
enabledInConfig: true,
Expand Down
83 changes: 83 additions & 0 deletions x-pack/legacy/plugins/siem/public/lib/connectors/jira/flyout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import React from 'react';
import {
EuiFieldText,
EuiFlexGroup,
EuiFlexItem,
EuiFormRow,
EuiFieldPassword,
EuiSpacer,
} from '@elastic/eui';

import * as i18n from './translations';
import { ConnectorFlyoutFormProps } from '../types';
import { JiraActionConnector } from './types';
import { withConnectorFlyout } from '../components/connector_flyout';

const JiraConnectorForm: React.FC<ConnectorFlyoutFormProps<JiraActionConnector>> = ({
errors,
action,
onChangeSecret,
onBlurSecret,
}) => {
const { email, apiToken } = action.secrets;
const isEmailInvalid: boolean = errors.email.length > 0 && email != null;
const isApiTokenInvalid: boolean = errors.apiToken.length > 0 && apiToken != null;

return (
<>
<EuiFlexGroup>
<EuiFlexItem>
<EuiFormRow
id="connector-jira-email"
fullWidth
error={errors.email}
isInvalid={isEmailInvalid}
label={i18n.EMAIL_LABEL}
>
<EuiFieldText
fullWidth
isInvalid={isEmailInvalid}
name="connector-jira-email"
value={email || ''} // Needed to prevent uncontrolled input error when value is undefined
data-test-subj="emailFromInput"
onChange={evt => onChangeSecret('email', evt.target.value)}
onBlur={() => onBlurSecret('email')}
/>
</EuiFormRow>
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="m" />
<EuiFlexGroup>
<EuiFlexItem>
<EuiFormRow
id="connector-jira-apiToken"
fullWidth
error={errors.apiToken}
isInvalid={isApiTokenInvalid}
label={i18n.API_TOKEN_LABEL}
>
<EuiFieldPassword
fullWidth
isInvalid={isApiTokenInvalid}
name="connector-jira-apiToken"
value={apiToken || ''} // Needed to prevent uncontrolled input error when value is undefined
data-test-subj="apiTokenFromInput"
onChange={evt => onChangeSecret('apiToken', evt.target.value)}
onBlur={() => onBlurSecret('apiToken')}
/>
</EuiFormRow>
</EuiFlexItem>
</EuiFlexGroup>
</>
);
};

export const JiraConnectorFlyout = withConnectorFlyout<JiraActionConnector>({
ConnectorFormComponent: JiraConnectorForm,
secretKeys: ['email', 'apiToken'],
});
48 changes: 48 additions & 0 deletions x-pack/legacy/plugins/siem/public/lib/connectors/jira/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import {
ValidationResult,
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
} from '../../../../../../../plugins/triggers_actions_ui/public/types';

import { connector } from './config';
import { createActionType } from '../utils';
import logo from './logo.svg';
import { JiraActionConnector } from './types';
import { JiraConnectorFlyout } from './flyout';
import * as i18n from './translations';

interface Errors {
email: string[];
apiToken: string[];
}

const validateConnector = (action: JiraActionConnector): ValidationResult => {
const errors: Errors = {
email: [],
apiToken: [],
};

if (!action.secrets.email) {
errors.email = [...errors.email, i18n.EMAIL_REQUIRED];
}

if (!action.secrets.apiToken) {
errors.apiToken = [...errors.apiToken, i18n.API_TOKEN_REQUIRED];
}

return { errors };
};

export const getActionType = createActionType({
id: connector.id,
iconClass: logo,
selectMessage: i18n.JIRA_DESC,
actionTypeTitle: connector.name,
validateConnector,
actionConnectorFields: JiraConnectorFlyout,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { i18n } from '@kbn/i18n';

export * from '../translations';

export const JIRA_DESC = i18n.translate('xpack.siem.case.connectors.jira.selectMessageText', {
defaultMessage: 'Push or update SIEM case data to a new issue in Jira',
});

export const JIRA_TITLE = i18n.translate('xpack.siem.case.connectors.jira.actionTypeTitle', {
defaultMessage: 'Jira',
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
/* eslint-disable @kbn/eslint/no-restricted-paths */

import {
ResilientPublicConfigurationType,
ResilientSecretConfigurationType,
} from '../../../../../../../plugins/actions/server/builtin_action_types/connectors/resilient/types';
JiraPublicConfigurationType,
JiraSecretConfigurationType,
} from '../../../../../../../plugins/actions/server/builtin_action_types/connectors/jira/types';

export interface ResilientActionConnector {
config: ResilientPublicConfigurationType;
secrets: ResilientSecretConfigurationType;
export interface JiraActionConnector {
config: JiraPublicConfigurationType;
secrets: JiraSecretConfigurationType;
}
Loading

0 comments on commit ef46abf

Please sign in to comment.