Marketplace Uninstall Plugins

Change-Id: Ic5bd2aad8803097f37849cdcec549a76c5e17195
diff --git a/dev/scss/main/marketplace.scss b/dev/scss/main/marketplace.scss
index 05e1a1a..6f8a8aa 100644
--- a/dev/scss/main/marketplace.scss
+++ b/dev/scss/main/marketplace.scss
@@ -3,8 +3,6 @@
 /*
 * Styles for marketplace
 */
-
-
 ul.plugin-list, ul.plugin_in-list {
   list-style-type: none;
   padding-left: 1.5em;
diff --git a/lib/Kalamar/Plugin/Auth.pm b/lib/Kalamar/Plugin/Auth.pm
index 9d65b5b..2bcfeda 100644
--- a/lib/Kalamar/Plugin/Auth.pm
+++ b/lib/Kalamar/Plugin/Auth.pm
@@ -120,6 +120,11 @@
           instdate=> 'Installationsdatum',
           install => 'Installieren',
           installFail => 'Plugin konnte nicht installiert werden',
+          uninstallFail => 'Plugin konnte nicht deinstalliert werden',
+          marketplaceFail => {
+            -long => 'Die Plugins konnten leider nicht angezeigt werden.',
+            short => 'Erneut versuchen'
+            },
           oauthUnregister => {
             -long => 'Möchten sie <span class="client-name"><%= $client_name %></span> wirklich löschen?',
             short => 'Löschen'
@@ -189,6 +194,12 @@
           install => 'Install',
           uninstall => 'Uninstall',
           installFail => 'Plugin could not be installed',
+          uninstallFail => 'Plugin could not be uninstalled',
+          uninstallFail => 'Plugin could not be uninstalled',
+          marketplaceFail => {
+            -long => 'Plugins could not be displayed.',
+            short => 'Try again'
+            },
           oauthUnregister => {
             -long => 'Do you really want to unregister <span class="client-name"><%= $client_name %></span>?',
             short => 'Unregister'
@@ -1055,7 +1066,7 @@
       $c->render_later;
       my $promiselist = $c->auth->plugin_list_p;
       my $promiseinlist = $c->auth->plugin_listin_p;
-
+      my $fl = 0;
       Mojo::Promise->all($promiselist, $promiseinlist)-> then(
         sub {
           my ($promiselist, $promiseinlist) = @_;
@@ -1068,30 +1079,36 @@
               @$clean_pllist = grep{!($_->{client_id} eq $entry->{client_id})} @$clean_pllist ;
             }
           }
-          $c->stash('plugin_list', $clean_pllist);
-        }
-      )->catch(
-        sub {
-          return;
-        }
-      )->finally(
-        sub {
-          return $c->render(template => 'auth/marketplace');
-        }
-      )->wait;
-    }
-  )->name('marketplace');
+            $c->stash('plugin_list', $clean_pllist);
+          }
+          )
+          ->catch(
+            sub { 
+              $fl = 1;
+              }
+              )
+              ->finally(
+                sub {
+                  if($fl){
+                    return $c->render(template => 'auth/marketplace-fail')
+                  }
+                  return $c->render(template => 'auth/marketplace');
+                  }
+              )->wait;
+         }
+     )->name('marketplace');
 
