Skip to content

Commit d161148

Browse files
committed
fix: Fixed callbacks for sudo and import
1 parent 77a2505 commit d161148

2 files changed

Lines changed: 56 additions & 51 deletions

File tree

codify.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"default": "../codify-homebrew-plugin/src/index.ts"
66
}
77
},
8+
{ "type": "terraform" },
89
{
910
"type": "homebrew",
1011
"taps": [
@@ -13,8 +14,7 @@
1314
"homebrew/services"
1415
],
1516
"formulae": [
16-
"asciinema",
17-
"abduco"
17+
"asciinema"
1818
],
1919
"casks": [
2020
"firefox"

src/ui/reporters/default-reporter2.tsx

Lines changed: 54 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,12 @@ enum RenderState {
3434

3535
enum Callbacks {
3636
CONFIRMATION_RESULT = 'confirmation_result',
37+
PROMPT_IMPORT_RESULT = 'prompt_import_result',
38+
SUDO_PROMPT_RESULT = 'sudo_prompt_result',
3739
}
3840

3941
interface AppState {
40-
renderState: RenderState;
42+
renderState?: RenderState;
4143
plan?: Plan;
4244
data?: any; // Any temporary data we want to pass will be stored here. For ex: the apply confirmation message.
4345
}
@@ -54,29 +56,6 @@ class DefaultReporter2 extends React.Component<{}, AppState> implements Reporter
5456
ctx.on(Event.OUTPUT, (args) => this.log(args));
5557
}
5658

57-
async askRequiredParametersForImport(requiredParameters: RequiredParameters): Promise<UserSuppliedParameters> {
58-
if (requiredParameters.size === 0) {
59-
return new Map();
60-
}
61-
62-
this.renderEmitter.emit(RenderEvent.PROMPT_IMPORT_PARAMETERS, requiredParameters);
63-
64-
return new Promise((resolve) => {
65-
this.renderEmitter.once(RenderEvent.PROMPT_IMPORT_PARAMETERS_RESULT, (result: object) => {
66-
const userSuppliedParameters = this.extractUserSuppliedParametersFromResult(result);
67-
resolve(userSuppliedParameters);
68-
});
69-
})
70-
}
71-
72-
displayImportResult(importResult: ImportResult): void {
73-
this.setState(structuredClone({
74-
...this.state,
75-
renderState: RenderState.DISPLAY_IMPORT_RESULT,
76-
importResult,
77-
}))
78-
}
79-
8059
async promptSudo(pluginName: string, data: SudoRequestData, secureMode: boolean): Promise<SudoRequestResponseData> {
8160
console.log(chalk.blue(`Plugin: "${pluginName}" requires root access to run command: "${data.command}"`));
8261

@@ -87,10 +66,7 @@ class DefaultReporter2 extends React.Component<{}, AppState> implements Reporter
8766
password = await this.getUserPassword();
8867
}
8968

90-
const result = await SudoUtils.runCommand(data.command, data.options, secureMode, pluginName, password)
91-
this.renderEmitter.emit(RenderEvent.PROMPT_SUDO_GRANTED);
92-
93-
return result;
69+
return SudoUtils.runCommand(data.command, data.options, secureMode, pluginName, password)
9470
}
9571

9672
displayPlan(plan: Plan): void {
@@ -110,9 +86,10 @@ class DefaultReporter2 extends React.Component<{}, AppState> implements Reporter
11086

11187
const continueApply = await this.awaitCallback<boolean>(Callbacks.CONFIRMATION_RESULT);
11288
if (continueApply) {
113-
this.setState(structuredClone({
89+
this.setState({
90+
...this.state,
11491
renderState: RenderState.PROGRESS,
115-
}))
92+
})
11693
this.log(`${message} -> "Yes"`)
11794
}
11895

@@ -126,6 +103,29 @@ class DefaultReporter2 extends React.Component<{}, AppState> implements Reporter
126103
}))
127104
}
128105

106+
async askRequiredParametersForImport(requiredParameters: RequiredParameters): Promise<UserSuppliedParameters> {
107+
if (requiredParameters.size === 0) {
108+
return new Map();
109+
}
110+
111+
this.setState({
112+
...this.state,
113+
renderState: RenderState.IMPORT_PROMPT,
114+
data: requiredParameters,
115+
})
116+
117+
const result = await this.awaitCallback<object>(Callbacks.PROMPT_IMPORT_RESULT);
118+
return this.extractUserSuppliedParametersFromResult(result);
119+
}
120+
121+
displayImportResult(importResult: ImportResult): void {
122+
this.setState({
123+
...this.state,
124+
renderState: RenderState.DISPLAY_IMPORT_RESULT,
125+
data: importResult,
126+
})
127+
}
128+
129129
private log(log: string): void {
130130
console.log(chalk.cyan(log));
131131
}
@@ -134,12 +134,22 @@ class DefaultReporter2 extends React.Component<{}, AppState> implements Reporter
134134
let attemptCount = 0;
135135

