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