@@ -164,87 +164,88 @@ class CoderCLIManager(
164
164
* Download the CLI from the deployment if necessary.
165
165
*/
166
166
suspend fun download (buildVersion : String , showTextProgress : (String ) -> Unit ): Boolean {
167
- val cliResult = withContext(Dispatchers .IO ) {
168
- downloader.downloadCli(buildVersion, showTextProgress)
169
- }.let { result ->
170
- when {
171
- result.isSkipped() -> return false
172
- result.isNotFound() -> throw IllegalStateException (" Could not find Coder CLI" )
173
- result.isFailed() -> throw (result as DownloadResult .Failed ).error
174
- else -> result as Downloaded
167
+ try {
168
+ val cliResult = withContext(Dispatchers .IO ) {
169
+ downloader.downloadCli(buildVersion, showTextProgress)
170
+ }.let { result ->
171
+ when {
172
+ result.isSkipped() -> return false
173
+ result.isNotFound() -> throw IllegalStateException (" Could not find Coder CLI" )
174
+ result.isFailed() -> throw (result as DownloadResult .Failed ).error
175
+ else -> result as Downloaded
176
+ }
175
177
}
176
- }
177
-
178
- var signatureResult = withContext(Dispatchers .IO ) {
179
- downloader.downloadSignature(showTextProgress)
180
- }
181
178
182
- if (signatureResult.isNotDownloaded()) {
183
- context.logger.info(" Trying to download signature file from releases.coder.com" )
184
- signatureResult = withContext(Dispatchers .IO ) {
185
- downloader.downloadReleasesSignature(buildVersion, showTextProgress)
179
+ var signatureResult = withContext(Dispatchers .IO ) {
180
+ downloader.downloadSignature(showTextProgress)
186
181
}
187
- }
188
182
189
- // if we could not find any signature and the user wants to explicitly
190
- // confirm whether we run an unsigned cli
191
- if (signatureResult.isNotDownloaded()) {
192
- if (context.settingsStore.allowUnsignedBinaryWithoutPrompt) {
193
- context.logger.warn(" Running unsigned CLI from ${cliResult.source} " )
194
- return true
195
- } else {
196
- val acceptsUnsignedBinary = context.ui.showYesNoPopup(
197
- context.i18n.ptrl(" Security Warning" ),
198
- context.i18n.pnotr(" Can't verify the integrity of the Coder CLI pulled from ${cliResult.source} " ),
199
- context.i18n.ptrl(" Accept" ),
200
- context.i18n.ptrl(" Abort" ),
201
- )
183
+ if (signatureResult.isNotDownloaded()) {
184
+ context.logger.info(" Trying to download signature file from releases.coder.com" )
185
+ signatureResult = withContext(Dispatchers .IO ) {
186
+ downloader.downloadReleasesSignature(buildVersion, showTextProgress)
187
+ }
188
+ }
202
189
203
- if (acceptsUnsignedBinary) {
190
+ // if we could not find any signature and the user wants to explicitly
191
+ // confirm whether we run an unsigned cli
192
+ if (signatureResult.isNotDownloaded()) {
193
+ if (context.settingsStore.allowUnsignedBinaryWithoutPrompt) {
194
+ context.logger.warn(" Running unsigned CLI from ${cliResult.source} " )
195
+ downloader.commit()
204
196
return true
205
197
} else {
206
- // remove the cli, otherwise next time the user tries to login the cached cli is picked up,
207
- // and we don't verify cached cli signatures
208
- Files .delete(cliResult.dst)
209
- throw UnsignedBinaryExecutionDeniedException (" Running unsigned CLI from ${cliResult.source} was denied by the user" )
198
+ val acceptsUnsignedBinary = context.ui.showYesNoPopup(
199
+ context.i18n.ptrl(" Security Warning" ),
200
+ context.i18n.pnotr(" Can't verify the integrity of the Coder CLI pulled from ${cliResult.source} " ),
201
+ context.i18n.ptrl(" Accept" ),
202
+ context.i18n.ptrl(" Abort" ),
203
+ )
204
+
205
+ if (acceptsUnsignedBinary) {
206
+ downloader.commit()
207
+ return true
208
+ } else {
209
+ throw UnsignedBinaryExecutionDeniedException (" Running unsigned CLI from ${cliResult.source} was denied by the user" )
210
+ }
210
211
}
211
212
}
212
- }
213
-
214
- // we have the cli, and signature is downloaded, let's verify the signature
215
- signatureResult = signatureResult as Downloaded
216
- gpgVerifier.verifySignature(cliResult.dst, signatureResult.dst).let { result ->
217
- when {
218
- result.isValid() -> return true
219
- else -> {
220
- // remove the cli, otherwise next time the user tries to login the cached cli is picked up,
221
- // and we don't verify cached cli signatures
222
- runCatching { Files .delete(cliResult.dst) }
223
- .onFailure { ex ->
224
- context.logger.warn(ex, " Failed to delete CLI file: ${cliResult.dst} " )
225
- }
226
213
227
- val exception = when {
228
- result.isInvalid() -> {
229
- val reason = (result as Invalid ).reason
230
- UnsignedBinaryExecutionDeniedException (
231
- " Signature of ${cliResult.dst} is invalid." + reason?.let { " Reason: $it " }.orEmpty()
232
- )
233
- }
234
-
235
- result.signatureIsNotFound() -> {
236
- UnsignedBinaryExecutionDeniedException (
237
- " Can't verify signature of ${cliResult.dst} because ${signatureResult.dst} does not exist"
238
- )
239
- }
214
+ // we have the cli, and signature is downloaded, let's verify the signature
215
+ signatureResult = signatureResult as Downloaded
216
+ gpgVerifier.verifySignature(cliResult.dst, signatureResult.dst).let { result ->
217
+ when {
218
+ result.isValid() -> {
219
+ downloader.commit()
220
+ return true
221
+ }
240
222
241
- else -> {
242
- UnsignedBinaryExecutionDeniedException ((result as Failed ).error.message)
223
+ else -> {
224
+ val exception = when {
225
+ result.isInvalid() -> {
226
+ val reason = (result as Invalid ).reason
227
+ UnsignedBinaryExecutionDeniedException (
228
+ " Signature of ${cliResult.dst} is invalid." + reason?.let { " Reason: $it " }
229
+ .orEmpty()
230
+ )
231
+ }
232
+
233
+ result.signatureIsNotFound() -> {
234
+ UnsignedBinaryExecutionDeniedException (
235
+ " Can't verify signature of ${cliResult.dst} because ${signatureResult.dst} does not exist"
236
+ )
237
+ }
238
+
239
+ else -> {
240
+ UnsignedBinaryExecutionDeniedException ((result as Failed ).error.message)
241
+ }
243
242
}
243
+ throw exception
244
244
}
245
- throw exception
246
245
}
247
246
}
247
+ } finally {
248
+ downloader.cleanup()
248
249
}
249
250
}
250
251
@@ -475,7 +476,7 @@ class CoderCLIManager(
475
476
}
476
477
477
478
else -> {
478
- // An error here most likely means the CLI does not exist or
479
+ // An error here most likely means the CLI does not exist, or
479
480
// it executed successfully but output no version which
480
481
// suggests it is not the right binary.
481
482
context.logger.info(" Unable to determine $localBinaryPath version: ${e.message} " )
0 commit comments