Skip to content

Commit f81b4aa

Browse files
authored
Merge pull request #1324 from nextcloud/enh/1307/alt-client-secret-cli-input
New upsert command options to read client secret from env var or file
2 parents 831a5cc + 31a17e9 commit f81b4aa

1 file changed

Lines changed: 50 additions & 7 deletions

File tree

lib/Command/UpsertProvider.php

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ protected function configure() {
178178
->addArgument('identifier', InputArgument::OPTIONAL, 'Administrative identifier name of the provider in the setup')
179179
->addOption('clientid', 'c', InputOption::VALUE_REQUIRED, 'OpenID client identifier')
180180
->addOption('clientsecret', 's', InputOption::VALUE_REQUIRED, 'OpenID client secret')
181+
->addOption('clientsecret-file', null, InputOption::VALUE_REQUIRED, 'File that contains the OpenID client secret')
182+
->addOption('clientsecret-env', null, InputOption::VALUE_REQUIRED, 'Environment variable that contains the OpenID client secret')
181183
->addOption('discoveryuri', 'd', InputOption::VALUE_REQUIRED, 'OpenID discovery endpoint uri')
182184
->addOption('endsessionendpointuri', 'e', InputOption::VALUE_REQUIRED, 'OpenID end session endpoint uri')
183185
->addOption('postlogouturi', 'p', InputOption::VALUE_REQUIRED, 'Post logout URI')
@@ -192,10 +194,15 @@ protected function execute(InputInterface $input, OutputInterface $output) {
192194
$outputFormat = $input->getOption('output') ?? 'table';
193195

194196
$identifier = $input->getArgument('identifier');
195-
$clientid = $input->getOption('clientid');
196-
$clientsecret = $input->getOption('clientsecret');
197-
if ($clientsecret !== null) {
198-
$clientsecret = $this->crypto->encrypt($clientsecret);
197+
$clientId = $input->getOption('clientid');
198+
$clientSecret = $input->getOption('clientsecret');
199+
$clientSecretFile = $input->getOption('clientsecret-file');
200+
$clientSecretEnv = $input->getOption('clientsecret-env');
201+
try {
202+
$clientSecret = $this->getClientSecretInput($clientSecret, $clientSecretFile, $clientSecretEnv, $output);
203+
} catch (\Exception $e) {
204+
$output->writeln($e->getMessage());
205+
return 1;
199206
}
200207
$discoveryuri = $input->getOption('discoveryuri');
201208
$endsessionendpointuri = $input->getOption('endsessionendpointuri');
@@ -218,7 +225,7 @@ protected function execute(InputInterface $input, OutputInterface $output) {
218225
try {
219226
$provider = $this->providerMapper->findProviderByIdentifier($identifier);
220227
} catch (DoesNotExistException $e) {
221-
$output->writeln('Provider not found');
228+
$output->writeln('<error>Provider not found</error>');
222229
return -1;
223230
}
224231
$provider = $this->providerService->getProviderWithSettings($provider->getId());
@@ -250,7 +257,7 @@ protected function execute(InputInterface $input, OutputInterface $output) {
250257
}
251258
try {
252259
$provider = $this->providerMapper->createOrUpdateProvider(
253-
$identifier, $clientid, $clientsecret, $discoveryuri, $scope, $endsessionendpointuri, $postLogoutUri
260+
$identifier, $clientId, $clientSecret, $discoveryuri, $scope, $endsessionendpointuri, $postLogoutUri
254261
);
255262
// invalidate JWKS cache (even if it was just created)
256263
$this->providerService->setSetting($provider->getId(), ProviderService::SETTING_JWKS_CACHE, '');
@@ -287,7 +294,7 @@ private function listProviders(InputInterface $input, OutputInterface $output) {
287294
}
288295

289296
if (count($providers) === 0) {
290-
$output->writeln('No providers configured');
297+
$output->writeln('<error>No providers configured</error>');
291298
return 0;
292299
}
293300

@@ -306,4 +313,40 @@ private function listProviders(InputInterface $input, OutputInterface $output) {
306313
$table->render();
307314
return 0;
308315
}
316+
317+
private function getClientSecretInput(
318+
?string $clientSecret, ?string $clientSecretFile, ?string $clientSecretEnv, OutputInterface $output,
319+
): ?string {
320+
if (
321+
($clientSecret !== null && $clientSecretFile !== null)
322+
|| ($clientSecret !== null && $clientSecretEnv !== null)
323+
|| ($clientSecretFile !== null && $clientSecretEnv !== null)
324+
) {
325+
throw new \Exception('<comment>Only one of "--clientsecret", "--clientsecret-file" or "--clientsecret-env" can be used.</comment>');
326+
}
327+
if ($clientSecret !== null) {
328+
return $this->crypto->encrypt($clientSecret);
329+
}
330+
if ($clientSecretFile !== null) {
331+
$clientSecret = file_get_contents($clientSecretFile);
332+
if (is_string($clientSecret) && $clientSecret !== '') {
333+
$output->writeln('<info>Client secret loaded from file "' . $clientSecretFile . '"</info>');
334+
$clientSecret = trim($clientSecret);
335+
return $this->crypto->encrypt($clientSecret);
336+
} else {
337+
throw new \Exception('<error>Client secret file "' . $clientSecretFile . '" could not be read or is empty</error>');
338+
}
339+
}
340+
if ($clientSecretEnv !== null) {
341+
$clientSecret = getenv($clientSecretEnv);
342+
if (is_string($clientSecret) && $clientSecret !== '') {
343+
$output->writeln('<info>Client secret loaded from environment variable "' . $clientSecretEnv . '"</info>');
344+
$clientSecret = trim($clientSecret);
345+
return $this->crypto->encrypt($clientSecret);
346+
} else {
347+
throw new \Exception('<error>Client secret environment variable "' . $clientSecretEnv . '" could not be read or is empty</error>');
348+
}
349+
}
350+
return null;
351+
}
309352
}

0 commit comments

Comments
 (0)