Plugins: Add Hide OAuth Forward config option (#36306)

* add prop

* add angular conf

* invert naming

* undo md changes

* fix wording

* y u fail 4 me

* refactor(datasourcesettings): rename hideForwardOAuthIdentityOption prop

* refactor(datasourcesettings): rename scope.hideForwardOAuthIdentityOption

* Update contribute/style-guides/e2e.md

Co-authored-by: achatterjee-grafana <70489351+achatterjee-grafana@users.noreply.github.com>

* feat(datasourcehttpsettings): add showForwardOAuthIdentityOption to angular wrappers & template

Co-authored-by: Jack Westbrook <jack.westbrook@gmail.com>
Co-authored-by: achatterjee-grafana <70489351+achatterjee-grafana@users.noreply.github.com>
This commit is contained in:
Will Browne 2021-08-20 15:53:54 +02:00 committed by GitHub
parent 5231660627
commit ae17cce316
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 70 additions and 47 deletions

View File

@ -23,20 +23,13 @@ Inspired by https://martinfowler.com/bliki/PageObject.html
Let's start with a simple [JSX](https://reactjs.org/docs/introducing-jsx.html) example containing a single input field that we want to populate during our E2E test:
```jsx
<input
className="gf-form-input login-form-input"
type="text"
/>
<input className="gf-form-input login-form-input" type="text" />
```
We _could_ target the field with a CSS selector like `.gf-form-input.login-form-input` but that would be brittle as style changes occur frequently. Furthermore there is nothing that signals to future developers that this input is part of an E2E test. At Grafana, we use `aria-label` attributes as our preferred way of defining selectors instead of [`data-*`](https://mdn.io/docs/Web/HTML/Global_attributes/data-*) as they also aid in [accessibility](https://mdn.io/docs/Learn/Accessibility/What_is_accessibility):
```jsx
<input
aria-label="Username input field"
className="gf-form-input login-form-input"
type="text"
/>
<input aria-label="Username input field" className="gf-form-input login-form-input" type="text" />
```
The next step is to create a `Page` representation in our E2E framework to glue the test with the real implementation using the `pageFactory` function. For that function we can supply a `url` and `selectors` like in the example below:
@ -45,7 +38,6 @@ The next step is to create a `Page` representation in our E2E framework to glue
export const Login = {
// Called via `Login.visit()`
url: '/login',
// Called via `Login.username()`
username: 'Username input field',
};
@ -67,11 +59,7 @@ Now that we have a `Page` called `Login` in our `Pages` const we can use that to
```jsx
import { selectors } from '@grafana/e2e-selectors';
<input
aria-label={selectors.pages.Login.username}
className="gf-form-input login-form-input"
type="text"
/>
<input aria-label={selectors.pages.Login.username} className="gf-form-input login-form-input" type="text" />;
```
The last step in our example is to use our `Login` page as part of a test.
@ -86,9 +74,7 @@ describe('Login test', () => {
e2e.pages.Login.visit();
// To prevent flaky tests, always do a `.should` on any selector that you expect to be in the DOM.
// Read more here: https://docs.cypress.io/guides/core-concepts/retry-ability.html#Commands-vs-assertions
e2e.pages.Login.username()
.should('be.visible')
.type('admin');
e2e.pages.Login.username().should('be.visible').type('admin');
});
});
```
@ -154,25 +140,28 @@ describe('List test', () => {
e2e.pages.DataSources.visit();
// To prevent flaky tests, always do a .should on any selector that you expect to be in the DOM.
// Read more here: https://docs.cypress.io/guides/core-concepts/retry-ability.html#Commands-vs-assertions
e2e.pages.DataSources.dataSources('B')
.should('be.visible')
.click();
e2e.pages.DataSources.dataSources('B').should('be.visible').click();
});
});
```
## Aria-Labels vs data-testid
Our selectors are set up to work with both aria-labels and data-testid attributes. Aria-labels help assistive technologies such as screenreaders identify interactive elements of a page for our users.
Our selectors are set up to work with both aria-labels and data-testid attributes. Aria-labels help assistive technologies such as screenreaders identify interactive elements of a page for our users.
A good example of a time to use an aria-label might be if you have a button with an X to close:
```
<button aria-label="close">X<button>
```
It might be clear visually that the X closes the modal, but audibly it would not be clear for example.
```
<button aria-label="close">Close<button>
```
The above example for example might read aloud to a user "Close, Close" or something similar.
The example might read aloud to a user as "Close, Close" or something similar.
However adding aria-labels to elements that are already clearly labeled or not interactive can be confusing and redundant for users with assistive technologies.
@ -185,16 +174,18 @@ In such cases rather than adding unnecessary aria-labels to components so as to
We have added support for this in our selectors, to use:
Prefix your selector string with "data-testid":
```typescript
export const Components = {
Login: {
openButton: "data-testid-open", // this would look for a data-testid
closeButton: "close-button" // this would look for an aria-label
openButton: 'data-testid-open', // this would look for a data-testid
closeButton: 'close-button', // this would look for an aria-label
},
};
```
and in your component, import the selectors and add the data test id:
```
<button data-testid={Selectors.Components.Login.openButton}>
```
```

View File

@ -120,7 +120,7 @@ Example use cases:
### Typography
For font family, font sizes and line heights use the variables under `theme.typography`.
For font family, font sizes and line heights use the variables under `theme.typography`.
#### Using `ThemeContext` directly

View File

@ -1,15 +1,18 @@
# Using this docker image
## User
The user will be `circleci`
The home directory will be `/home/circleci`
## Node
- node 14 is installed
- yarn is installed globally
- npm is installed globally
## Go
- Go is installed in `/usr/local/bin/go`
- golangci-lint is installed in `/usr/local/bin/golangci-lint`
- mage is installed in `/usr/local/bin/mage`
@ -17,17 +20,21 @@ The home directory will be `/home/circleci`
All of the above directories are in the path, so there is no need to specify fully qualified paths.
## Grafana
- Installed in `/home/circleci/src/grafana`
- `yarn install` has been run
## Integration/Release Testing
There are 4 previous versions pre-downloaded to /usr/local/grafana. These versions are:
1. 6.6.2
2. 6.5.3
3. 6.4.5
4. 6.3.7
To test, your CircleCI config will need a run section with something similar to the following
```
- run:
name: Setup Grafana (local install)
@ -39,15 +46,18 @@ To test, your CircleCI config will need a run section with something similar to
grafana-cli --version
```
# Building
To build, cd to `<srcroot>/packages/grafana-toolkit/docker/grafana-plugin-ci-e2e`
```
./build.sh
```
# Developing/Testing
To test, you should have docker-compose installed.
```
cd test
./start.sh

