Add option to skip interaction when using php artisan samlidp:cert#149
Add option to skip interaction when using php artisan samlidp:cert#149joelharkes wants to merge 1 commit into
php artisan samlidp:cert#149Conversation
|
@joelharkes I like this update. I trust this has been tested with multiple options? |
|
let me write some unit tests to this, its better validation. i will add separate PR to add github action to run the unit tests :) |
There was a problem hiding this comment.
Pull request overview
This PR updates the samlidp:cert Artisan command to better support non-interactive usage in automated processes by adding options that control overwriting existing cert files and customizing the generated certificate subject.
Changes:
- Add
--overwriteoption to skip the interactive overwrite confirmation when PEM files already exist. - Add
--subjectoption to pass an OpenSSL-subjvalue during certificate generation. - Refactor overwrite decision logic into a dedicated
canCreateFiles()helper.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| exec(sprintf($command, $days, $key, $cert)); | ||
| } |
There was a problem hiding this comment.
The exec(...) call ignores the exit code/output, so certificate generation failures (missing openssl, permission errors, invalid --subject, etc.) will be silent. Capture the exit status and report an error via $this->error(...)/non-zero return code so automated pipelines can fail fast.
| exec(sprintf($command, $days, $key, $cert)); | |
| } | |
| $fullCommand = sprintf($command, $days, $key, $cert); | |
| $output = []; | |
| $exitCode = 0; | |
| exec($fullCommand, $output, $exitCode); | |
| if ($exitCode !== 0) { | |
| $message = 'Failed to generate certificate. OpenSSL exited with code ' . $exitCode . '.'; | |
| if (!empty($output)) { | |
| $message .= ' Output: ' . implode(PHP_EOL, $output); | |
| } | |
| $this->error($message); | |
| return 1; | |
| } | |
| $this->info('Certificate and key generated successfully.'); | |
| return 0; | |
| } | |
| return 0; |
| if(!$anyFileExists) { | ||
| return true; | ||
| } | ||
| if($this->option('overwrite')) { |
There was a problem hiding this comment.
The new conditionals in canCreateFiles() don't follow the spacing convention used elsewhere in src/ (e.g., if (!file_exists(...))). Run Pint/PSR-12 formatting here (if (!$anyFileExists), if ($this->option('overwrite'))) to keep style consistent.
| if(!$anyFileExists) { | |
| return true; | |
| } | |
| if($this->option('overwrite')) { | |
| if (!$anyFileExists) { | |
| return true; | |
| } | |
| if ($this->option('overwrite')) { |
| if($this->option('overwrite')) { | ||
| return true; | ||
| } | ||
| $question = 'The name chosen for the PEM files already exist. Would you like to overwrite existing PEM files?'; |
There was a problem hiding this comment.
Grammar in the prompt string is off: "The name chosen ... already exist" mixes singular/plural. Consider rephrasing to something like "The chosen PEM file names already exist..." to avoid confusion in interactive mode.
| $question = 'The name chosen for the PEM files already exist. Would you like to overwrite existing PEM files?'; | |
| $question = 'The chosen PEM file names already exist. Would you like to overwrite the existing PEM files?'; |
| protected $signature = 'samlidp:cert | ||
| {--days=7300 : Number of days to add from today as the expiration date} | ||
| {--subject= : Subj input for OpenSSL request command} | ||
| {--overwrite=0 : Overwrite existing PEM files without asking} |
There was a problem hiding this comment.
--overwrite=0 defines an option with a value (default 0) rather than a boolean flag. With the current if ($this->option('overwrite')) check, running --overwrite without a value will not necessarily skip the prompt, and non-empty strings like --overwrite=false will evaluate truthy and overwrite anyway. Consider making this a real boolean flag ({--overwrite : ...}) or performing a strict check against expected values (e.g., 1/true).
| {--overwrite=0 : Overwrite existing PEM files without asking} | |
| {--overwrite : Overwrite existing PEM files without asking} |
| $command = 'openssl req -x509 -sha256 -nodes -days %s -newkey rsa:2048 -keyout %s -out %s'; | ||
| if ($subject) { | ||
| $command .= ' -subj "' . $subject . '"'; | ||
| } | ||
|
|
||
| exec(sprintf($command, $days, $key, $cert)); |
There was a problem hiding this comment.
Building the OpenSSL command by string concatenation with a user-provided --subject and then passing it to exec() is vulnerable to shell injection and also breaks if the subject contains quotes/spaces. Use proper escaping (escapeshellarg) for all dynamic parts (days/key/cert/subject) or switch to Symfony\Component\Process\Process with an argument array to avoid invoking a shell.
We used to use the command
php artisan samlidp:certin a process, that did not have interactivity. The process would hanging because a question was asked.Added
samlidp:cert--overwrite option to skip the question to overwrite cert filessamlidp:cert--subject to add subject name when generating certificates