Add command to generate super_client_info files
Change-Id: Id995295df35d62d277ebd78eb9f8ea184648799f
diff --git a/.gitignore b/.gitignore
index 84cb25a..910a8e6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,6 +22,7 @@
/lib/Kalamar/Plugin/Announcements.pm
/log
/blib
+/super_client_info
/script*
/MYMETA*
/Makefile
diff --git a/Changes b/Changes
index 50b2458..fc20a0c 100755
--- a/Changes
+++ b/Changes
@@ -1,3 +1,6 @@
+0.47 2022-11-22
+ - Add command to generate super_client_info file. (diewald)
+
0.46 2022-08-08
- Increased max query length from 1000 to 4096 characters. (kupietz)
- Fix handling of public clients. (diewald)
diff --git a/lib/Kalamar.pm b/lib/Kalamar.pm
index 36b2524..8ba4cae 100644
--- a/lib/Kalamar.pm
+++ b/lib/Kalamar.pm
@@ -8,7 +8,7 @@
use List::Util 'none';
# Minor version - may be patched from package.json
-our $VERSION = '0.46';
+our $VERSION = '0.47';
# Supported version of Backend API
our $API_VERSION = '1.0';
@@ -37,6 +37,9 @@
# Add additional plugin path
push(@{$self->plugins->namespaces}, __PACKAGE__ . '::Plugin');
+ # Add additional commands
+ push(@{$self->commands->namespaces}, __PACKAGE__ . '::Command');
+
# Set secrets for signed cookies
my $secret_file = $self->home->rel_file('kalamar.secret.json');
diff --git a/lib/Kalamar/Command/super_client_info.pm b/lib/Kalamar/Command/super_client_info.pm
new file mode 100644
index 0000000..4670689
--- /dev/null
+++ b/lib/Kalamar/Command/super_client_info.pm
@@ -0,0 +1,104 @@
+package Kalamar::Command::super_client_info;
+use Mojo::Base 'Mojolicious::Command';
+
+has description => 'Generate random super_client_info file';
+has usage => sub { shift->extract_usage };
+
+sub run {
+ my $self = shift;
+ my $client_id = shift;
+
+ # Path for super client file
+ my $path = shift || $self->rel_file('super_client_info');
+
+ my $app = $self->app;
+
+ $app->plugin(
+ 'Mojolicious::Plugin::Util::RandomString',
+ entropy => 256,
+ printable => {
+ alphabet => '2345679bdfhmnprtFGHJLMNPRT',
+ length => 20
+ }
+ );
+
+ my $secret = $app->random_string('printable');
+
+ unless ($client_id) {
+ $client_id = $app->random_string('printable');
+ };
+
+ my $c = $self->app->build_controller;
+
+ $self->write_file(
+ $path,
+ $c->render_to_string(
+ json => {
+ client_id => $client_id,
+ client_secret => $secret
+ }
+ )
+ );
+};
+
+1;
+
+=encoding utf8
+
+=head1 NAME
+
+Kalamar::Command::super_client_info - Generate random super_client_info file
+
+=head1 SYNOPSIS
+
+ Usage: APPLICATION super_client_info
+
+ kalamar super_client_info
+ kalamar super_client_info 'my-client'
+ kalamar super_client_info 'my-client' './output/super_client_info'
+
+ Options:
+ -h, --help Show this summary of available options
+
+=head1 DESCRIPTION
+
+L<Kalamar::Command::super_client_info> generates C<super_client_info>
+files with a client ID (either random or passed) and a randomized client secret.
+
+This file can be used by Kalamar and Kustvakt (full) to have a common secret.
+
+=head1 ATTRIBUTES
+
+L<Kalamar::Command::Author::generate::super_client_info> inherits all attributes from L<Mojolicious::Command> and implements
+the following new ones.
+
+=head2 description
+
+ my $description = $super_client_info->description;
+ $super_client_info = $super_client_info->description('Foo');
+
+Short description of this command, used for the command list.
+
+=head2 usage
+
+ my $usage = $super_client_info->usage;
+ $super_client_info = $super_client_info->usage('Foo');
+
+Usage information for this command, used for the help screen.
+
+=head1 METHODS
+
+L<Kalamar::Command::super_client_info> inherits all methods from L<Mojolicious::Command> and implements
+the following new ones.
+
+=head2 run
+
+ $super_client_info->run(@ARGV);
+
+Run this command.
+
+=head1 SEE ALSO
+
+L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>.
+
+=cut
diff --git a/t/command/super_client_info.t b/t/command/super_client_info.t
new file mode 100644
index 0000000..d058aac
--- /dev/null
+++ b/t/command/super_client_info.t
@@ -0,0 +1,104 @@
+#!usr/bin/env perl
+use Mojolicious::Lite;
+use Mojolicious::Commands;
+use Data::Dumper;
+use Test::Output qw/:stdout :stderr :combined :functions/;
+use Test::More;
+use Test::Mojo;
+use Mojo::Util qw/decode encode/;
+use Mojo::JSON qw/decode_json/;
+use Mojo::File 'path';
+use File::Temp 'tempdir';
+
+my $t = Test::Mojo->new('Kalamar');
+
+my $dir = tempdir CLEANUP => 1;
+chdir $dir;
+
+my $dir_ext = tempdir CLEANUP => 1;
+
+my $cmds = $t->app->commands;
+
+like(
+ join(' ', @{$cmds->namespaces}),
+ qr!Mojolicious::Command!,
+ 'Namespace is set'
+);
+
+like(
+ join(' ', @{$cmds->namespaces}),
+ qr!Kalamar::Command!,
+ 'Namespace is set'
+);
+
+stdout_like(
+ sub {
+ local $ENV{HARNESS_ACTIVE} = 0;
+ $cmds->run('super-client-info');
+ },
+ qr/\[write\].*super_client_info/,
+ 'Write'
+);
+
+stdout_unlike(
+ sub {
+ local $ENV{HARNESS_ACTIVE} = 0;
+ $cmds->run('super-client-info');
+ },
+ qr/\[write\].*super_client_info/,
+ 'Already exists'
+);
+
+my $file = path($dir, 'super_client_info');
+
+my $out = decode_json($file->slurp);
+
+like($out->{client_id},qr!^.{20}$!);
+like($out->{client_secret},qr!^.{20}$!);
+
+unlink $file->to_string;
+
+stdout_like(
+ sub {
+ local $ENV{HARNESS_ACTIVE} = 0;
+ $cmds->run('super-client-info', 'my-client');
+ },
+ qr/\[write\].*super_client_info/,
+ 'Write with client id'
+);
+
+$out = decode_json($file->slurp);
+
+like($out->{client_id}, qr!my-client$!);
+like($out->{client_secret}, qr!^.{20}$!);
+
+my $file_ext = path($dir_ext, 'super_client_fun');
+
+stdout_like(
+ sub {
+ local $ENV{HARNESS_ACTIVE} = 0;
+ $cmds->run('super-client-info', 'my-client-2', $file_ext);
+ },
+ qr/\[write\].*super_client_fun/,
+ 'Error'
+);
+
+$out = decode_json($file->slurp);
+
+like($out->{client_id}, qr!my-client$!);
+like($out->{client_secret}, qr!^.{20}$!);
+
+my $secret_1 = $out->{client_secret};
+
+$out = decode_json($file_ext->slurp);
+
+like($out->{client_id}, qr!my-client-2$!);
+like($out->{client_secret}, qr!^.{20}$!);
+
+my $secret_2 = $out->{client_secret};
+
+isnt($secret_1, $secret_2, 'Generated secrets differ');
+
+
+done_testing;
+__END__