View File

@ -62,6 +62,7 @@ export const DataSourceHttpSettings: React.FC<HttpSettingsProps> = (props) => {
onChange,
showAccessOptions,
sigV4AuthToggleEnabled,
showForwardOAuthIdentityOption,
azureAuthSettings,
} = props;
let urlTooltip;
@ -250,6 +251,7 @@ export const DataSourceHttpSettings: React.FC<HttpSettingsProps> = (props) => {
<HttpProxySettings
dataSourceConfig={dataSourceConfig}
onChange={(jsonData) => onSettingsChange({ jsonData })}
showForwardOAuthIdentityOption={showForwardOAuthIdentityOption}
/>
)}
</div>

View File

@ -2,7 +2,11 @@ import React from 'react';
import { HttpSettingsBaseProps } from './types';
import { Switch } from '../Forms/Legacy/Switch/Switch';
export const HttpProxySettings: React.FC<HttpSettingsBaseProps> = ({ dataSourceConfig, onChange }) => {
export const HttpProxySettings: React.FC<HttpSettingsBaseProps> = ({
dataSourceConfig,
onChange,
showForwardOAuthIdentityOption = true,
}) => {
return (
<>
<div className="gf-form-inline">
@ -31,15 +35,19 @@ export const HttpProxySettings: React.FC<HttpSettingsBaseProps> = ({ dataSourceC
onChange={(event) => onChange({ ...dataSourceConfig.jsonData, tlsSkipVerify: event!.currentTarget.checked })}
/>
</div>
<div className="gf-form-inline">
<Switch
label="Forward OAuth Identity"
labelClass="width-13"
checked={dataSourceConfig.jsonData.oauthPassThru || false}
onChange={(event) => onChange({ ...dataSourceConfig.jsonData, oauthPassThru: event!.currentTarget.checked })}
tooltip="Forward the user's upstream OAuth identity to the data source (Their access token gets passed along)."
/>
</div>
{showForwardOAuthIdentityOption && (
<div className="gf-form-inline">
<Switch
label="Forward OAuth Identity"
labelClass="width-13"
checked={dataSourceConfig.jsonData.oauthPassThru || false}
onChange={(event) =>
onChange({ ...dataSourceConfig.jsonData, oauthPassThru: event!.currentTarget.checked })
}
tooltip="Forward the user's upstream OAuth identity to the data source (Their access token gets passed along)."
/>
</div>
)}
</>
);
};

View File

@ -11,6 +11,8 @@ export interface HttpSettingsBaseProps {
dataSourceConfig: DataSourceSettings<any, any>;
/** Callback for handling changes to the configuration object */
onChange: (config: DataSourceSettings) => void;
/** Show the Forward OAuth identity option */
showForwardOAuthIdentityOption?: boolean;
}
export interface HttpSettingsProps extends HttpSettingsBaseProps {

View File

@ -1,13 +1,15 @@
import { ArgsTable} from '@storybook/addon-docs/blocks';
import { DateTimePicker } from "./DateTimePicker";
import { ArgsTable } from '@storybook/addon-docs/blocks';
import { DateTimePicker } from './DateTimePicker';
# DateTimePicker
A component for selecting a date _and_ time.
### Usage
```tsx
import React, { useState} from 'react';
import {DateTime, dateTime} from '@grafana/data';
import React, { useState } from 'react';
import { DateTime, dateTime } from '@grafana/data';
import { DateTimePicker } from '@grafana/ui';
const [date, setDate] = useState<DateTime>(dateTime('2021-05-05 12:00:00'));
@ -15,4 +17,5 @@ return <DateTimePicker label="Date" date={date} onChange={setDate} />;
```
### Props
<ArgsTable of={DateTimePicker} />

View File

@ -166,6 +166,7 @@ export function registerAngularDirectives() {
'defaultUrl',
'showAccessOptions',
'dataSourceConfig',
'showForwardOAuthIdentityOption',
['onChange', { watchDepth: 'reference', wrapApply: true }],
]);
react2AngularDirective('folderPicker', FolderPicker, [

View File

@ -1 +1,7 @@
<datasource-http-settings-next on-change="onChange" dataSourceConfig="current" showAccessOptions="showAccessOption" defaultUrl="suggestUrl" />
<datasource-http-settings-next
on-change="onChange"
dataSourceConfig="current"
showAccessOptions="showAccessOption"
defaultUrl="suggestUrl"
showForwardOAuthIdentityOption="showForwardOAuthIdentityOption"
/>

View File

@ -6,6 +6,7 @@ coreModule.directive('datasourceHttpSettings', () => {
current: '=',
suggestUrl: '@',
noDirectAccess: '@',
showForwardOAuthIdentityOption: '@',
},
templateUrl: 'public/app/features/datasources/partials/http_settings_next.html',
link: {

View File

@ -1,12 +1,11 @@
# Annotation List Panel - Native Plugin
# Annotation List Panel - Native Plugin
This Annotations List panel is **included** with Grafana.
Using the annotations list panel, you can quickly collect, filter and access annotations for easy reference or referral.
Using the annotations list panel, you can quickly collect, filter and access annotations for easy reference or referral.
The annotations panel can be used to show annotations present within the panels on the current dashboard, or site-wide. Additional options include the ability to limit the list of annotations based on the current time range and the tags used on the annotations.
Read more about it here:
[http://docs.grafana.org/features/panels/annolist/](http://docs.grafana.org/features/panels/annolist/)

View File

@ -1,3 +1,3 @@
# Geomap Panel - Native Plugin
# Geomap Panel - Native Plugin
The Geomap is **included** with Grafana.