Skip to content

Commit 400a4da

Browse files
authored
Improve sandbox workflow and go directly to 'Copy Login Command' page (#2568)
* Improve sandbox workflow and go directly to 'Copy Login Command' page Signed-off-by: Denis Golovin dgolovin@redhat.com * Fix eslint errors Signed-off-by: Denis Golovin dgolovin@redhat.com Signed-off-by: Denis Golovin dgolovin@redhat.com
1 parent daea6a1 commit 400a4da

File tree

4 files changed

+56
-12
lines changed

4 files changed

+56
-12
lines changed

src/openshift/cluster.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,19 @@ export class Cluster extends OpenShiftItem {
351351
}
352352

353353
@vsCommand('openshift.explorer.login.clipboard')
354+
static async loginUsingClipboardToken(apiEndpointUrl: string, oauthRequestTokenUrl: string): Promise<string | null> {
355+
const clipboard = await Cluster.readFromClipboard();
356+
if(!clipboard) {
357+
const choice = await window.showErrorMessage('Cannot parse token in clipboard. Please click `Get token` button below, copy token into clipboard and press `Login to Sandbox` button again.',
358+
'Get token');
359+
if (choice === 'Get token') {
360+
await commands.executeCommand('vscode.open', Uri.parse(oauthRequestTokenUrl));
361+
}
362+
return;
363+
}
364+
return Cluster.tokenLogin(apiEndpointUrl, true, clipboard);
365+
}
366+
354367
static async loginUsingClipboardInfo(dashboardUrl: string): Promise<string | null> {
355368
const clipboard = await Cluster.readFromClipboard();
356369
if(!Cluster.ocLoginCommandMatches(clipboard)) {

src/openshift/sandbox.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ export interface VerificationCodeResponse{
4343
json: SBResponseData;
4444
}
4545

46+
export const OAUTH_SERVER_INFO_PATH = '.well-known/oauth-authorization-server';
47+
48+
export interface OauthServerInfo {
49+
issuer: string;
50+
authorization_endpoint: string;
51+
token_endpoint: string;
52+
scopes_supported: string[];
53+
response_types_supported: string[];
54+
grant_types_supported: string[];
55+
code_challenge_methods_supported: string[];
56+
}
57+
4658
export function getSandboxAPIUrl(): string {
4759
return workspace.getConfiguration('openshiftConnector').get('sandboxApiHostUrl');
4860
}
@@ -56,6 +68,7 @@ export interface SandboxAPI {
5668
signUp(token: string): Promise<boolean>;
5769
requestVerificationCode(token: string, areaCode: string, phoneNumber: string): Promise<VerificationCodeResponse>;
5870
validateVerificationCode(token: string, code: string): Promise<boolean>;
71+
getOauthServerInfo(apiEndpointUrl: string): Promise<OauthServerInfo>;
5972
}
6073

6174
export async function getSignUpStatus(token: string): Promise<SBSignupResponse | undefined> {
@@ -112,11 +125,21 @@ export async function validateVerificationCode(token: string, code: string): Pro
112125
return validationRequestResponse.ok;
113126
}
114127

128+
export async function getOauthServerInfo(apiEndpointUrl: string): Promise<OauthServerInfo> {
129+
const oauthServerInfoResponse = await fetch(`${apiEndpointUrl}/${OAUTH_SERVER_INFO_PATH}`, {
130+
method: 'GET',
131+
timeout: getSandboxAPITimeout()
132+
});
133+
const oauthInfoText = await oauthServerInfoResponse.text();
134+
return (oauthInfoText ? JSON.parse(oauthInfoText) : {}) as OauthServerInfo;
135+
}
136+
115137
export function createSandboxAPI(): SandboxAPI {
116138
return {
117139
getSignUpStatus,
118140
signUp,
119141
requestVerificationCode,
120-
validateVerificationCode
142+
validateVerificationCode,
143+
getOauthServerInfo
121144
};
122145
}

src/webview/cluster/app/sandboxView.tsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ export default function addSandboxView(props): JSX.Element {
6060
action: 'sandboxPageDetectAuthSession',
6161
statusInfo: '',
6262
consoleDashboard: '',
63+
apiEndpoint: '',
64+
oauthTokenEndpoint: '',
6365
errorCode: undefined
6466
});
6567

@@ -150,6 +152,8 @@ export default function addSandboxView(props): JSX.Element {
150152
action: currentState.action,
151153
consoleDashboard: currentState.consoleDashboard,
152154
statusInfo: currentState.statusInfo,
155+
apiEndpoint: '',
156+
oauthTokenEndpoint: '',
153157
errorCode: undefined
154158
});
155159
postMessage('sandboxDetectStatus');
@@ -299,6 +303,8 @@ export default function addSandboxView(props): JSX.Element {
299303
action: 'sandboxPageRequestVerificationCode',
300304
statusInfo: '',
301305
consoleDashboard: '',
306+
apiEndpoint: '',
307+
oauthTokenEndpoint: '',
302308
errorCode: undefined
303309
});
304310
}
@@ -376,7 +382,7 @@ export default function addSandboxView(props): JSX.Element {
376382
const Provisioned = () => {
377383

378384
const handleLoginButton = () => {
379-
postMessage('sandboxLoginUsingDataInClipboard', {url: currentState.consoleDashboard});
385+
postMessage('sandboxLoginUsingDataInClipboard', {apiEndpointUrl: currentState.apiEndpoint, oauthRequestTokenUrl: `${currentState.oauthTokenEndpoint}/request`});
380386
};
381387

382388
return (
@@ -399,16 +405,19 @@ export default function addSandboxView(props): JSX.Element {
399405
</Typography>
400406
<Typography variant="caption" display="block" style={{ textAlign:'left', margin: '20px 70px' }}>
401407
Next steps to connect with Developer Sandbox:<br></br>
402-
1. Click on <strong>Open Dashboard button</strong>. In the browser, login using <strong>DevSandbox</strong> and once loggedin, click on username dropdown.<br></br>
403-
2. Select <strong>Copy Login command</strong>. Once the new tab is opened, copy the entire <strong>Log in with this token</strong> command.<br></br>
404-
3. Come back to IDE and press <strong>'Login To Sandbox'</strong> Button. This will login your DevSandbox in OpenShift Application View.<br></br>
408+
1. Click on <strong>Get token</strong> button. In the browser, login using <strong>DevSandbox</strong> button.<br></br>
409+
2. Click on <strong>Display token</strong> link and copy token to clipboard.<br></br>
410+
3. Switch back to IDE and press <strong>'Login To DevSandbox'</strong> button. This will login you to DevSandbox with token from clipboard.<br></br>
405411
4. Once successfully logged in, start creating applications and deploy on cluster.
406412
</Typography>
407-
<Tooltip title="Launch your Sandbox console in browser" placement="bottom">
413+
<Tooltip title="Launch your DevSandbox console in browser" placement="bottom">
408414
<Button variant="contained" className={classes.button} href={currentState.consoleDashboard}>Open Dashboard</Button>
409415
</Tooltip>
410-
<Tooltip title="Connect in OpenShift Application View" placement="bottom">
411-
<Button variant="contained" className={classes.buttonSecondary} onClick={handleLoginButton}>Login to Sandbox</Button>
416+
<Tooltip title="Copy token from DevSandbox console page in browser" placement="bottom">
417+
<Button variant="contained" className={classes.button} href={`${currentState.oauthTokenEndpoint}/request`}>Get token</Button>
418+
</Tooltip>
419+
<Tooltip title="Login to DevSandbox OpenShift cluster with token from clipboard" placement="bottom">
420+
<Button variant="contained" className={classes.buttonSecondary} onClick={handleLoginButton}>Login to DevSandbox</Button>
412421
</Tooltip>
413422
</div>
414423
)}

src/webview/cluster/clusterViewLoader.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ async function clusterEditorMessageListener (event: any ): Promise<any> {
108108
panel.webview.postMessage({action: 'sandboxPageRequestSignup'});
109109
} else {
110110
if (signupStatus.status.ready) {
111-
panel.webview.postMessage({action: 'sandboxPageProvisioned', statusInfo: signupStatus.username, consoleDashboard: signupStatus.consoleURL });
111+
const oauthInfo = await sandboxAPI.getOauthServerInfo(signupStatus.apiEndpoint);
112+
panel.webview.postMessage({action: 'sandboxPageProvisioned', statusInfo: signupStatus.username, consoleDashboard: signupStatus.consoleURL, apiEndpoint: signupStatus.apiEndpoint, oauthTokenEndpoint: oauthInfo.token_endpoint });
112113
} else {
113114
// cluster is not ready and the reason is
114115
if (signupStatus.status.verificationRequired) {
@@ -118,8 +119,6 @@ async function clusterEditorMessageListener (event: any ): Promise<any> {
118119
//
119120
if (signupStatus.status.reason === 'PendingApproval') {
120121
panel.webview.postMessage({action: 'sandboxPageWaitingForApproval'});
121-
} else if (signupStatus.status.reason === 'Provisioned') {
122-
panel.webview.postMessage({action: 'sandboxPageProvisioned', statusInfo: signupStatus.username, consoleDashboard: signupStatus.consoleURL});
123122
} else {
124123
panel.webview.postMessage({action: 'sandboxPageWaitingForProvision'})
125124
}
@@ -174,7 +173,7 @@ async function clusterEditorMessageListener (event: any ): Promise<any> {
174173
case 'sandboxLoginUsingDataInClipboard':
175174
const telemetryEventLoginToSandbox = new ExtCommandTelemetryEvent('openshift.explorer.addCluster.sandboxLoginUsingDataInClipboard');
176175
try {
177-
const result = await Cluster.loginUsingClipboardInfo(event.payload.url);
176+
const result = await Cluster.loginUsingClipboardToken(event.payload.apiEndpointUrl, event.payload.oauthRequestTokenUrl);
178177
if (result) vscode.window.showInformationMessage(`${result}`);
179178
telemetryEventLoginToSandbox.send();
180179
} catch (err) {

0 commit comments

Comments
 (0)