Fix unknown client handling and replace client info API (fixes #181)

Change-Id: I074f6b8f2b72807b635fa900da3d6a9bd9a3afe1
diff --git a/Changes b/Changes
index dab8ece..e5cb2a6 100755
--- a/Changes
+++ b/Changes
@@ -17,6 +17,8 @@
         - Introduce start-with-backend command via plugin. (diewald)
         - Update Mojolicious for security reasons. (diewald)
         - Fix terser installation (fixes #182). (diewald)
+        - Replaced list with info API request for client information
+          in OAuth registration flow. (diewald)
 
         WARNING: Mojolicious 9.31 is a security update -
           updating is highly recommended.
diff --git a/lib/Kalamar/Plugin/Auth.pm b/lib/Kalamar/Plugin/Auth.pm
index ec83b02..322019b 100644
--- a/lib/Kalamar/Plugin/Auth.pm
+++ b/lib/Kalamar/Plugin/Auth.pm
@@ -427,6 +427,40 @@
     }
   );
 
+  # Get info for registered client
+  $app->helper(
+    'auth.client_info_p' => sub {
+      my $c = shift;
+      my $client_id = shift;
+
+      # Get list of registered clients
+      my $r_url = Mojo::URL->new($c->korap->api)->path('oauth2/client/')->path($client_id);
+
+      my $form = {
+        super_client_id => $client_id,
+        super_client_secret => $client_secret,
+      };
+
+      # 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
+          return Mojo::Promise->reject($json->{error_description} // 'Client unknown');
+        }
+      );
+    }
+  );
+
 
   # Get a list of registered clients
   $app->helper(
@@ -1115,27 +1149,16 @@
 
         my $client_id = $v->param('client_id');
 
-        my $client_information = $c->auth->client_list_p->then(
+        my $client_information = $c->auth->client_info_p($client_id)->then(
           sub {
-            my $clients = shift;
-            foreach (@$clients) {
-              if ($_->{client_id} eq $client_id) {
-                $c->stash(client_name => $_->{'client_name'});
-                $c->stash(client_type => $_->{'client_type'});
-                $c->stash(client_desc => $_->{'client_description'});
-                $c->stash(client_url => $_->{'client_url'});
-                $c->stash(redirect_uri_server => $_->{'client_redirect_uri'});
-                last;
-              };
-            };
+            my $cl = shift;
+            $c->stash(client_name => $cl->{'client_name'});
+            $c->stash(client_type => $cl->{'client_type'});
+            $c->stash(client_desc => $cl->{'client_description'});
+            $c->stash(client_url => $cl->{'client_url'});
+            $c->stash(redirect_uri_server => $cl->{'client_redirect_uri'});
           }
-        )->catch(
-          sub {
-            $c->stash(client_type => 'PUBLIC');
-            $c->stash(client_name => $v->param('client_id'));
-            return;
-          }
-        )->finally(
+        )->then(
           sub {
 
             # Get auth token
@@ -1149,6 +1172,12 @@
             # Grant authorization
             return $c->render(template => 'auth/grant_scope');
           }
+        )->catch(
+          sub {
+            my $error = shift;
+            $c->notify(error => $error);
+            return $c->redirect_to('oauth-settings');
+          }
         );
       }
     )->name('oauth-grant-scope');
diff --git a/t/plugin/auth-oauth.t b/t/plugin/auth-oauth.t
index 63c1df2..b07645e 100644
--- a/t/plugin/auth-oauth.t
+++ b/t/plugin/auth-oauth.t
@@ -772,6 +772,16 @@
   ->text_is('div.notify-error', 'Some fields are invalid')
   ;
 
+# OAuth client authorization flow
+$t->get_ok(Mojo::URL->new('/settings/oauth/authorize?client_id=abc'))
+  ->status_is(302)
+  ->header_is('location','/settings/oauth')
+  ;
+
+$t->get_ok('/settings/oauth/')
+  ->text_is('div.notify-error', 'Unknown client with abc.')
+  ;
+
 # Logout
 $t->get_ok('/x/expired-with-wrong-refresh');
 
diff --git a/t/server/mock.pl b/t/server/mock.pl
index 3c1f74f..ab0c34d 100644
--- a/t/server/mock.pl
+++ b/t/server/mock.pl
@@ -53,7 +53,7 @@
 helper 'add_client' => sub {
   my $c = shift;
   my $client = shift;
-  my $list = $c->app->defaults('oauth.client_list');
+  my $list = $c->stash('oauth.client_list');
   push @$list, $client;
 };
 
@@ -579,6 +579,47 @@
   );
 };
 
+# Get client info
+post '/v1.0/oauth2/client/:client_id' => sub {
+  my $c = shift;
+
+  # Validate input
+  my $v = $c->validation;
+  $v->required('super_client_id');
+  $v->required('super_client_secret');
+
+  if ($v->has_error) {
+    return $c->render(
+      status => 400,
+      json => {
+        error_description => "No super client",
+        error => "no_superclient"
+      }
+    );
+  };
+
+  my $client_id = $c->stash('client_id');
+
+  my $list = $c->stash('oauth.client_list');
+
+  foreach (@$list) {
+    if ($_->{client_id} eq $client_id) {
+      return $c->render(
+        json => $_,
+        status => 200
+      );
+    };
+  };
+
+  return $c->render(
+    json => {
+      error_description => "Unknown client with $client_id.",
+      error => "invalid_client"
+    },
+    status => 401
+  );
+};
+
 
 # Get token list
 post '/v1.0/oauth2/token/list' => sub {