Password Change form for all users
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
* [#75] Device module inventory report / search
|
* [#75] Device module inventory report / search
|
||||||
* [#70] SSID Search (port)
|
* [#70] SSID Search (port)
|
||||||
* [#72] Search on Vendor / OUI
|
* [#72] Search on Vendor / OUI
|
||||||
|
* Password Change form for all users
|
||||||
|
|
||||||
[ENHANCEMENTS]
|
[ENHANCEMENTS]
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ use App::Netdisco::Web::AdminTask;
|
|||||||
use App::Netdisco::Web::TypeAhead;
|
use App::Netdisco::Web::TypeAhead;
|
||||||
use App::Netdisco::Web::PortControl;
|
use App::Netdisco::Web::PortControl;
|
||||||
use App::Netdisco::Web::Statistics;
|
use App::Netdisco::Web::Statistics;
|
||||||
|
use App::Netdisco::Web::Password;
|
||||||
|
|
||||||
sub _load_web_plugins {
|
sub _load_web_plugins {
|
||||||
my $plugin_list = shift;
|
my $plugin_list = shift;
|
||||||
|
|||||||
@@ -29,38 +29,38 @@ hook 'before' => sub {
|
|||||||
};
|
};
|
||||||
|
|
||||||
get qr{^/(?:login(?:/denied)?)?} => sub {
|
get qr{^/(?:login(?:/denied)?)?} => sub {
|
||||||
template 'index', { return_url => params->{return_url} };
|
template 'index', { return_url => param('return_url') };
|
||||||
};
|
};
|
||||||
|
|
||||||
# override default login_handler so we can log access in the database
|
# override default login_handler so we can log access in the database
|
||||||
post '/login' => sub {
|
post '/login' => sub {
|
||||||
my $mode = (request->is_ajax ? 'API' : 'Web');
|
my $mode = (request->is_ajax ? 'API' : 'Web');
|
||||||
my ($success, $realm) = authenticate_user(
|
my ($success, $realm) = authenticate_user(
|
||||||
params->{username}, params->{password}
|
param('username'), param('password')
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($success) {
|
if ($success) {
|
||||||
session logged_in_user => params->{username};
|
session logged_in_user => param('username');
|
||||||
session logged_in_user_realm => $realm;
|
session logged_in_user_realm => $realm;
|
||||||
|
|
||||||
schema('netdisco')->resultset('UserLog')->create({
|
schema('netdisco')->resultset('UserLog')->create({
|
||||||
username => session('logged_in_user'),
|
username => session('logged_in_user'),
|
||||||
userip => request->remote_address,
|
userip => request->remote_address,
|
||||||
event => "Login ($mode)",
|
event => "Login ($mode)",
|
||||||
details => params->{return_url},
|
details => param('return_url'),
|
||||||
});
|
});
|
||||||
|
|
||||||
return if request->is_ajax;
|
return if request->is_ajax;
|
||||||
redirect params->{return_url};
|
redirect param('return_url');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
session->destroy;
|
session->destroy;
|
||||||
|
|
||||||
schema('netdisco')->resultset('UserLog')->create({
|
schema('netdisco')->resultset('UserLog')->create({
|
||||||
username => params->{username},
|
username => param('username'),
|
||||||
userip => request->remote_address,
|
userip => request->remote_address,
|
||||||
event => "Login Failure ($mode)",
|
event => "Login Failure ($mode)",
|
||||||
details => params->{return_url},
|
details => param('return_url'),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (request->is_ajax) {
|
if (request->is_ajax) {
|
||||||
@@ -69,7 +69,7 @@ post '/login' => sub {
|
|||||||
else {
|
else {
|
||||||
vars->{login_failed}++;
|
vars->{login_failed}++;
|
||||||
forward uri_for('/login'),
|
forward uri_for('/login'),
|
||||||
{ login_failed => 1, return_url => params->{return_url} },
|
{ login_failed => 1, return_url => param('return_url') },
|
||||||
{ method => 'GET' };
|
{ method => 'GET' };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
51
Netdisco/lib/App/Netdisco/Web/Password.pm
Normal file
51
Netdisco/lib/App/Netdisco/Web/Password.pm
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package App::Netdisco::Web::Password;
|
||||||
|
|
||||||
|
use Dancer ':syntax';
|
||||||
|
use Dancer::Plugin::DBIC;
|
||||||
|
use Dancer::Plugin::Auth::Extensible;
|
||||||
|
use Dancer::Plugin::Passphrase;
|
||||||
|
|
||||||
|
use Digest::MD5 ();
|
||||||
|
|
||||||
|
sub _make_password {
|
||||||
|
my $pass = (shift || passphrase->generate_random);
|
||||||
|
if (setting('safe_password_store')) {
|
||||||
|
return passphrase($pass)->generate;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Digest::MD5::md5_hex($pass),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _bail {
|
||||||
|
var('passchange_failed' => 1);
|
||||||
|
return template 'password.tt';
|
||||||
|
}
|
||||||
|
|
||||||
|
any ['get', 'post'] => '/password' => require_login sub {
|
||||||
|
my $old = param('old');
|
||||||
|
my $new = param('new');
|
||||||
|
my $confirm = param('confirm');
|
||||||
|
|
||||||
|
if (request->is_post) {
|
||||||
|
unless ($old and $new and $confirm and ($new eq $confirm)) {
|
||||||
|
return _bail();
|
||||||
|
}
|
||||||
|
|
||||||
|
my ($success, $realm) = authenticate_user(
|
||||||
|
session('logged_in_user'), $old
|
||||||
|
);
|
||||||
|
return _bail() if not $success;
|
||||||
|
|
||||||
|
my $user = schema('netdisco')->resultset('User')
|
||||||
|
->find({username => session('logged_in_user')});
|
||||||
|
return _bail() if not $user;
|
||||||
|
|
||||||
|
$user->update({password => _make_password($new)});
|
||||||
|
var('passchange_ok' => 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template 'password.tt';
|
||||||
|
};
|
||||||
|
|
||||||
|
true;
|
||||||
@@ -38,8 +38,8 @@
|
|||||||
[% IF NOT session.logged_in_user %]
|
[% IF NOT session.logged_in_user %]
|
||||||
<form class="nd_login-form" method="post" action="[% uri_for('/login') %]">
|
<form class="nd_login-form" method="post" action="[% uri_for('/login') %]">
|
||||||
<div class="form-horizontal">
|
<div class="form-horizontal">
|
||||||
<input placeholder="Username" class="span2" name="username" type="text"/>
|
<input placeholder="Username" class="span2" name="username" type="text" required="required"/>
|
||||||
<input placeholder="Password" class="span2" name="password" type="password"/>
|
<input placeholder="Password" class="span2" name="password" type="password" required="required"/>
|
||||||
<button type="submit" class="btn btn-info">Log In</button>
|
<button type="submit" class="btn btn-info">Log In</button>
|
||||||
</div>
|
</div>
|
||||||
[% IF params.return_url %]
|
[% IF params.return_url %]
|
||||||
|
|||||||
@@ -157,7 +157,9 @@
|
|||||||
[% session.logged_in_user | html_entity %] <b class="caret"></b>
|
[% session.logged_in_user | html_entity %] <b class="caret"></b>
|
||||||
</a>
|
</a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="[% uri_for('/about') %]">About</a></li>
|
[% IF NOT user_has_role('ldap') %]
|
||||||
|
<li><a href="[% uri_for('/password') %]">Change Password</a></li>
|
||||||
|
[% END %]
|
||||||
[% IF NOT settings.no_auth %]
|
[% IF NOT settings.no_auth %]
|
||||||
<li><a href="[% uri_for('/logout') %]">Log Out</a></li>
|
<li><a href="[% uri_for('/logout') %]">Log Out</a></li>
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|||||||
29
Netdisco/share/views/password.tt
Normal file
29
Netdisco/share/views/password.tt
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<div class="container">
|
||||||
|
<div class="row nd_hero-row">
|
||||||
|
<div class="span8 offset2">
|
||||||
|
[% IF vars.passchange_ok %]
|
||||||
|
<div class="alert alert-success fade in">
|
||||||
|
<a class="close" data-dismiss="alert">×</a>
|
||||||
|
Password successfully updated.
|
||||||
|
</div>
|
||||||
|
[% END %]
|
||||||
|
[% IF vars.passchange_failed %]
|
||||||
|
<div class="alert alert-error fade in">
|
||||||
|
<a class="close" data-dismiss="alert">×</a>
|
||||||
|
Incorrect current password, or new passwords did not match. Please try again.
|
||||||
|
</div>
|
||||||
|
[% END %]
|
||||||
|
<div class="hero-unit">
|
||||||
|
<h2>Change Password</h2>
|
||||||
|
<form class="nd_login-form" method="post" action="[% uri_for('/password') %]">
|
||||||
|
<div class="form-horizontal">
|
||||||
|
<input placeholder="Current Password" class="span2" name="old" type="password" required="required"/><br/>
|
||||||
|
<input placeholder="New Password" class="span2" name="new" type="password" required="required"/>
|
||||||
|
<input placeholder="Confirm New Password" class="span2" name="confirm" type="password" required="required"/>
|
||||||
|
<button type="submit" class="btn btn-info">Save</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> <!-- /container -->
|
||||||
Reference in New Issue
Block a user