-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
styra-link: correct password flow #81
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,13 +61,22 @@ export class StyraInstall { | |
|
||
if (selection === 'Install') { | ||
info('Installing Styra CLI. This may take a few minutes...'); | ||
try { | ||
await this.installStyra(); | ||
teeInfo(`CLI ${operation} completed.`); | ||
return true; | ||
} catch (err) { | ||
teeError(`CLI ${operation} failed: ${err}`); | ||
return false; | ||
let trials = 0; | ||
// eslint-disable-next-line no-constant-condition | ||
while (true) { | ||
Comment on lines
+71
to
+72
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Surprised it is not smart enough to recognize the loop does have exits. |
||
try { | ||
const tempFile = await this.installStyra(trials++); | ||
await StyraInstall.installOnPath(tempFile); | ||
teeInfo(`CLI ${operation} completed.`); | ||
return true; | ||
} catch (err) { | ||
if ((err as Error).message.includes('Sorry, try again')) { | ||
info('invalid password; try again...'); | ||
Comment on lines
+78
to
+79
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add in a specific check for a password failure and, if found: |
||
} else { | ||
teeError(`CLI ${operation} failed: ${(err as Error).message}`); | ||
return false; | ||
} | ||
} | ||
} | ||
} else { | ||
infoFromUserAction(`CLI ${operation} cancelled`); | ||
|
@@ -163,37 +172,44 @@ export class StyraInstall { | |
: `${prefix}/linux/amd64/styra`; | ||
} | ||
|
||
private static async installStyra(): Promise<void> { | ||
private static async installStyra(trials = 0): Promise<string> { | ||
|
||
const tempFileLocation = path.join(os.homedir(), this.BinaryFile); | ||
const url = this.getDownloadUrl(); | ||
|
||
return await IDE.withProgress({ | ||
await IDE.withProgress({ | ||
location: IDE.ProgressLocation.Notification, | ||
title: 'Installing Styra CLI', | ||
cancellable: false | ||
}, async () => { | ||
await this.getBinary(url, tempFileLocation); | ||
info(` Platform: ${process.platform}`); | ||
info(` Architecture: ${process.arch}`); | ||
info(` Executable: ${this.ExeFile}`); | ||
fs.chmodSync(tempFileLocation, '755'); | ||
if (this.isWindows()) { | ||
await moveFile(tempFileLocation, this.ExeFile); | ||
await this.adjustWindowsPath(this.ExePath); | ||
} else { | ||
const state = await this.collectInputs(); | ||
// see https://stackoverflow.com/q/39785436/115690 for ideas on running sudo | ||
const args = ['-c', `echo ${state.pwd} | sudo -S bash -c 'mv ${tempFileLocation} ${this.ExeFile}'`]; | ||
// vital to run in quiet mode so password does not display | ||
await new CommandRunner().runShellCmd('sh', args, {progressTitle: '', quiet: true}); | ||
Comment on lines
-185
to
-189
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By moving |
||
if (trials === 0) { | ||
await this.getBinary(url, tempFileLocation); | ||
info(` Platform: ${process.platform}`); | ||
info(` Architecture: ${process.arch}`); | ||
info(` Executable: ${this.ExeFile}`); | ||
fs.chmodSync(tempFileLocation, '755'); | ||
} | ||
}); | ||
return tempFileLocation; | ||
} | ||
|
||
private static async installOnPath(tempFileLocation: string) { | ||
if (this.isWindows()) { | ||
await moveFile(tempFileLocation, this.ExeFile); | ||
await this.adjustWindowsPath(this.ExePath); | ||
} else { | ||
const state = await this.collectInputs(); | ||
// see https://stackoverflow.com/q/39785436/115690 for ideas on running sudo | ||
const args = ['-c', `echo ${state.pwd} | sudo -S bash -c 'mv ${tempFileLocation} ${this.ExeFile}'`]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nit] I know this is copied code, but I still don't quite like this. I'm always getting nervous when any tool asks me to input my password. Be that as it may, I suppose we're not here to discuss this. Anyway... This particular method seems icky, too -- multi-user machines are no longer the norm, but any other process on the machine could read the user's password from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I certainly agree with your point but I am not sure there is a way to give a user a shell prompt from within a VSCode command. I like the idea though, so will put it on my backlog but merge as is for now. Thanks! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only winning move is not to play -- we can install the binary anywhere, and use it from anywhere. So we can use a location where an unprivileged user can write to. |
||
// vital to run in quiet mode so password does not display | ||
await new CommandRunner().runShellCmd('sh', args, {progressTitle: '', quiet: true}); | ||
} | ||
} | ||
|
||
private static async getBinary(url: string, tempFileLocation: string): Promise<void> { | ||
// adapted from https://stackoverflow.com/a/69290915 | ||
const response = await fetch(url); | ||
|
||
if (!response.ok) { | ||
throw new Error( | ||
response.status === 404 ? `Bad URL for downloading styra - ${url}` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Separating
installStyra
intodownloadBinary
andinstallOnPath
.