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;
|
||||
$r->any('/')->to('root#index');
|
||||
$r->get('/')->to('root#index');
|
||||
$r->post('/')->to('root#auth_login');
|
||||
$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 $c = shift;
|
||||
|
||||
|
@ -101,13 +100,17 @@ sub startup {
|
|||
|
||||
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->post('/tokens')->to('admin-tokens#create');
|
||||
$admin_routes->get('/tokens/:id')->to('admin-tokens#read');
|
||||
$admin_routes->post('/tokens/:id')->to('admin-tokens#update');
|
||||
$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 {
|
||||
my $self = shift;
|
||||
|
||||
|
|
|
@ -1,28 +1,16 @@
|
|||
package Pear::LocalLoop::Controller::Admin;
|
||||
use Mojo::Base 'Mojolicious::Controller';
|
||||
|
||||
sub index {
|
||||
my $c = shift;
|
||||
}
|
||||
|
||||
sub under {
|
||||
my $c = shift;
|
||||
|
||||
if ( $c->is_user_authenticated ) {
|
||||
return 1 if defined $c->current_user->administrator;
|
||||
}
|
||||
$c->redirect_to('/');
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub login {
|
||||
my $c = shift;
|
||||
|
||||
if ( $c->authenticate($c->param('email'), $c->param('password')) ) {
|
||||
$c->redirect_to('/admin/home');
|
||||
$c->redirect_to('/home');
|
||||
} else {
|
||||
$c->redirect_to('/admin');
|
||||
$c->redirect_to('/');
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub home {
|
||||
|
|
|
@ -3,7 +3,26 @@ use Mojo::Base 'Mojolicious::Controller';
|
|||
|
||||
sub index {
|
||||
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 {
|
||||
|
@ -13,5 +32,9 @@ sub auth_logout {
|
|||
$c->redirect_to('/');
|
||||
}
|
||||
|
||||
sub home {
|
||||
my $c = shift;
|
||||
$c->render(text => 'Root Home');
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -49,38 +49,36 @@ my $location_is = sub {
|
|||
};
|
||||
|
||||
$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)
|
||||
->$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')
|
||||
->status_is(302)
|
||||
->$location_is('/');
|
||||
|
||||
$t->get_ok('/admin/home')
|
||||
$t->get_ok('/admin')
|
||||
->status_is(302)
|
||||
->$location_is('/', 'Logged out');
|
||||
|
||||
$t->ua->max_redirects(10);
|
||||
$t->post_ok('/admin', form => {
|
||||
$t->post_ok('/', form => {
|
||||
email => 'admin@example.com',
|
||||
password => 'abc123',
|
||||
})->status_is(200)
|
||||
->content_like(qr/Admin/);
|
||||
})->status_is(200);
|
||||
|
||||
$t->ua->max_redirects(0);
|
||||
$t->get_ok('/admin/home')
|
||||
$t->get_ok('/admin')
|
||||
->status_is(200)
|
||||
->content_like(qr/Admin/);
|
||||
|
||||
|
@ -88,7 +86,7 @@ $t->get_ok('/logout')
|
|||
->status_is(302)
|
||||
->$location_is('/');
|
||||
|
||||
$t->get_ok('/admin/home')
|
||||
$t->get_ok('/admin')
|
||||
->status_is(302)
|
||||
->$location_is('/', 'Logged out');
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
% layout 'default';
|
||||
% title 'LocalLoop Admin - Login';
|
||||
% layout 'admin';
|
||||
% title 'Home';
|
||||
% content_for css => begin
|
||||
<style>
|
||||
body {
|
||||
|
@ -22,24 +22,4 @@ body {
|
|||
% end
|
||||
% content_for javascript => begin
|
||||
% 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>
|
||||
|
|
|
@ -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';
|
||||
% title 'LocalLoop Admin - Login';
|
||||
% layout 'admin';
|
||||
% title 'Tokens';
|
||||
% content_for css => begin
|
||||
<style>
|
||||
body {
|
||||
|
@ -22,26 +22,6 @@ body {
|
|||
% end
|
||||
% content_for javascript => begin
|
||||
% 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">
|
||||
% if ( my $error = flash 'error' ) {
|
||||
<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