Show source code of registered plugins

Change-Id: I8ddc6b59fe3dbff068a23c4aca6d17181a881a2e
diff --git a/dev/scss/main/oauth.scss b/dev/scss/main/oauth.scss
index 262b2b4..9e1a3d7 100644
--- a/dev/scss/main/oauth.scss
+++ b/dev/scss/main/oauth.scss
@@ -57,6 +57,14 @@
   color:     $ids-blue-1;
 }
 
+#client_source {
+  white-space: pre;
+  border-radius: $standard-border-radius;
+  border-color:     $ids-grey-2;
+  border-style:     solid;
+  background-color: $light-orange;
+}
+
 li.token {
     list-style-type: none;
 }
diff --git a/lib/Kalamar/Plugin/Auth.pm b/lib/Kalamar/Plugin/Auth.pm
index 941e716..d3d347a 100644
--- a/lib/Kalamar/Plugin/Auth.pm
+++ b/lib/Kalamar/Plugin/Auth.pm
@@ -4,7 +4,7 @@
 use File::Spec::Functions qw/catdir/;
 use Mojo::ByteStream 'b';
 use Mojo::Util qw!deprecated b64_encode encode!;
-use Mojo::JSON 'decode_json';
+use Mojo::JSON qw'decode_json encode_json';
 use Encode 'is_utf8';
 
 # This is a plugin to deal with the Kustvakt OAuth server.
@@ -966,6 +966,7 @@
               $c->stash('client_desc' => $v->param('desc'));
               $c->stash('client_type' => $v->param('type'));
               $c->stash('client_url'  => $v->param('url'));
+              $c->stash('client_src'  => $v->param('source'));
               $c->stash('client_redirect_uri' => $v->param('redirect_uri'));
               $c->stash('client_id' => $client_id);
 
@@ -1258,6 +1259,7 @@
               $c->stash(client_desc => $item->{client_description});
               $c->stash(client_url  => $item->{client_url});
               $c->stash(client_type => ($item->{client_type} // 'PUBLIC'));
+              $c->stash(client_src  => encode_json($item->{source})) if $item->{source};
 
               $c->auth->token_list_p($c->stash('client_id'));
             }
diff --git a/lib/Kalamar/Plugin/Auth/templates/auth/client.html.ep b/lib/Kalamar/Plugin/Auth/templates/auth/client.html.ep
index 8e852a0..409bf5e 100644
--- a/lib/Kalamar/Plugin/Auth/templates/auth/client.html.ep
+++ b/lib/Kalamar/Plugin/Auth/templates/auth/client.html.ep
@@ -29,6 +29,19 @@
         </div>
         % };
 
+        % if (stash('client_src') && length(stash('client_src')) > 0) {
+        %= label_for 'client_source' => 'Source Code'
+        <div id="client_source"><%= stash('client_src') %></div>
+        %   content_block('nonce_js' => {
+        %     inline => 'window.addEventListener("load",function(){
+        %       let e = document.getElementById("client_source");
+        %       let src = e.textContent;
+        %       e.textContent = JSON.stringify(JSON.parse(src) || {}, null, "  ");
+        %       hljs.highlightBlock(e);
+        %     })'
+        %   });
+        % }
+        
         <br />
 
         <span class="button-group button-panel">
diff --git a/t/plugin/auth-oauth.t b/t/plugin/auth-oauth.t
index 80afe05..45281df 100644
--- a/t/plugin/auth-oauth.t
+++ b/t/plugin/auth-oauth.t
@@ -494,7 +494,7 @@
 $csrf = $t->post_ok('/settings/oauth/register' => form => {
   name => 'MyApp',
   type => 'PUBLIC',
-  desc => 'This is my application'
+  desc => 'This is my plugin application'
 })
   ->text_is('div.notify-error', 'Bad CSRF token')
   ->tx->res->dom->at('input[name="csrf_token"]')
