@@ -164,87 +164,88 @@ class CoderCLIManager(
164164 * Download the CLI from the deployment if necessary.
165165 */
166166 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+ }
175177 }
176- }
177-
178- var signatureResult = withContext(Dispatchers .IO ) {
179- downloader.downloadSignature(showTextProgress)
180- }
181178
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)
186181 }
187- }
188182
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+ }
202189
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()
204196 return true
205197 } 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+ }
210211 }
211212 }
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- }
226213
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+ }
240222
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+ }
243242 }
243+ throw exception
244244 }
245- throw exception
246245 }
247246 }
247+ } finally {
248+ downloader.cleanup()
248249 }
249250 }
250251
@@ -475,7 +476,7 @@ class CoderCLIManager(
475476 }
476477
477478 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
479480 // it executed successfully but output no version which
480481 // suggests it is not the right binary.
481482 context.logger.info(" Unable to determine $localBinaryPath version: ${e.message} " )
0 commit comments