Move to single login page instead of seperate admin login

This commit is contained in:
Tom Bloor 2017-04-08 14:25:06 +01:00
parent a78de6ea8e
commit 30c80679be
9 changed files with 143 additions and 131 deletions

View file

@ -48,10 +48,9 @@ sub startup {
my $r = $self->routes; my $r = $self->routes;
$r->any('/')->to('root#index'); $r->get('/')->to('root#index');
$r->post('/')->to('root#auth_login');
$r->any('/logout')->to('root#auth_logout'); $r->any('/logout')->to('root#auth_logout');
$r->get('/admin')->to('admin#index');
$r->post('/admin')->to('admin#login');
my $api = $r->under('/api' => sub { my $api = $r->under('/api' => sub {
my $c = shift; my $c = shift;
@ -101,13 +100,17 @@ sub startup {
my $admin_routes = $r->under('/admin')->to('admin#under'); my $admin_routes = $r->under('/admin')->to('admin#under');
$admin_routes->get('/home')->to('admin#home'); $admin_routes->get('/')->to('admin#home');
$admin_routes->get('/tokens')->to('admin-tokens#index'); $admin_routes->get('/tokens')->to('admin-tokens#index');
$admin_routes->post('/tokens')->to('admin-tokens#create'); $admin_routes->post('/tokens')->to('admin-tokens#create');
$admin_routes->get('/tokens/:id')->to('admin-tokens#read'); $admin_routes->get('/tokens/:id')->to('admin-tokens#read');
$admin_routes->post('/tokens/:id')->to('admin-tokens#update'); $admin_routes->post('/tokens/:id')->to('admin-tokens#update');
$admin_routes->post('/tokens/:id/delete')->to('admin-tokens#delete'); $admin_routes->post('/tokens/:id/delete')->to('admin-tokens#delete');
my $user_routes = $r->under('/')->to('root#under');
$user_routes->get('/home')->to('root#home');
$self->hook( before_dispatch => sub { $self->hook( before_dispatch => sub {
my $self = shift; my $self = shift;

View file

@ -1,28 +1,16 @@
package Pear::LocalLoop::Controller::Admin; package Pear::LocalLoop::Controller::Admin;
use Mojo::Base 'Mojolicious::Controller'; use Mojo::Base 'Mojolicious::Controller';
sub index {
my $c = shift;
}
sub under { sub under {
my $c = shift; my $c = shift;
if ( $c->is_user_authenticated ) { if ( $c->is_user_authenticated ) {
return 1 if defined $c->current_user->administrator; return 1 if defined $c->current_user->administrator;
} $c->redirect_to('/home');
$c->redirect_to('/');
return undef;
}
sub login {
my $c = shift;
if ( $c->authenticate($c->param('email'), $c->param('password')) ) {
$c->redirect_to('/admin/home');
} else { } else {
$c->redirect_to('/admin'); $c->redirect_to('/');
} }
return undef;
} }
sub home { sub home {

View file

@ -3,7 +3,26 @@ use Mojo::Base 'Mojolicious::Controller';
sub index { sub index {
my $c = shift; my $c = shift;
}
sub under {
my $c = shift;
if ( $c->is_user_authenticated ) {
return 1;
}
$c->redirect_to('/');
return undef;
}
sub auth_login {
my $c = shift;
if ( $c->authenticate($c->param('email'), $c->param('password')) ) {
$c->redirect_to('/home');
} else {
$c->redirect_to('/');
}
} }
sub auth_logout { sub auth_logout {
@ -13,5 +32,9 @@ sub auth_logout {
$c->redirect_to('/'); $c->redirect_to('/');
} }
sub home {
my $c = shift;
$c->render(text => 'Root Home');
}
1; 1;

View file

@ -49,38 +49,36 @@ my $location_is = sub {
}; };
$t->get_ok('/admin') $t->get_ok('/admin')
->status_is(200)
->content_like(qr/Login/);
$t->ua->max_redirects(10);
$t->post_ok('/admin', form => {
email => 'user@example.com',
password => 'abc123',
})->status_is(200)
->content_like(qr/Hello!/, 'Redirected to root as not an admin');
$t->ua->max_redirects(0);
$t->get_ok('/admin/home')
->status_is(302) ->status_is(302)
->$location_is('/'); ->$location_is('/');
$t->ua->max_redirects(10);
$t->post_ok('/', form => {
email => 'user@example.com',
password => 'abc123',
})->status_is(200);
$t->ua->max_redirects(0);
$t->get_ok('/admin')
->status_is(302)
->$location_is('/home');
$t->get_ok('/logout') $t->get_ok('/logout')
->status_is(302) ->status_is(302)
->$location_is('/'); ->$location_is('/');
$t->get_ok('/admin/home') $t->get_ok('/admin')
->status_is(302) ->status_is(302)
->$location_is('/', 'Logged out'); ->$location_is('/', 'Logged out');
$t->ua->max_redirects(10); $t->ua->max_redirects(10);
$t->post_ok('/admin', form => { $t->post_ok('/', form => {
email => 'admin@example.com', email => 'admin@example.com',
password => 'abc123', password => 'abc123',
})->status_is(200) })->status_is(200);
->content_like(qr/Admin/);
$t->ua->max_redirects(0); $t->ua->max_redirects(0);
$t->get_ok('/admin/home') $t->get_ok('/admin')
->status_is(200) ->status_is(200)
->content_like(qr/Admin/); ->content_like(qr/Admin/);
@ -88,7 +86,7 @@ $t->get_ok('/logout')
->status_is(302) ->status_is(302)
->$location_is('/'); ->$location_is('/');
$t->get_ok('/admin/home') $t->get_ok('/admin')
->status_is(302) ->status_is(302)
->$location_is('/', 'Logged out'); ->$location_is('/', 'Logged out');

View file

@ -1,5 +1,5 @@
% layout 'default'; % layout 'admin';
% title 'LocalLoop Admin - Login'; % title 'Home';
% content_for css => begin % content_for css => begin
<style> <style>
body { body {
@ -22,24 +22,4 @@ body {
% end % end
% content_for javascript => begin % content_for javascript => begin
% end % end
<nav class="navbar navbar-toggleable-md fixed-top navbar-inverse bg-primary">
<button class="navbar-toggler navbar-toggler-right"
type="button"
data-toggle="collapse"
data-target="#navbarNav"
aria-controls="navbarNav"
aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="<%= url_for '/admin/home' %>"><%= title %></a>
<div class="collapse navbar-collapse" id="navbarNav">
<div class="navbar-nav">
<a class="nav-item nav-link" href="<%= url_for '/admin/tokens' %>">Tokens</a>
<a class="nav-item nav-link" href="#">Users</a>
</div>
</div>
</nav>
<div>Admin Pages</div> <div>Admin Pages</div>

View file

@ -1,49 +0,0 @@
% layout 'default';
% title 'LocalLoop Admin - Login';
% content_for css => begin
<style>
body {
background: whitesmoke;
padding-top: 54px;
}
.panel {
background: white;
padding: 16px;
-webkit-box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.2);
-moz-box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.2);
box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.2);
}
.login-form {
margin-top: 20%;
}
</style>
% end
% content_for javascript => begin
% end
<nav class="navbar fixed-top navbar-inverse bg-primary">
<a class="navbar-brand" href="#"><%= title %></a>
</nav>
<div class="container-fluid">
<div class="row justify-content-center">
<!-- Fluid Gird, this login box stay in the middle of screen -->
<div class="col-5">
<div class="login-form panel">
<form action="<%= url_for %>" method="post">
<div class="form-group">
<label for="login-email">Email Address</label>
<input type="email" id="login-email" class="form-control" name="email" required>
</div>
<div class="form-group">
<label for="login-password">Password</label>
<input type="password" id="login-password" class="form-control" name="password" required>
</div>
<input type="submit" class="btn btn-block btn-primary" value="Sign In">
</form>
</div>
</div>
</div>
</div><!-- Container fluid-->

View file

@ -1,5 +1,5 @@
% layout 'default'; % layout 'admin';
% title 'LocalLoop Admin - Login'; % title 'Tokens';
% content_for css => begin % content_for css => begin
<style> <style>
body { body {
@ -22,26 +22,6 @@ body {
% end % end
% content_for javascript => begin % content_for javascript => begin
% end % end
<nav class="navbar navbar-toggleable-md fixed-top navbar-inverse bg-primary">
<button class="navbar-toggler navbar-toggler-right"
type="button"
data-toggle="collapse"
data-target="#navbarNav"
aria-controls="navbarNav"
aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="<%= url_for '/admin/home' %>"><%= title %></a>
<div class="collapse navbar-collapse" id="navbarNav">
<div class="navbar-nav">
<a class="nav-item nav-link active" href="<%= url_for '/admin/tokens' %>">Tokens</a>
<a class="nav-item nav-link" href="#">Users</a>
</div>
</div>
</nav>
<div class="container"> <div class="container">
% if ( my $error = flash 'error' ) { % if ( my $error = flash 'error' ) {
<div class="alert alert-danger" role="alert"> <div class="alert alert-danger" role="alert">

View file

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>LocalLoop Admin - <%= title %></title>
<!-- Bootstrap and jQuery js -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
%= content_for 'css';
</head>
<body>
<nav class="navbar navbar-toggleable-md fixed-top navbar-inverse bg-primary">
<button class="navbar-toggler navbar-toggler-right"
type="button"
data-toggle="collapse"
data-target="#navbarNav"
aria-controls="navbarNav"
aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="<%= url_for '/admin' %>">LocalLoop Admin</a>
<div class="collapse navbar-collapse" id="navbarNav">
<div class="navbar-nav ml-auto">
<a class="nav-item nav-link<%= title eq 'Tokens' ? ' active' : '' %>" href="<%= url_for '/admin/tokens' %>">Tokens</a>
<a class="nav-item nav-link<%= title eq 'Users' ? ' active' : '' %>" href="#">Users</a>
<a class="nav-item nav-link" href="<%= url_for '/logout' %>">Logout</a>
</div>
</div>
</nav>
<%= content %>
%= content_for 'javascript';
</body>
</html>

View file

@ -1 +1,49 @@
Hello! % layout 'default';
% title 'LocalLoop Admin - Login';
% content_for css => begin
<style>
body {
background: whitesmoke;
padding-top: 54px;
}
.panel {
background: white;
padding: 16px;
-webkit-box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.2);
-moz-box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.2);
box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.2);
}
.login-form {
margin-top: 20%;
}
</style>
% end
% content_for javascript => begin
% end
<nav class="navbar fixed-top navbar-inverse bg-primary">
<a class="navbar-brand" href="#"><%= title %></a>
</nav>
<div class="container-fluid">
<div class="row justify-content-center">
<!-- Fluid Gird, this login box stay in the middle of screen -->
<div class="col-5">
<div class="login-form panel">
<form action="<%= url_for %>" method="post">
<div class="form-group">
<label for="login-email">Email Address</label>
<input type="email" id="login-email" class="form-control" name="email" required>
</div>
<div class="form-group">
<label for="login-password">Password</label>
<input type="password" id="login-password" class="form-control" name="password" required>
</div>
<input type="submit" class="btn btn-block btn-primary" value="Sign In">
</form>
</div>
</div>
</div>
</div><!-- Container fluid-->