List tokens of a client

Change-Id: Ib4752a9f4fc502f79fefd870857405634ef5ebb9
diff --git a/Changes b/Changes
index ff68be4..126a723 100755
--- a/Changes
+++ b/Changes
@@ -15,6 +15,7 @@
         - Overhaul of menuSpec to use getElementsByClassName
           and getElementsById instead of child accessors
           (lerepp).
+        - List tokens of a client.
 
 0.41 2021-03-01
         - Introduce CORS headers to the proxy.
diff --git a/dev/js/src/plugin/server.js b/dev/js/src/plugin/server.js
index bc4eaaa..daea33c 100644
--- a/dev/js/src/plugin/server.js
+++ b/dev/js/src/plugin/server.js
@@ -395,6 +395,7 @@
     // The handling needs to be very careful,
     // as this can easily become a security nightmare.
     _receiveMsg : function (e) {
+
       // Get event data
       var d = e.data;
 
@@ -404,7 +405,11 @@
         return;
 
       // e.origin is probably set and okay - CHECK!
+      // TODO: Check e.origin is in the list of registered participants
+      // if (e.origin !== "http://example.com:8080")
+      //   return;
 
+      
       // Get origin ID
       var id = d["originID"];
 
diff --git a/lib/Kalamar/Plugin/Auth.pm b/lib/Kalamar/Plugin/Auth.pm
index a56634a..7313a7f 100644
--- a/lib/Kalamar/Plugin/Auth.pm
+++ b/lib/Kalamar/Plugin/Auth.pm
@@ -341,6 +341,47 @@
     );
 
 
+    # Get a list of registered clients
+    $app->helper(
+      'auth.token_list_p' => sub {
+        my $c = shift;
+        my $user_client_id = shift;
+
+        # Revoke the token
+        state $r_url = Mojo::URL->new($c->korap->api)->path('oauth2/token/list');
+
+        my $form = {
+          super_client_id => $client_id,
+          super_client_secret => $client_secret,
+          token_type => 'access_token',
+        };
+
+        if ($user_client_id) {
+          $form->{client_id} = $user_client_id;
+        };
+
+        # Get the list of all clients
+        return $c->korap_request(post => $r_url, {} => form => $form)->then(
+          sub {
+            my $tx = shift;
+            my $json = $tx->result->json;
+
+            # Response is fine
+            if ($tx->res->is_success) {
+              return Mojo::Promise->resolve($json);
+            };
+
+            $c->log->error($c->dumper($tx->res->to_string));
+
+            # Failure
+            $c->notify(error => $c->loc('Auth_responseError'));
+            return Mojo::Promise->reject($json // 'No response');
+          }
+        );
+      }
+    );
+
+
     # Issue a korap request with "oauth"orization
     # This will override the core request helper
     $app->helper(
@@ -895,10 +936,18 @@
               };
 
               $c->stash(client_name => $item->{client_name});
-              $c->stash(client_desc => $item->{description});
-              $c->stash(client_url  => $item->{url});
+              $c->stash(client_desc => $item->{client_description});
+              $c->stash(client_url  => $item->{client_url});
               $c->stash(client_type => 'PUBLIC');
 
+              $c->auth->token_list_p($c->stash('client_id'));
+            }
+          )->then(
+            sub {
+              my $json = shift;
+
+              $c->stash(tokens => $json);
+
               return Mojo::Promise->resolve;
             }
           )->catch(
@@ -907,11 +956,6 @@
             }
           )->finally(
             sub {
-              # return $c->render(text => 'hui');
-
-              # TODO:
-              #   This would better be a redirect to the client page, but in case there is a client_secret
-              # this wouldn't work (unless we flash that).
               return $c->render(template => 'auth/client')
             }
           );
@@ -1024,11 +1068,7 @@
 
                 $c->notify(success => 'New access token created');
 
