Move to single login page instead of seperate admin login
This commit is contained in:
parent
a78de6ea8e
commit
30c80679be
9 changed files with 143 additions and 131 deletions
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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');
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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-->
|
|
||||||
|
|
|
@ -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">
|
||||||
|
|
41
templates/layouts/admin.html.ep
Normal file
41
templates/layouts/admin.html.ep
Normal 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>
|
|
@ -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-->
|
||||||
|
|
||||||
|
|
Reference in a new issue