1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as React from 'react';
17 } from '@material-ui/core';
18 import * as CopyToClipboard from 'react-copy-to-clipboard';
19 import { ArvadosTheme } from '~/common/custom-theme';
20 import { withDialog } from '~/store/dialog/with-dialog';
21 import { WithDialogProps } from '~/store/dialog/with-dialog';
22 import { connect, DispatchProp } from 'react-redux';
27 } from '~/store/token-dialog/token-dialog-actions';
28 import { DefaultCodeSnippet } from '~/components/default-code-snippet/default-code-snippet';
29 import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions';
30 import { getNewExtraToken } from '~/store/auth/auth-action';
31 import { CopyIcon } from '~/components/icon/icon';
33 type CssRules = 'link' | 'paper' | 'button' | 'actionButton' | 'copyIcon' | 'inlineMonospaced';
35 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
37 color: theme.palette.primary.main,
38 textDecoration: 'none',
42 padding: theme.spacing.unit,
43 marginBottom: theme.spacing.unit * 2,
44 backgroundColor: theme.palette.grey["200"],
45 border: `1px solid ${theme.palette.grey["300"]}`
48 fontSize: '0.8125rem',
53 marginTop: theme.spacing.unit * 2,
54 marginBottom: theme.spacing.unit * 2,
55 marginRight: theme.spacing.unit * 2,
58 marginLeft: theme.spacing.unit,
59 color: theme.palette.grey["500"],
67 fontFamily: 'Monospace',
69 display: 'inline-block',
73 type TokenDialogProps = TokenDialogData & WithDialogProps<{}> & WithStyles<CssRules> & DispatchProp;
75 export class TokenDialogComponent extends React.Component<TokenDialogProps> {
76 onCopy = (message: string) => {
77 this.props.dispatch(snackbarActions.OPEN_SNACKBAR({
80 kind: SnackbarKind.SUCCESS
84 onGetNewToken = async () => {
85 const newToken = await this.props.dispatch<any>(getNewExtraToken());
87 this.props.dispatch(snackbarActions.OPEN_SNACKBAR({
88 message: 'New token retrieved',
90 kind: SnackbarKind.SUCCESS
93 this.props.dispatch(snackbarActions.OPEN_SNACKBAR({
94 message: 'Creating new tokens is not allowed',
96 kind: SnackbarKind.WARNING
101 getSnippet = ({ apiHost, token }: TokenDialogData) =>
102 `HISTIGNORE=$HISTIGNORE:'export ARVADOS_API_TOKEN=*'
103 export ARVADOS_API_TOKEN=${token}
104 export ARVADOS_API_HOST=${apiHost}
105 unset ARVADOS_API_HOST_INSECURE`
108 const { classes, open, closeDialog, ...data } = this.props;
112 onClose={closeDialog}
115 <DialogTitle>Get API Token</DialogTitle>
117 <Typography paragraph={true}>
118 The Arvados API token is a secret key that enables the Arvados SDKs to access Arvados with the proper permissions.
119 <Typography component='span'>
120 For more information see
121 <a href='http://doc.arvados.org/user/reference/api-tokens.html' target='blank' className={classes.link}>
122 Getting an API token.
126 <Typography paragraph={true}>
127 <Typography component='span'>
128 Your Arvados API host is: <Typography className={classes.inlineMonospaced} component='span'>{data.apiHost} {<Tooltip title="Copy to clipboard">
129 <span className={classes.copyIcon}>
130 <CopyToClipboard text={data.apiHost} onCopy={() => this.onCopy("API host copied")}>
137 <Typography component='span'>
138 Your token is: <Typography className={classes.inlineMonospaced} component='span'>{data.token} {<Tooltip title="Copy to clipboard">
139 <span className={classes.copyIcon}>
140 <CopyToClipboard text={data.token} onCopy={() => this.onCopy("Token copied")}>
147 <Typography component='span'>
148 { data.tokenExpiration
149 ? `Expires at: ${data.tokenExpiration.toLocaleString()}`
150 : `This token does not have an expiration date`
154 { this.props.canCreateNewTokens && <Button
155 onClick={() => this.onGetNewToken()}
159 className={classes.actionButton}
163 <Typography paragraph={true}>
164 Paste the following lines at a shell prompt to set up the necessary environment for Arvados SDKs to authenticate to your account.
166 <DefaultCodeSnippet lines={[this.getSnippet(data)]} />
167 <CopyToClipboard text={this.getSnippet(data)} onCopy={() => this.onCopy('Shell code block copied')}>
172 className={classes.actionButton}
179 <a href='http://doc.arvados.org/user/reference/api-tokens.html' target='blank' className={classes.link}>virtual machines</a>
180 do this for you automatically. This setup is needed only when you use the API remotely (e.g., from your own workstation).
184 <Button onClick={closeDialog} className={classes.button} color="primary">CLOSE</Button>
190 export const TokenDialog =
192 connect(getTokenDialogData)(
193 withDialog(TOKEN_DIALOG_NAME)(TokenDialogComponent)));