Improved JWT handling and fixed test server behaviour

Change-Id: I169dbaa3afbb059e2b2c99bc2fc0f5f417ad57a5
diff --git a/Makefile.PL b/Makefile.PL
index 0e006e9..5de3390 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -21,6 +21,7 @@
     'Mojolicious::Plugin::MailException' => 0.18,
     'Mojolicious::Plugin::CHI' => 0.09,
     'Cache::FastMmap' => 0,
+    'Mojo::JWT' => 0.05,
     'File::Temp' => 1,
 
     # Currently on GitHub only (github.com/akron)
diff --git a/kalamar.conf b/kalamar.conf
index 29d5bf6..c748169 100644
--- a/kalamar.conf
+++ b/kalamar.conf
@@ -1,6 +1,6 @@
 # api => 'http://10.0.10.51:7070/api/v0.1/'
-# api => 'http://10.0.10.13:7070/api/v0.1/'
-my $api = 'http://localhost:9998/api/v0.1/';
+my $api = 'http://10.0.10.13:7070/api/v0.1/';
+#my $api = 'http://localhost:9998/api/v0.1/';
 
 {
   Search => {
diff --git a/lib/Kalamar.pm b/lib/Kalamar.pm
index 64220aa..1348219 100644
--- a/lib/Kalamar.pm
+++ b/lib/Kalamar.pm
@@ -63,12 +63,18 @@
   # Configuration framework
   $self->plugin('Config');
 
+  $self->log->info('Mode is ' . $self->mode);
+
   # Start fixture server
   if ($self->mode eq 'test') {
+
+    $self->log->info('Mount test server');
+
     $self->plugin(Mount => {
       '/api/v0.1' => $self->home->child('lib/Kalamar/Apps/test_backend.pl')
     });
 
+    # Fix api endpoint
     $self->config('Kalamar')->{api} = "/api/v0.1/";
   };
 
diff --git a/lib/Kalamar/Apps/test_backend.pl b/lib/Kalamar/Apps/test_backend.pl
index ba11f51..27566a2 100644
--- a/lib/Kalamar/Apps/test_backend.pl
+++ b/lib/Kalamar/Apps/test_backend.pl
@@ -2,13 +2,29 @@
 use Mojolicious::Lite;
 use Mojo::ByteStream 'b';
 use Mojo::Date;
+use strict;
+use warnings;
+use Mojo::JWT;
 
 # This is an API fake server with fixtures
 
+helper jwt => sub {
+  shift;
+  Mojo::JWT->new(
+    secret => 's3cr3t',
+    token_type => 'api_token',
+    expires => Mojo::Date->new(time + (3 * 34 * 60 * 60)),
+    claims => { @_ }
+  );
+};
+
+
+# Base page
 get '/' => sub {
   shift->render(text => 'Fake server available');
 };
 
+
 # Request API token
 get '/auth/apiToken' => sub {
   my $c = shift;
@@ -17,10 +33,10 @@
   my $auth = $c->req->headers->authorization;
 
   # Authorization missing or not basic
-  if (!$auth || $auth =~ s/\s*Basic\s+//gi) {
+  if (!$auth || $auth !~ s/\s*Basic\s+//gi) {
     return $c->render(
       json => {
-        error => [2, 'x']
+        error => [[2, 'x']]
       }
     );
   };
@@ -28,22 +44,27 @@
   # Decode header
   my ($username, $pwd) = @{b($auth)->b64_decode->split(':')->to_array};
 
-  if ($pwd eq 'test') {
 
-    # Render info with token
+  # the password is 'pass'
+  if ($pwd) {
+
+    # the password is 'pass'
+    if ($pwd eq 'pass') {
+
+      # Render info with token
+      return $c->render($c->jwt(username => $username));
+    };
+
     return $c->render(
       json => {
-        username => $username,
-        expires => Mojo::Date->new(time + (3 * 34 * 60 * 60)),
-        token => 'abcdefg',
-        token_type => 'api_token'
+        error => [[3, 'x']]
       }
     );
   };
 
   return $c->render(
     json => {
-      error => []
+      error => [[4, 'x']]
     }
   );
 };
diff --git a/lib/Kalamar/Controller/User.pm b/lib/Kalamar/Controller/User.pm
index 6d82dab..de47390 100644
--- a/lib/Kalamar/Controller/User.pm
+++ b/lib/Kalamar/Controller/User.pm
@@ -11,7 +11,7 @@
   $v->required('pwd', 'trim');
 
   if ($v->has_error) {
-    $c->notify(error => 'login fail');
+    $c->notify(error => 'Login fail');
   }
 
   # Login user
@@ -22,7 +22,7 @@
     $c->notify(success => 'Login successful!');
   };
 
-  # return $c->render(text => 'ok');
+  # Redirect to slash
   return $c->redirect_to('/');
 };
 
diff --git a/lib/Kalamar/Plugin/KalamarUser.pm b/lib/Kalamar/Plugin/KalamarUser.pm
index 3eda76a..cb4f0be 100644
--- a/lib/Kalamar/Plugin/KalamarUser.pm
+++ b/lib/Kalamar/Plugin/KalamarUser.pm
@@ -93,17 +93,35 @@
       # Login successful
       if (my $res = $tx->success) {
 
-        $c->app->log->debug("Transaction: " . $res->to_string);
-
+        # Get the java token
         my $jwt = $res->json;
 
+        # No java web token
         unless ($jwt) {
           $c->notify(error => 'Response is no valid JWT (remote)');
           return;
         };
 
-        # TODO: Deal with user return values.
+        # There is an error here
+        # Dealing with errors here
+        if (my $error = $jwt->{error}) {
+          if (ref $error eq 'ARRAY') {
+            foreach (@$error) {
+              if (ref($_) eq 'ARRAY') {
+                $c->notify(error => join(', ', @{$_}));
+              }
+              else {
+                $c->notify(error => 'There is an unknown JWT error');
+              };
+            };
+          }
+          else {
+            $c->notify(error => 'There is an unknown JWT error');
+          };
+          return;
+        };
 
+        # TODO: Deal with user return values.
         my $auth = $jwt->{token_type} . ' ' . $jwt->{token};
 
         $mojo->log->debug(qq!Login successful: "$user" with "$auth"!);
@@ -112,6 +130,7 @@
         $c->session(user => $user);
         $c->session(auth => $auth);
 
+        # Set stash info
         $c->stash(user => $user);
         $c->stash(auth => $auth);
 
@@ -121,12 +140,19 @@
       }
 
       elsif (my $e = $tx->error) {
+
+        # Notify the user
         $c->notify(
           error =>
             ($e->{code} ? $e->{code} . ': ' : '') .
             $e->{message} . ' for Login (remote)'
           );
-        $c->app->log->debug($e->{code} . ($e->{message} ? ' - ' . $e->{message} : ''));
+
+        # Log failure
+        $c->app->log->debug(
+          ($e->{code} ? $e->{code} . ' - ' : '') .
+            $e->{message}
+          );
       };
 
       $mojo->log->debug(qq!Login fail: "$user"!);
diff --git a/t/remote_user.t b/t/remote_user.t
index 2110b78..ac81b5c 100644
--- a/t/remote_user.t
+++ b/t/remote_user.t
@@ -5,25 +5,35 @@
 use Data::Dumper;
 
 $ENV{MOJO_USERAGENT_DEBUG} = 1;
+$ENV{MOJO_MODE} = 'test';
 
 my $t = Test::Mojo->new('Kalamar');
 
-$t->app->mode('test');
-
-# my $c = $t->app->build_controller;
-
 $t->get_ok('/')
   ->element_exists('form[action=/user/login] input[name=handle_or_email]');
 
-$t->post_ok('/user/login' => form => { handle_or_email => 'test' })
-  ->status_is(302);
+#$t->post_ok('/user/login' => form => { handle_or_email => 'test' })
+#  ->status_is(302);
 
-$t->post_ok('/user/login' => form => { handle_or_email => 'test', pwd => 'xyz' });
+# TODO: Use csrf!!!
+
+$t->post_ok('/user/login' => form => { handle_or_email => 'test', pwd => 'fail' })
+  ->status_is(302)
+  ->header_is('Location' => '/');
+
+$t->get_ok('/')
+  ->status_is(200)
+  ->element_exists('div.notify-error')
+  # ->element_exists('input[name=handle_or_email][value=test]')
+  ;
 
 done_testing;
 __END__
 
 
+
+
+
 ok(!$c->user->get('details'), 'User not logged in');
 
 # Login with user credentials
diff --git a/templates/layouts/main.html.ep b/templates/layouts/main.html.ep
index ed45db1..0b68f9f 100644
--- a/templates/layouts/main.html.ep
+++ b/templates/layouts/main.html.ep
@@ -27,10 +27,10 @@
 % content_for 'sidebar', begin
 <fieldset>
   %= form_for 'login', begin
-    <legend><span><%= loc 'login' %></span></legend>
-    <input type="text" name="handle_or_email" placeholder="<%= loc 'email' %>" />
+  <legend><span><%= loc 'login' %></span></legend>
+    %= text_field 'handle_or_email', placeholder => loc('email')
     <div>
-      <input type="password" name="pwd" placeholder="<%= loc 'pwd' %>" />
+      %= password_field 'pwd', placeholder => loc('pwd')
       <button type="submit"><span><%= loc 'go' %></span></button>
     </div>
   % end