136136
while (attemptCount < 3) {
137-
const passwordAttempt = await this.renderSudoPrompt(attemptCount);
137+
this.setState({
138+
...this.state,
139+
renderState: RenderState.SUDO_PROMPT,
140+
data: attemptCount,
141+
})
142+
143+
const passwordAttempt = await this.awaitCallback<string>(Callbacks.SUDO_PROMPT_RESULT)
138144

139145
// Validates that the password works
140146
if (SudoUtils.validate(passwordAttempt)) {
141-
this.renderEmitter.emit(RenderEvent.PROMPT_SUDO_GRANTED);
142-
return passwordAttempt
147+
this.setState({
148+
...this.state,
149+
renderState: RenderState.PROGRESS,
150+
})
151+
152+
return passwordAttempt;
143153
}
144154

145155
if (attemptCount + 1 < 3) {
@@ -150,17 +160,12 @@ class DefaultReporter2 extends React.Component<{}, AppState> implements Reporter
150160
attemptCount++;
151161
}
152162

153-
this.renderEmitter.emit(RenderEvent.PROMPT_SUDO_ERROR);
154-
throw new Error('sudo: 3 incorrect password attempts')
155-
}
163+
this.setState({
164+
...this.state,
165+
renderState: undefined,
166+
});
156167

157-
private async renderSudoPrompt(attemptCount: number): Promise<string> {
158-
return new Promise((resolve) => {
159-
this.renderEmitter.emit(RenderEvent.PROMPT_SUDO, attemptCount);
160-
this.renderEmitter.on(RenderEvent.PROMPT_SUDO_RESULT, (password) => {
161-
resolve(password)
162-
})
163-
})
168+
throw new Error('sudo: 3 incorrect password attempts')
164169
}
165170

166171
private extractUserSuppliedParametersFromResult(result: object): Map<string, Record<string, unknown>> {
@@ -204,7 +209,7 @@ class DefaultReporter2 extends React.Component<{}, AppState> implements Reporter
204209
this.state.renderState === RenderState.PROMPT_CONFIRMATION && (
205210
<Box flexDirection="column">
206211
<Text>{this.state.data}</Text>
207-
<Select onChange={(value) => this.callbacks.emit(RenderEvent.PROMPT_CONFIRMATION_RESULT, value === 'yes')} options={[
212+
<Select onChange={(value) => this.callbacks.emit(Callbacks.CONFIRMATION_RESULT, value === 'yes')} options={[
208213
{ label: 'Yes', value: 'yes' },
209214
{ label: 'No', value: 'no' },
210215
]}/>
@@ -225,22 +230,22 @@ class DefaultReporter2 extends React.Component<{}, AppState> implements Reporter
225230
<Box flexDirection="column">
226231
<Text>Password:</Text>
227232
{/* Use sudoAttemptCount as a hack to reset password input between attempts */}
228-
<PasswordInput key={sudoAttemptCount} onSubmit={(password) => {
229-
this.callbacks.emit(RenderEvent.PROMPT_SUDO_RESULT, password);
233+
<PasswordInput key={this.state.data} onSubmit={(password) => {
234+
this.callbacks.emit(Callbacks.SUDO_PROMPT_RESULT, password);
230235
}}/>
231236
</Box>
232237
)
233238
}
234239
{
235240
this.state.renderState === RenderState.IMPORT_PROMPT && (
236241
<ImportParametersForm onSubmit={(result) => {
237-
this.callbacks.emit(RenderEvent.PROMPT_IMPORT_PARAMETERS_RESULT, result)
238-
}} requiredParameters={requiredParametersForImport}/>
242+
this.callbacks.emit(Callbacks.PROMPT_IMPORT_RESULT, result)
243+
}} requiredParameters={this.state.data}/>
239244
)
240245
}
241246
{
242247
this.state.renderState === RenderState.DISPLAY_IMPORT_RESULT && (
243-
<Static items={[this.state.importResult]}>{
248+
<Static items={[this.state.data]}>{
244249
(importResult, idx) => <ImportResultComponent importResult={importResult} key={idx}/>
245250
}</Static>
246251
)

0 commit comments

Comments
 (0)