-                return $c->render(
-                  template => 'auth/client',
-                  client_name => $name,
-                  %$json
-                );
+                $c->redirect_to('oauth-tokens' => { client_id => $client_id })
               }
             )->catch(
               sub {
diff --git a/lib/Kalamar/Plugin/Auth/templates/auth/client.html.ep b/lib/Kalamar/Plugin/Auth/templates/auth/client.html.ep
index 8900777..07745e1 100644
--- a/lib/Kalamar/Plugin/Auth/templates/auth/client.html.ep
+++ b/lib/Kalamar/Plugin/Auth/templates/auth/client.html.ep
@@ -14,28 +14,50 @@
         % if (stash('client_url')) {
         <span class="client-url"><a href="<%= stash('client_url') %>"><%= stash('client_url') %></a></span>
         % };
+
+        <p><%= loc 'Auth_clientType' %>: <tt><%= stash 'client_type' %></tt></p>
+        %= label_for 'client_id' => loc('Auth_clientID')
+        %= text_field 'client_id', stash('client_id'), readonly => 'readonly'
+        % if (stash('client_type') && stash('client_type') ne 'PUBLIC') {
+        <div>
+          %= label_for 'client_secret' => loc('Auth_clientSecret')
+          %= password_field 'client_secret', value => stash('client_secret'), readonly => 'readonly'
+        </div>
+        % };
+
       </li>
     </ul>
+
     <span class="button-group button-panel">
       %= link_to Unregister => url_for('oauth-unregister', client_id => stash('client_id'))->query('name' => stash('client_name')) => {} => ( class => 'client-unregister' )
       %= link_to IssueToken => url_for('oauth-issue-token', client_id => stash('client_id'))->query('name' => stash('client_name')) => {} => ( class => 'client-issue-token' )
     </span>
-    <p><%= loc 'Auth_clientType' %>: <tt><%= stash 'client_type' %></tt></p>
-    %= label_for 'client_id' => loc('Auth_clientID')
-    %= text_field 'client_id', stash('client_id'), readonly => 'readonly'
-    % if (stash('client_type') && stash('client_type') ne 'PUBLIC') {
-    <div>
-      %= label_for 'client_secret' => loc('Auth_clientSecret')
-      %= password_field 'client_secret', value => stash('client_secret'), readonly => 'readonly'
-    </div>
-    % };
+    
 
-    % if (stash('access_token')) {
-    %= label_for 'access_token' => 'Access Token'
-    %= text_field 'access_token', stash('access_token'), readonly => 'readonly'
-    <p name="expires">Expires in: <tt><%= stash 'expires_in' %></tt></p>
-    <p name="scope">Scope: <tt><%= stash 'scope' %></tt></p>
-    <p name="type">Token-Type: <tt><%= stash 'token_type' %></tt></p>
-    % }
+    % if ($c->stash('tokens')) {
+    <h4>Tokens</h3>
+    <ul class="token-list">
+      % foreach (@{$c->stash('tokens')}) {
+      <li>
+      %= label_for 'token' => loc('Auth_accessToken')
+      %= text_field '', $_->{token}, readonly => 'readonly'
+      <p name="created">Created at: <%= $_->{created_date} %></p>
+      <p name="expires">Expires in: <%= $_->{expires_in} %></p>
+      % if ($_->{scope}) {
+      <p name="scope">Scope: <tt><%= join ',', @{$_->{scope}} %></tt></p>
+      % };
+      </li>
+      % }
+    </ul>
+    % };
+    
+    %# New access token:
+    %# if (stash('access_token')) {
+    %#= label_for 'access_token' => 'Access Token'
+    %#= text_field 'access_token', stash('access_token'), readonly => 'readonly'
+    %# <p name="expires">Expires in: <tt><%= stash 'expires_in' %></tt></p>
+    %# <p name="scope">Scope: <tt><%= stash 'scope' %></tt></p>
+    %# <p name="type">Token-Type: <tt><%= stash 'token_type' %></tt></p>
+    %# }
   </fieldset>
 </form>
diff --git a/lib/Kalamar/Plugin/Auth/templates/auth/clients.html.ep b/lib/Kalamar/Plugin/Auth/templates/auth/clients.html.ep
index 17be73e..ed50b95 100644
--- a/lib/Kalamar/Plugin/Auth/templates/auth/clients.html.ep
+++ b/lib/Kalamar/Plugin/Auth/templates/auth/clients.html.ep
@@ -10,9 +10,9 @@
 %   foreach (@$list) {
   <li class="client">
     <span class="client-name"><%= link_to $_->{client_name} => url_for('oauth-tokens', client_id => $_->{client_id}) %></span>
-    <span class="client-desc"><%= $_->{description} %></span>
-% if ($_->{url}) {
-    <span class="client-url"><a href="<%= $_->{url} %>"><%= $_->{url} %></a></span>
+    <span class="client-desc"><%= $_->{client_description} %></span>
+% if ($_->{client_url}) {
+    <span class="client-url"><a href="<%= $_->{client_url} %>"><%= $_->{client_url} %></a></span>
 % }
   </li>
 %   };
diff --git a/t/plugin/auth-oauth.t b/t/plugin/auth-oauth.t
index adb7378..4f0d67a 100644
--- a/t/plugin/auth-oauth.t
+++ b/t/plugin/auth-oauth.t
@@ -556,11 +556,12 @@
   name => 'MyApp2',
   'client-id' => 'fCBbQkA2NDA3MzM1Yw=='
 })
-  ->status_is(200)
-  ->attr_is('input[name=access_token]', 'value', 'jvgjbvjgzucgdwuiKHJK')
-  ->text_is('p[name=expires] tt', '31536000')
-  ->text_is('p[name=scope] tt', 'match_info search openid')
-  ->text_is('p[name=type] tt', 'Bearer')
+  ->status_is(302)
+  ->header_is('Location','/settings/oauth/client/fCBbQkA2NDA3MzM1Yw==')
+  ;
+
+$t->get_ok('/settings/oauth/client/fCBbQkA2NDA3MzM1Yw==')
+  ->text_is('div.notify-success', 'New access token created')
   ;
 
 
diff --git a/t/server/mock.pl b/t/server/mock.pl
index 43f4f5f..7e3eedb 100644
--- a/t/server/mock.pl
+++ b/t/server/mock.pl
@@ -544,8 +544,8 @@
   push @$list, {
     "client_id" => $tokens{new_client_id},
     "client_name" => $name,
-    "description" => $desc,
-    "url" => $url
+    "client_description" => $desc,
+    "client_url" => $url
   };
 
   # Confidential server application
@@ -577,6 +577,29 @@
   );
 };
 
+
+# Get token list
+post '/v1.0/oauth2/token/list' => sub {
+  my $c = shift;
+  return $c->render(json => [
+    {
+      "client_description" => "Nur ein Beispiel",
+      "client_id" => $tokens{new_client_id},
+      "client_name" => "Beispiel",
+      "client_url" => "",
+      "created_date" => "2021-04-14T19:40:26.742+02:00[Europe\/Berlin]",
+      "expires_in" => "31533851",
+      "scope" => [
+        "match_info",
+        "search",
+        "openid"
+      ],
+      "token" => "jhkhkjhk_hjgjsfz67i",
+      "user_authentication_time" => "2021-04-14T19:39:41.81+02:00[Europe\/Berlin]"
+    }
+  ]);
+};
+
 del '/v1.0/oauth2/client/deregister/:client_id' => sub {
   my $c = shift;
   my $client_id = $c->stash('client_id');