@@ -504,7 +504,7 @@
 $t->post_ok('/settings/oauth/register' => form => {
   name => 'MyApp',
   type => 'CONFIDENTIAL',
-  desc => 'This is my application',
+  desc => 'This is my plugin application',
   csrf_token => $csrf,
   src => {
     filename => '',
@@ -526,7 +526,7 @@
   ->text_is('.form-table legend', 'Register new client application')
   ->attr_is('.oauth-register','action', '/settings/oauth/register')
   ->text_is('ul.client-list > li > span.client-name a', 'MyApp')
-  ->text_is('ul.client-list > li > p.client-desc', 'This is my application')
+  ->text_is('ul.client-list > li > p.client-desc', 'This is my plugin application')
   ->header_is('Cache-Control','max-age=0, no-cache, no-store, must-revalidate')
   ->header_is('Expires','Thu, 01 Jan 1970 00:00:00 GMT')
   ->header_is('Pragma','no-cache')
@@ -537,7 +537,7 @@
 $t->get_ok('/settings/oauth/fCBbQkA2NDA3MzM1Yw==')
   ->status_is(200)
   ->text_is('ul.client-list > li.client > span.client-name', 'MyApp')
-  ->text_is('ul.client-list > li.client > p.client-desc', 'This is my application')
+  ->text_is('ul.client-list > li.client > p.client-desc', 'This is my plugin application')
   ->text_is('a.client-unregister', 'Unregister')
   ->attr_is('a.client-unregister', 'href', '/settings/oauth/fCBbQkA2NDA3MzM1Yw==/unregister?name=MyApp')
   ;
@@ -591,7 +591,7 @@
 $t->post_ok('/settings/oauth/register' => form => {
   name => 'MyApp2',
   type => 'PUBLIC',
-  desc => 'This is my application',
+  desc => 'This is my plugin application',
   csrf_token => $csrf
 })->status_is(200)
   ->element_exists('div.notify-success')
@@ -607,7 +607,7 @@
 
 $t->get_ok('/settings/oauth/fCBbQkA2NDA3MzM1Yw==')
   ->text_is('.client-name', 'MyApp2')
-  ->text_is('.client-desc', 'This is my application')
+  ->text_is('.client-desc', 'This is my plugin application')
   ->text_is('.client-issue-token', 'Issue new token')
   ->attr_is('.client-issue-token', 'href', '/settings/oauth/fCBbQkA2NDA3MzM1Yw==/token?name=MyApp2')
   ->header_is('Cache-Control','max-age=0, no-cache, no-store, must-revalidate')
@@ -725,7 +725,7 @@
 $csrf = $t->post_ok('/settings/oauth/register' => form => {
   name => 'MyConfApp',
   type => 'CONFIDENTIAL',
-  desc => 'This is my application',
+  desc => 'This is my plugin application',
 })
   ->text_is('div.notify-error', 'Bad CSRF token')
   ->tx->res->dom->at('input[name="csrf_token"]')
@@ -896,7 +896,7 @@
 my $json_post = {
   name => 'Funny',
   type => 'PUBLIC',
-  desc => 'This is my application',
+  desc => 'This is my plugin application 2',
   csrf_token => $csrf,
   src => 'hMMM'
 };
@@ -938,6 +938,15 @@
   ->text_is('div.notify-success', 'Registration successful')
   ;
 
+$t->get_ok('/settings/oauth/jh0gfjhjbfdsgzjghj==')
+  ->status_is(200)
+  ->text_is('div.notify-error', undef)
+  ->text_is('li.client #client_source', '{"name":"example"}')
+  ->text_is('li.client span.client-name', 'Funny')
+  ->text_is('li.client p.client-desc', 'This is my plugin application 2')
+  ->element_exists_not('li.client .client-redirect-uri tt')
+  ->text_is('li.client .client-type tt', 'CONFIDENTIAL')
+  ;
 
 
 done_testing;
diff --git a/t/server/mock.pl b/t/server/mock.pl
index 1f32a39..abc6846 100644
--- a/t/server/mock.pl
+++ b/t/server/mock.pl
@@ -22,6 +22,7 @@
   'refresh_token_2' => "fghijk",
   'new_client_id' => 'fCBbQkA2NDA3MzM1Yw==',
   'new_client_id_2' => 'hghGHhjhFRz_gJhjrd==',
+  'new_client_id_3' => 'jh0gfjhjbfdsgzjghj==',
   'new_client_secret' => 'KUMaFxs6R1WGud4HM22w3HbmYKHMnNHIiLJ2ihaWtB4N5JxGzZgyqs5GTLutrORj',
   'auth_token_1'    => 'mscajfdghnjdfshtkjcuynxahgz5il'
 );
@@ -558,15 +559,23 @@
 
   my $list = $c->app->defaults('oauth.client_list');
 
-  push @$list, {
+  my $obj = {
     "client_id" => $tokens{new_client_id},
     "client_name" => $name,
     "client_description" => $desc,
     "client_url" => $url,
     "client_redirect_uri" => $redirect_uri,
-    "client_source" => $src
+    "client_type" => $type
   };
 
+  # Plugin!
+  if ($src) {
+    $obj->{source} = $src;
+    $obj->{client_id} = $tokens{new_client_id_3};
+  };
+
+  push @$list, $obj;
+
   if ($redirect_uri && $redirect_uri =~ /FAIL$/) {
     return $c->render(
       status => 400,