diff --git a/dev/custom.ini b/dev/custom.ini index 44928215b..18e58ab91 100644 --- a/dev/custom.ini +++ b/dev/custom.ini @@ -799,6 +799,7 @@ homepage=true topnav=true multi-http=true synthetics-scenes=true +synthetics-oauth2=true [navigation.app_standalone_pages] # WORKS diff --git a/src/components/http/HttpSettings.tsx b/src/components/http/HttpSettings.tsx index 7e5217736..f1716fec4 100644 --- a/src/components/http/HttpSettings.tsx +++ b/src/components/http/HttpSettings.tsx @@ -17,7 +17,7 @@ import { } from '@grafana/ui'; import { css } from '@emotion/css'; import { useFormContext, Controller, useFieldArray } from 'react-hook-form'; -import { HttpVersion, CheckType, HttpRegexValidationType, HttpMethod } from 'types'; +import { HttpVersion, CheckType, HttpRegexValidationType, HttpMethod, FeatureName } from 'types'; import { Collapse } from 'components/Collapse'; import { HTTP_COMPRESSION_ALGO_OPTIONS, @@ -33,6 +33,7 @@ import { NameValueInput } from 'components/NameValueInput'; import { validateBearerToken, validateHTTPBody, validateHTTPHeaderName, validateHTTPHeaderValue } from 'validation'; import { GrafanaTheme2 } from '@grafana/data'; import { HorizontalCheckboxField } from 'components/HorizonalCheckboxField'; +import { useFeatureFlag } from 'hooks/useFeatureFlag'; const httpVersionOptions = [ { @@ -114,6 +115,8 @@ const generateValidStatusCodes = () => { const validStatusCodes = generateValidStatusCodes(); const REGEX_FIELD_NAME = 'settings.http.regexValidations'; +const SCOPES_FIELD_NAME = 'settings.http.oauth2.scopes'; +const ENDPOINT_PARAMS_FIELD_NAME = 'settings.http.oauth2.endpointParams'; const getStyles = (theme: GrafanaTheme2) => ({ validationGroup: css` @@ -164,11 +167,24 @@ export const HttpSettingsForm = ({ isEditor }: Props) => { const bearerToken = watch('settings.http.bearerToken'); const basicAuth = watch('settings.http.basicAuth'); + const oauth2 = watch('settings.http.oauth2'); const [includeBearerToken, setIncludeBearerToken] = useState(Boolean(bearerToken)); + const [includeOauth2, setIncludeOauth2] = useState(Boolean(oauth2)); const [includeBasicAuth, setIncludeBasicAuth] = useState(Boolean(basicAuth)); + const { + fields: scopesFields, + append: appendScope, + remove: removeScope, + } = useFieldArray({ control, name: SCOPES_FIELD_NAME }); + const { + fields: endpointParamFields, + append: appendEndpointParam, + remove: removeEndpointParam, + } = useFieldArray({ control, name: ENDPOINT_PARAMS_FIELD_NAME }); const { fields, append, remove } = useFieldArray({ control, name: REGEX_FIELD_NAME }); const styles = useStyles2(getStyles); + const { isEnabled: oauth2Enabled } = useFeatureFlag(FeatureName.Oauth2); return ( @@ -318,7 +334,127 @@ export const HttpSettingsForm = ({ isEditor }: Props) => { )} + {oauth2Enabled && ( + + setIncludeOauth2(!includeOauth2)} + /> + {includeOauth2 && ( + + + + + + + + + + + + + {endpointParamFields.map((field, index) => { + return ( + + + + + + + + + + removeEndpointParam(index)} /> + + ); + })} + + + + + + + {scopesFields.map((field, index) => { + return ( + + + removeScope(index)} /> + + ); + })} + + + + + + )} + + )} + setShowValidation(!showValidation)} diff --git a/src/types.ts b/src/types.ts index eb998b3e7..797147967 100644 --- a/src/types.ts +++ b/src/types.ts @@ -183,6 +183,7 @@ export interface HttpSettings { // Authentication bearerToken?: string; basicAuth?: BasicAuth; + oauth2Config?: Oauth2Config; // validations failIfSSL?: boolean; @@ -193,10 +194,19 @@ export interface HttpSettings { failIfBodyNotMatchesRegexp?: string[]; failIfHeaderMatchesRegexp?: HeaderMatch[]; failIfHeaderNotMatchesRegexp?: HeaderMatch[]; - cacheBustingQueryParamName?: string; } +export interface Oauth2Config { + clientId: string; + clientSecret: string; + tokenURL: string; + scopes?: string[]; + endpointParams?: Label[]; + // tlsConfig: TLSConfig; + // proxyUrl: string; +} + interface HttpHeaderFormValue { name: string; value: string; @@ -525,6 +535,7 @@ export enum FeatureName { UnifiedAlerting = 'ngalert', MultiHttp = 'multi-http', Scenes = 'synthetics-scenes', + Oauth2 = 'synthetics-oauth2', } export interface UsageValues {