Remember application state on login (issue #20)

Change-Id: Ie72bb05ee53080986749e74b87fc4f71b343c270
diff --git a/lib/Kalamar.pm b/lib/Kalamar.pm
index 43e98b6..7eec66c 100644
--- a/lib/Kalamar.pm
+++ b/lib/Kalamar.pm
@@ -8,11 +8,9 @@
 # Minor version - may be patched from package.json
 our $VERSION = '0.26';
 
-# TODO: Use CSRF!!!
 # TODO: The FAQ-Page has a contact form for new questions
 # TODO: Embed query serialization
 # TODO: Embed collection statistics
-# TODO: Show further meta data per click
 # TODO: Implement tab opener for matches and the tutorial
 # TODO: Implement a "projects" system
 
@@ -130,7 +128,8 @@
     'TagHelpers::MailToChiffre', # Obfuscate email addresses
     'KalamarHelpers',            # Specific Helpers for Kalamar
     'KalamarUser',               # Specific Helpers for Kalamar
-    'ClientIP'                   # Get client IP from X-Forwarded-For
+    'ClientIP',                  # Get client IP from X-Forwarded-For
+    'ClosedRedirect'             # Redirect with OpenRedirect protection
   ) {
     $self->plugin($_);
   };
diff --git a/lib/Kalamar/Controller/User.pm b/lib/Kalamar/Controller/User.pm
index a77062d..6eb0372 100644
--- a/lib/Kalamar/Controller/User.pm
+++ b/lib/Kalamar/Controller/User.pm
@@ -10,9 +10,13 @@
   $v->required('handle_or_email', 'trim');
   $v->required('pwd', 'trim');
   $v->csrf_protect;
+  $v->optional('fwd')->closed_redirect;
 
   if ($v->has_error) {
-    if ($v->has_error('csrf_token')) {
+    if ($v->has_error('fwd')) {
+      $c->notify(error => $c->loc('Auth_openRedirectFail'));
+    }
+    elsif ($v->has_error('csrf_token')) {
       $c->notify(error => $c->loc('Auth_csrfFail'));
     }
     else {
@@ -36,7 +40,7 @@
   $c->flash(handle_or_email => $v->param('handle_or_email'));
 
   # Redirect to slash
-  return $c->redirect_to('index');
+  return $c->relative_redirect_to($v->param('fwd') // 'index');
 };