Skip to content

Commit

Permalink
🪟🎉 Connector builder: Session token and oauth authentication (#20712)
Browse files Browse the repository at this point in the history
* session token and oauth authentication

* fill in session token variable

* typos

* make sure validation error does not go away
  • Loading branch information
Joe Reuter authored Dec 22, 2022
1 parent 750c383 commit fca9305
Show file tree
Hide file tree
Showing 6 changed files with 365 additions and 70 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import { BuilderCard } from "./BuilderCard";
import { BuilderField } from "./BuilderField";
import { BuilderOneOf } from "./BuilderOneOf";
import { BuilderOptional } from "./BuilderOptional";
import { KeyValueListField } from "./KeyValueListField";
import { UserInputField } from "./UserInputField";

export const AuthenticationSection: React.FC = () => {
return (
<BuilderCard>
<BuilderOneOf
path="global.authenticator"
label="Authentication"
tooltip="Authentication method to use for requests sent to the API"
options={[
{ label: "No Auth", typeValue: "NoAuth" },
{
label: "API Key",
typeValue: "ApiKeyAuthenticator",
default: {
api_token: "{{ config['api_key'] }}",
header: "",
},
children: (
<>
<BuilderField
type="string"
path="global.authenticator.header"
label="Header"
tooltip="HTTP header which should be set to the API Key"
/>
<UserInputField
label="API Key"
tooltip="The API key issued by the service. Fill it in in the user inputs"
/>
</>
),
},
{
label: "Bearer",
typeValue: "BearerAuthenticator",
default: {
api_token: "{{ config['api_key'] }}",
},
children: (
<UserInputField
label="API Key"
tooltip="The API key issued by the service. Fill it in in the user inputs"
/>
),
},
{
label: "Basic HTTP",
typeValue: "BasicHttpAuthenticator",
default: {
username: "{{ config['username'] }}",
password: "{{ config['password'] }}",
},
children: (
<>
<UserInputField label="Username" tooltip="The username for the login. Fill it in in the user inputs" />
<UserInputField label="Password" tooltip="The password for the login. Fill it in in the user inputs" />
</>
),
},
{
label: "OAuth",
typeValue: "OAuthAuthenticator",
default: {
client_id: "{{ config['client_id'] }}",
client_secret: "{{ config['client_secret'] }}",
refresh_token: "{{ config['client_refresh_token'] }}",
refresh_request_body: [],
token_refresh_endpoint: "",
},
children: (
<>
<BuilderField
type="string"
path="global.authenticator.token_refresh_endpoint"
label="Token refresh endpoint"
tooltip="The URL to call to obtain a new access token"
/>
<UserInputField label="Client ID" tooltip="The OAuth client ID" />
<UserInputField label="Client secret" tooltip="The OAuth client secret" />
<UserInputField label="Refresh token" tooltip="The OAuth refresh token" />
<BuilderOptional>
<BuilderField
type="array"
path="global.authenticator.scopes"
optional
label="Scopes"
tooltip="Scopes to request"
/>
<BuilderField
type="array"
path="global.authenticator.token_expiry_date_format"
optional
label="Token expiry date format"
tooltip="The format of the expiry date of the access token as obtained from the refresh endpoint"
/>
<BuilderField
type="string"
path="global.authenticator.expires_in_name"
optional
label="Token expiry property name"
tooltip="The name of the property which contains the token exipiry date in the response from the token refresh endpoint"
/>
<BuilderField
type="string"
path="global.authenticator.access_token_name"
optional
label="Access token property name"
tooltip="The name of the property which contains the access token in the response from the token refresh endpoint"
/>
<BuilderField
type="string"
path="global.authenticator.grant_type"
optional
label="Grant type"
tooltip="The grant type to request for access_token"
/>
<KeyValueListField
path="global.authenticator.refresh_request_body"
label="Request Parameters"
tooltip="The request body to send in the refresh request"
/>
</BuilderOptional>
</>
),
},
{
label: "Session token",
typeValue: "SessionTokenAuthenticator",
default: {
username: "{{ config['username'] }}",
password: "{{ config['password'] }}",
session_token: "{{ config['session_token'] }}",
},
children: (
<>
<BuilderField
type="string"
path="global.authenticator.header"
label="Header"
tooltip="Specific HTTP header of source API for providing session token"
/>
<BuilderField
type="string"
path="global.authenticator.session_token_response_key"
label="Session token response key"
tooltip="Key for retrieving session token from api response"
/>
<BuilderField
type="string"
path="global.authenticator.login_url"
label="Login url"
tooltip="Url for getting a specific session token"
/>
<BuilderField
type="string"
path="global.authenticator.validate_session_url"
label="Validate session url"
tooltip="Url to validate passed session token"
/>
<UserInputField label="Username" tooltip="The username" />
<UserInputField label="Password" tooltip="The password" />
<UserInputField
label="Session token"
tooltip="Session token generated by user (if provided username and password are not required)"
/>
</>
),
},
]}
/>
</BuilderCard>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
@use "scss/variables";
@use "scss/colors";
@use "scss/mixins";

.wrapper {
display: flex;
flex-direction: column;
align-items: flex-start;
border-top: variables.$border-thin solid colors.$grey-100;
gap: variables.$spacing-lg;
}

.container {
padding-left: variables.$spacing-xl;
display: flex;
flex-direction: column;
align-items: stretch;
align-self: stretch;
gap: variables.$spacing-lg;
}

.label {
cursor: pointer;
background: none;
border: none;
display: flex;
gap: variables.$spacing-sm;
margin-top: variables.$spacing-lg;
align-items: center;

&.closed {
color: colors.$grey-400;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { faAngleDown, faAngleRight } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import classNames from "classnames";
import React, { useState } from "react";
import { FormattedMessage } from "react-intl";

import styles from "./BuilderOptional.module.scss";

export const BuilderOptional: React.FC<React.PropsWithChildren<unknown>> = ({ children }) => {
const [isOpen, setIsOpen] = useState(false);
return (
<div className={styles.wrapper}>
<button
onClick={() => {
setIsOpen(!isOpen);
}}
className={classNames(styles.label, { [styles.closed]: !isOpen })}
>
{isOpen ? <FontAwesomeIcon icon={faAngleDown} /> : <FontAwesomeIcon icon={faAngleRight} />}
<FormattedMessage id="connectorBuilder.optionalFieldsLabel" />
</button>
{isOpen && <div className={styles.container}>{children}</div>}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { useIntl } from "react-intl";

import { AuthenticationSection } from "./AuthenticationSection";
import { BuilderCard } from "./BuilderCard";
import { BuilderConfigView } from "./BuilderConfigView";
import { BuilderField } from "./BuilderField";
import { BuilderOneOf } from "./BuilderOneOf";
import { BuilderTitle } from "./BuilderTitle";
import styles from "./GlobalConfigView.module.scss";
import { UserInputField } from "./UserInputField";

export const GlobalConfigView: React.FC = () => {
const { formatMessage } = useIntl();
Expand All @@ -18,70 +17,7 @@ export const GlobalConfigView: React.FC = () => {
<BuilderCard className={styles.content}>
<BuilderField type="string" path="global.urlBase" label="API URL" tooltip="Base URL of the source API" />
</BuilderCard>
<BuilderCard>
<BuilderOneOf
path="global.authenticator"
label="Authentication"
tooltip="Authentication method to use for requests sent to the API"
options={[
{ label: "No Auth", typeValue: "NoAuth" },
{
label: "API Key",
typeValue: "ApiKeyAuthenticator",
default: {
api_token: "{{ config['api_key'] }}",
},
children: (
<>
<BuilderField
type="string"
path="global.authenticator.header"
label="Header"
tooltip="HTTP header which should be set to the API Key"
/>
<UserInputField
label="API Key"
tooltip="The API key issued by the service. Fill it in in the user inputs"
/>
</>
),
},
{
label: "Bearer",
typeValue: "BearerAuthenticator",
default: {
api_token: "{{ config['api_key'] }}",
},
children: (
<UserInputField
label="API Key"
tooltip="The API key issued by the service. Fill it in in the user inputs"
/>
),
},
{
label: "Basic HTTP",
typeValue: "BasicHttpAuthenticator",
default: {
username: "{{ config['username'] }}",
password: "{{ config['password'] }}",
},
children: (
<>
<UserInputField
label="Username"
tooltip="The username for the login. Fill it in in the user inputs"
/>
<UserInputField
label="Password"
tooltip="The password for the login. Fill it in in the user inputs"
/>
</>
),
},
]}
/>
</BuilderCard>
<AuthenticationSection />
</BuilderConfigView>
);
};
Loading

0 comments on commit fca9305

Please sign in to comment.