-  # Route to install plugin
-  $r->post('/settings/marketplace')->to(
-    cb => sub {
-      my $c = shift;
-      _set_no_cache($c->res->headers);
-      my $v = $c->validation;
-      $v->required('client-id');
 
-      if ($v->has_error) {
-        return $c->render(
+   # Route to install plugin
+    $r->post('/settings/marketplace/install')->to(
+      cb => sub {
+        my $c = shift;
+        _set_no_cache($c->res->headers);
+        my $v = $c->validation;
+        $v->required('client-id');
+
+        if ($v->has_error) {
+          return $c->render(
           json => [],
           status => 400
         );
@@ -1107,71 +1124,125 @@
       my $mclient_id = $v->param('client-id');
       $c->render_later;
 
-      state $p_url = Mojo::URL->new($c->korap->api)->path('plugins/install');
-
-      return $c->korap_request(post => $p_url, {} => form => {
-        super_client_id => $client_id,
-        super_client_secret => $client_secret,
-        client_id => $mclient_id
-      })->then(
-        sub {
-          my $tx = shift;
-          my $json = $tx->result->json;
-          # Response is fine
-          if ($tx->res->is_success) {
-            return Mojo::Promise->resolve($json);
-          };
-          #Log errors
-          $c->log->error($tx->res->to_string);
-          # Failure
-          return Mojo::Promise->reject;
-        }
-      )->catch(
-        sub {
-          $c->notify('error' => $c->loc('Auth_installFail'));
-        }
-      )->finally(
-        sub {
-          return $c->redirect_to('marketplace');
-        }
-      );
-    }
-  )->name('install-plugin');
-
-
-  # Route to OAuth settings
-  $r->get('/settings/oauth')->to(
-    cb => sub {
-      my $c = shift;
-
-      _set_no_cache($c->res->headers);
-
-      unless ($c->auth->token) {
-        return $c->render(
-          template => 'exception',
-          msg => $c->loc('Auth_authenticationFail'),
-          status => 401
+        state $p_url = Mojo::URL->new($c->korap->api)->path('plugins/install');
+        
+        return $c->korap_request(post => $p_url, {} => form => {
+          super_client_id => $client_id,
+          super_client_secret => $client_secret,
+          client_id => $mclient_id
+          })->then( 
+          sub {
+            my $tx = shift;
+            my $json = $tx->result->json;
+            # Response is fine
+            if ($tx->res->is_success) {
+              return Mojo::Promise->resolve($json);
+              };
+            #Log errors
+            $c->log->error($tx->res->to_string);
+            # Failure
+            return Mojo::Promise->reject;
+            }
+            )
+           ->catch(
+            sub {
+              $c->notify('error' => $c->loc('Auth_installFail'));
+            }
+            )
+         ->finally(
+            sub {
+              return $c->redirect_to('marketplace');
+            }
         );
-      };
+      }
+    )->name('install-plugin');
 
-      # Wait for async result
-      $c->render_later;
+    # Route to plugin deinstallation
+    $r->post('/settings/marketplace/uninstall')->to(
+      cb => sub {
+        my $c = shift;
+        _set_no_cache($c->res->headers);
+        my $v = $c->validation;
+        $v->required('client-id');
+        
+        if ($v->has_error) {
+          return $c->render(
+          json => [],
+          status => 400
+          );
+        };
 
-      $c->auth->client_list_p->then(
-        sub {
-          $c->stash('client_list' => shift);
-        }
-      )->catch(
-        sub {
-          return;
-        }
-      )->finally(
-        sub {
-          return $c->render(template => 'auth/clients')
-        }
-      );
-    }
-  )->name('oauth-settings');
+        unless ($c->auth->token) {
+          return $c->render(
+            content => 'Unauthorized',
+            status => 401
+          );
+        };
+
+        my $uclient_id = $v->param('client-id');
+     
+        $c->render_later;
+        state $s_url = Mojo::URL->new($c->korap->api)->path('plugins/uninstall');
+        return $c->korap_request(post => $s_url, {} => form => {
+          super_client_id => $client_id,
+          super_client_secret => $client_secret,
+          client_id => $uclient_id
+         })->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($tx->res->to_string);
+            # Failure
+            return Mojo::Promise->reject($json // 'No response');
+            }
+         )
+          ->catch(
+            sub {
+              $c->notify('error' => $c->loc('Auth_uninstallFail'));
+            }
+            )
+          ->finally(
+            sub {
+              return $c->redirect_to('marketplace');
+            }
+        );
+      }
+    )->name('uninstall-plugin');
+
+    # Route to OAuth settings
+    $r->get('/settings/oauth')->to(
+      cb => sub {
+        my $c = shift;
+        _set_no_cache($c->res->headers);
+        unless ($c->auth->token) {
+          return $c->render(
+            template => 'exception',
+            msg => $c->loc('Auth_authenticationFail'),
+            status => 401
+          );
+        };
+        # Wait for async result
+        $c->render_later;
+        $c->auth->client_list_p->then(
+          sub {
+            $c->stash('client_list' => shift);
+          }
+        )->catch(
+          sub {
+            return;
+          }
+        )->finally(
+          sub {
+            return $c->render(template => 'auth/clients')
+          }
+        );
+      }
+    )->name('oauth-settings');
+
 
   # Route to oauth client registration
   $r->post('/settings/oauth/register')->to(
diff --git a/lib/Kalamar/Plugin/Auth/templates/auth/marketplace-fail.html.ep b/lib/Kalamar/Plugin/Auth/templates/auth/marketplace-fail.html.ep
new file mode 100644
index 0000000..437e067
--- /dev/null
+++ b/lib/Kalamar/Plugin/Auth/templates/auth/marketplace-fail.html.ep
@@ -0,0 +1,8 @@
+% extends 'settings', title => loc('Auth_marketplace'), page => 'oauth';
+
+%= page_title
+
+<%== loc('Auth_marketplaceFail') %>
+%= form_for 'marketplace', class => 'form-table', begin
+  <input type="submit" class="form-submit" value="<%= loc 'Auth_marketplaceFail_short' %>" /> 
+% end
diff --git a/lib/Kalamar/Plugin/Auth/templates/auth/marketplace.html.ep b/lib/Kalamar/Plugin/Auth/templates/auth/marketplace.html.ep
index 0acce2d..60f2294 100644
--- a/lib/Kalamar/Plugin/Auth/templates/auth/marketplace.html.ep
+++ b/lib/Kalamar/Plugin/Auth/templates/auth/marketplace.html.ep
@@ -3,7 +3,7 @@
 %= page_title
 
 % my $pluginsin = stash("pluginsin_list");
-  % if (@$pluginsin) {
+  % if ($pluginsin && @$pluginsin) {
   <ul class="plugin_in-list">
     %foreach (@$pluginsin) {
     <li class="plugin">
@@ -17,8 +17,12 @@
       %if ($_->{installed_date}) {
         <p class="inst_date"><%=loc('Auth_instdate')%>: <%= $_->{installed_date} %></p>
       % }
+      %= form_for 'uninstall-plugin', class => 'mkplace', method => "POST",  begin
+      %= hidden_field 'client-id' => $_->{client_id}
+      <input type="submit" class="form-submit" value="<%= loc('Auth_uninstall')%>"/>
+      % end
     </li>
-    %};  
+    %};
   </ul>
 % };
 
@@ -27,7 +31,7 @@
 % my $plugins = stash('plugin_list');
 
 
-% if (@$plugins) {
+% if ($plugins && @$plugins) {
 <ul class="plugin-list">
 %   foreach (@$plugins) {
   <li class="plugin">
diff --git a/t/plugin/auth-oauth.t b/t/plugin/auth-oauth.t
index 16b0f6e..a67b98b 100644
--- a/t/plugin/auth-oauth.t
+++ b/t/plugin/auth-oauth.t
@@ -1021,16 +1021,13 @@
   ->text_is('ul.plugin-list > li + li >p.plugin-desc','Description Plugin 2')
   ;
 
-$t->ua->max_redirects(0);
-
-$t->post_ok('/settings/marketplace', form => {'client-id' => '52abc'})
+$t->post_ok('/settings/marketplace/install', form => {'client-id' => '52abc'})
   ->status_is(302)
   ->header_is(location => '/settings/marketplace')
   ;
-
 $t->ua->max_redirects(1);
 
-$t->post_ok('/settings/marketplace', form => {'client-id' => '52abc'})
+$t->post_ok('/settings/marketplace/install', form => {'client-id' => '52abc'})
   ->status_is(200)
   ->element_exists('ul.plugin-list')
   ->element_exists('ul.plugin-list > li')
@@ -1045,18 +1042,35 @@
 
 $t->ua->max_redirects(0);
 
- $t->post_ok('/settings/marketplace', form => {'client-id' => 'unsinn31'})
+ $t->post_ok('/settings/marketplace/install', form => {'client-id' => 'unsinn31'})
   ->status_is(302)
   ->header_is(location => '/settings/marketplace')
   ;
 
 $t->ua->max_redirects(1);
 
-$t->post_ok('/settings/marketplace', form => {'client-id' => 'unsinn31'})
+$t->post_ok('/settings/marketplace/install', form => {'client-id' => 'unsinn31'})
   ->status_is(200)
   ->text_is('div.notify-error', 'Plugin could not be installed')
   ;
 
+$t->post_ok('/settings/marketplace/uninstall', form => {'client-id' => '52abc'})
+  ->status_is(200)
+  ->element_exists('ul.plugin-list')
+  ->element_exists('ul.plugin-list > li')
+  ->text_is('span.client-name','Plugin 1')
+  ->text_is('p.plugin-desc','Description Plugin 1')
+  ->element_exists('ul.plugin-list > li + li')
+  ->text_is('ul.plugin-list > li + li >span.client-name','Plugin 2')
+  ->text_is('ul.plugin-list > li + li >p.plugin-desc','Description Plugin 2')
+  ->element_exists_not('ul.plugin_in-list')
+  ;
+
+$t->post_ok('/settings/marketplace/uninstall', form => {'client-id' => 'quatsch12'})
+  ->status_is(200)
+  ->text_is('div.notify-error', 'Plugin could not be uninstalled')
+  ;
+
 $t->ua->max_redirects(0);
 
 $t->get_ok(Mojo::URL->new('/settings/oauth/authorize')->query({
diff --git a/t/server/mock.pl b/t/server/mock.pl
index e76f8c5..e27542a 100644
--- a/t/server/mock.pl
+++ b/t/server/mock.pl
@@ -649,6 +649,35 @@
   );
 };
 
+# Mock API plugin uninstallation
+post '/v1.0/plugins/uninstall' => sub {
+  my $c = shift;
+  my $v = $c->validation;
+  $v->required('super_client_id');
+  $v->required('super_client_secret');
+  $v->required('client_id');
+  if ($v->has_error) {
+    return $c->render(
+      json => [],
+      status => 400
+    );
+  };
+  my $cl_id = $c->param('client_id');
+
+  my $plin_list =  $c->app->defaults('oauth.pluginin_list');
+  my @new_list = grep{!($_->{client_id} eq $cl_id)}@$plin_list;
+  $c->app->defaults('oauth.pluginin_list' => \@new_list);
+  
+  if(scalar @new_list eq scalar @$plin_list){
+    return $c->render(
+      status => 404
+     );
+  }
+  return $c->render(
+   json => $c->stash('oauth.pluginin_list'),
+    status => 200
+  );
+  };
 
 # Register a client
 post '/v1.0/oauth2/client/list' => sub {