Add account management page
This commit is contained in:
parent
01ad8acd9a
commit
30902a0912
|
@ -23,6 +23,9 @@ sub startup ($self) {
|
||||||
|
|
||||||
$r->get('/register')->to('Register#registration');
|
$r->get('/register')->to('Register#registration');
|
||||||
$r->post('/register')->to('Register#register');
|
$r->post('/register')->to('Register#register');
|
||||||
|
|
||||||
|
$r->get('/account')->to('Account#account');
|
||||||
|
$r->post('/account')->to('Account#update_account');
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
package unix_dog::Controller::Account;
|
||||||
|
use Mojo::Base 'Mojolicious::Controller', -signatures;
|
||||||
|
use Net::LDAPS;
|
||||||
|
use Net::LDAP::Extension::SetPassword;
|
||||||
|
|
||||||
|
sub update_account($self) {
|
||||||
|
my $v = $self->validation;
|
||||||
|
$v->optional('gecos');
|
||||||
|
$v->optional('givenName');
|
||||||
|
$v->optional('surname');
|
||||||
|
$v->required('loginShell')->size(1,64);
|
||||||
|
$v->optional('roomNumber');
|
||||||
|
$v->optional('telNum');
|
||||||
|
$v->required('sshKeys')->size(1,4096);
|
||||||
|
|
||||||
|
$v->optional('newPasswd');
|
||||||
|
$v->required('curPasswd')->size(1,512);
|
||||||
|
|
||||||
|
$v->required('username', 'trim')->size(1,32)->like(qr/^([a-z_][a-z0-9_-]*[\$]?)$/);
|
||||||
|
|
||||||
|
my $gecos = $self->param('gecos');
|
||||||
|
my $givenName = $self->param('givenName');
|
||||||
|
my $surname = $self->param('surname');
|
||||||
|
my $loginShell = $self->param('loginShell');
|
||||||
|
my $roomNumber = $self->param('roomNumber');
|
||||||
|
my $telNum = $self->param('telNum');
|
||||||
|
my @sshKeys = split "\n", $self->param('sshKeys');
|
||||||
|
|
||||||
|
my $curPasswd = $self->param('curPasswd');
|
||||||
|
my $newPasswd = $self->param('newPasswd');
|
||||||
|
|
||||||
|
my $username = $self->param('username');
|
||||||
|
|
||||||
|
$self->stash(
|
||||||
|
gecos => $gecos,
|
||||||
|
givenName => $givenName,
|
||||||
|
surname => $surname,
|
||||||
|
loginShell => $loginShell,
|
||||||
|
roomNumber => $roomNumber,
|
||||||
|
telNum => $telNum,
|
||||||
|
sshKeys => join("\n", @sshKeys),
|
||||||
|
username => $username,
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($v->has_error) {
|
||||||
|
my $err = "Your input was invalid. Please try again.";
|
||||||
|
my @failed = $v->failed;
|
||||||
|
$self->stash(err => $err);
|
||||||
|
$self->stash(failed => @failed);
|
||||||
|
$self->stash(v => $v);
|
||||||
|
|
||||||
|
return $self->render('account/accountManage');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my $config = $self->config;
|
||||||
|
my $connStr = $config->{'ldap'}->{'uri'};
|
||||||
|
my $userDN ='CN='.$username.',OU=Dogs,DC=unix,DC=dog';
|
||||||
|
|
||||||
|
return Mojo::IOLoop->subprocess->run_p(sub {
|
||||||
|
my $ldap = Net::LDAPS->new($connStr, verify=>'none', version=>3) or die "$@";
|
||||||
|
my $mesg = $ldap->bind($userDN, password=>$curPasswd);
|
||||||
|
$mesg->code and die $mesg->error;
|
||||||
|
|
||||||
|
|
||||||
|
$mesg = $ldap->modify(
|
||||||
|
$userDN,
|
||||||
|
replace => {
|
||||||
|
gecos => $gecos || [],
|
||||||
|
givenName => $givenName || [],
|
||||||
|
sn => $surname || [],
|
||||||
|
loginShell => $loginShell,
|
||||||
|
roomNumber => $roomNumber || [],
|
||||||
|
telephoneNumber => $telNum || [],
|
||||||
|
sshPublicKey => @sshKeys,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
$mesg->code and die $mesg->error;
|
||||||
|
|
||||||
|
if (defined $newPasswd and $newPasswd) {
|
||||||
|
$mesg = $ldap->set_password(
|
||||||
|
user => $userDN,
|
||||||
|
oldpasswd => $curPasswd,
|
||||||
|
newpasswd => $newPasswd
|
||||||
|
);
|
||||||
|
$mesg->code and die $mesg->error;
|
||||||
|
}
|
||||||
|
})->then(sub (@results) {
|
||||||
|
return $self->render('account/success');
|
||||||
|
})->catch(sub ($err) {
|
||||||
|
$self->stash(err => $err);
|
||||||
|
return $self->render('account/accountManage');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sub account($self) {
|
||||||
|
|
||||||
|
my $v = $self->validation;
|
||||||
|
|
||||||
|
$v->optional('username', 'trim')->size(1,32)->like(qr/^([a-z_][a-z0-9_-]*[\$]?)$/);
|
||||||
|
|
||||||
|
if ($v->has_error) {
|
||||||
|
$self->stash(err => 'Username is invalid.');
|
||||||
|
return $self->render('account/accountPage');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($v->has_data) {
|
||||||
|
my $username = $self->param('username');
|
||||||
|
my $config = $self->config;
|
||||||
|
my $connStr = $config->{'ldap'}->{'uri'};
|
||||||
|
return Mojo::IOLoop->subprocess->run_p(sub {
|
||||||
|
my $ldap = Net::LDAPS->new($connStr, verify=>'none', version=>3) or die "$@";
|
||||||
|
my $mesg = $ldap->bind();
|
||||||
|
$mesg->code and die $mesg->error;
|
||||||
|
|
||||||
|
$mesg = $ldap->search(
|
||||||
|
base => 'OU=Dogs,DC=unix,DC=dog',
|
||||||
|
filter => '(uid='.$username.')',
|
||||||
|
);
|
||||||
|
$mesg->code and die $mesg->error;
|
||||||
|
|
||||||
|
my $userEntry = $mesg->first_entry;
|
||||||
|
$userEntry or die 'User not found';
|
||||||
|
|
||||||
|
my $gecos = $userEntry->get_value('gecos');
|
||||||
|
my $givenName = $userEntry->get_value('givenname');
|
||||||
|
my $surname = $userEntry->get_value('sn');
|
||||||
|
my $loginShell = $userEntry->get_value('loginshell');
|
||||||
|
my $roomNumber = $userEntry->get_value('roomnumber');
|
||||||
|
my $telNum = $userEntry->get_value('telephonenumber');
|
||||||
|
my @sshKeys = $userEntry->get_value('sshPublicKey');
|
||||||
|
|
||||||
|
return (
|
||||||
|
gecos => $gecos,
|
||||||
|
givenName => $givenName,
|
||||||
|
surname => $surname,
|
||||||
|
loginShell => $loginShell,
|
||||||
|
roomNumber => $roomNumber,
|
||||||
|
telNum => $telNum,
|
||||||
|
sshKeys => join("\n", @sshKeys),
|
||||||
|
username => $username,
|
||||||
|
)
|
||||||
|
})->then(sub (@results) {
|
||||||
|
$self->stash(@results);
|
||||||
|
$self->render('account/accountManage');
|
||||||
|
})->catch(sub ($err) {
|
||||||
|
$self->stash(err => $err);
|
||||||
|
$self->render('account/accountPage');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return $self->render('account/accountPage');
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
|
@ -132,6 +132,7 @@ textarea {
|
||||||
margin: auto 0 auto auto;
|
margin: auto 0 auto auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav a {
|
#nav a {
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
% title 'UNIX.dog Account';
|
||||||
|
% layout 'default';
|
||||||
|
<% if (my $err = stash 'err') { %>
|
||||||
|
<p class="error">
|
||||||
|
<%= $err %>
|
||||||
|
</p>
|
||||||
|
<% if (my $failed = stash 'failed' and my $v = stash 'v') { %>
|
||||||
|
<ul class="error">
|
||||||
|
<% foreach my $fn (@{$failed}) { %>
|
||||||
|
<% my ($check, $result, @args) = @{$v->error($fn)}; %>
|
||||||
|
<li><%= $fn %>: <%= $check %> <%= join "-", @args %></li>
|
||||||
|
<% } %>
|
||||||
|
</ul>
|
||||||
|
<% } %>
|
||||||
|
<% } %>
|
||||||
|
<p>
|
||||||
|
Please note that this information is public. We don't recommend
|
||||||
|
that you publish your actual phone number or actual name, but
|
||||||
|
it's fun for some jokes. :)
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Here is your current information:
|
||||||
|
</p>
|
||||||
|
%= form_for account => (method => 'POST') => begin
|
||||||
|
<p>
|
||||||
|
%= label_for gecos => 'GECOS field:'
|
||||||
|
%= text_field gecos => $gecos, id => 'gecos'
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
%= label_for givenName => 'First name:'
|
||||||
|
%= text_field givenName => $givenName, id => 'givenName'
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
%= label_for surname => 'Last name:'
|
||||||
|
%= text_field surname => $surname, id => 'surname'
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
%= label_for loginShell => 'Login shell:'
|
||||||
|
%= text_field loginShell => $loginShell, id => 'loginShell'
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
%= label_for roomNumber => 'Room number:'
|
||||||
|
%= text_field roomNumber => $roomNumber, id => 'roomNumber'
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
%= label_for telNum => 'Telephone number:'
|
||||||
|
%= text_field telNum => $telNum, id => 'telNum'
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
%= label_for sshKeys => 'SSH keys:'
|
||||||
|
<br>
|
||||||
|
%= text_area sshKeys => $sshKeys, id => 'sshKeys'
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Leave this blank if you don't want to change your password.
|
||||||
|
<br>
|
||||||
|
%= label_for newPasswd => 'New password:'
|
||||||
|
%= password_field 'newPasswd', id => 'newPasswd'
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
%= label_for curPasswd => 'Current password:'
|
||||||
|
%= password_field 'curPasswd', id => 'curPasswd'
|
||||||
|
</p>
|
||||||
|
<input type="text" name="username" hidden="true" value="<%= $username %>">
|
||||||
|
%= submit_button 'Update!'
|
||||||
|
% end
|
|
@ -0,0 +1,26 @@
|
||||||
|
% title 'UNIX.dog Account Management';
|
||||||
|
% layout 'default';
|
||||||
|
<h1>Account</h1>
|
||||||
|
<% if (my $err = stash 'err') { %>
|
||||||
|
<p class="error">
|
||||||
|
<%= $err %>
|
||||||
|
</p>
|
||||||
|
<% } %>
|
||||||
|
<p>
|
||||||
|
Here you can change your password or SSH keys
|
||||||
|
used to log into the server. Please note that
|
||||||
|
SSH keys must be stored in LDAP, and the
|
||||||
|
.authorized_keys file does not work.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
You can also use LDAP tools to connect to
|
||||||
|
ldap.unix.dog and manage your account information
|
||||||
|
that way.
|
||||||
|
</p>
|
||||||
|
%= form_for account => begin
|
||||||
|
<p>
|
||||||
|
%= label_for username => 'Enter your username to get started:'
|
||||||
|
%= text_field 'username', id => 'username'
|
||||||
|
</p>
|
||||||
|
%= submit_button
|
||||||
|
% end
|
|
@ -0,0 +1,4 @@
|
||||||
|
% title 'UNIX.dog Account Management';
|
||||||
|
% layout 'default';
|
||||||
|
<h1>Success</h1>
|
||||||
|
<p>Your account was updated successfully.</p>
|
|
@ -19,6 +19,7 @@
|
||||||
<img src="favicon.ico" width="32" height="32" alt="UNIX.dog"/>
|
<img src="favicon.ico" width="32" height="32" alt="UNIX.dog"/>
|
||||||
<h1><a href="/">UNIX.dog</a></h1>
|
<h1><a href="/">UNIX.dog</a></h1>
|
||||||
<div id="nav">
|
<div id="nav">
|
||||||
|
<a href="/account">Account</a>
|
||||||
<a href="/services">Services</a>
|
<a href="/services">Services</a>
|
||||||
<a href="/register">Register</a>
|
<a href="/register">Register</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue