website/lib/unix_dog/Controller/Register.pm

174 lines
5.3 KiB
Perl

package unix_dog::Controller::Register;
use Mojo::Base 'Mojolicious::Controller', -signatures;
use Net::LDAPS;
use Net::LDAP::Extension::SetPassword;
use Net::LDAP::Constant qw(LDAP_NO_SUCH_OBJECT);
use Email::Simple;
use Email::Sender::Simple;
use Email::Sender::Transport::Sendmail;
sub registration($self) {
$self->render('register/registerPage');
}
sub register($self) {
my $v = $self->validation;
$v->required('username', 'trim')->size(1,32)->like(qr/^([a-z_][a-z0-9_-]*[\$]?)$/);
$v->required('password')->size(8, 256);
$v->required('email')->size(1, 512);
$v->required('pubkey')->size(1,4096);
$v->required('bio')->size(1, 2048);
my $username = $self->param('username');
my $password = $self->param('password');
my $email = $self->param('email');
my $pubkeys = $self->param('pubkey');
my $bio = $self->param('bio');
my $fromIP = $self->tx->remote_address;
$self->stash(username => $username);
$self->stash(email => $email);
$self->stash(pubkeys => $pubkeys);
$self->stash(bio => $bio);
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('register/registerPage');
}
my $config = $self->config;
return Mojo::IOLoop->subprocess->run_p(sub {
my $connStr = $config->{'ldap'}->{'uri'};
my $bindDN = $config->{'ldap'}->{'bindDN'};
my $bindPasswd = $config->{'ldap'}->{'password'};
my $ldap = Net::LDAPS->new($connStr, verify=>'none', version => 3) or die "$@";
my $mesg = $ldap->bind($bindDN, password=>$bindPasswd);
$mesg->code and die $mesg->error;
$mesg = $ldap->search(
base => 'cn=NextID,ou=Unverified,dc=unix,dc=dog',
scope => 'base',
filter => '(&)'
);
$mesg->code and die $mesg->error;
my @searchEntries = $mesg->entries;
my $uidEntry = $searchEntries[0];
$uidEntry or die 'Entry not found';
my $nextUID = int($uidEntry->get_value('uidnumber'));
my $nextGID = int($uidEntry->get_value('gidnumber'));
$mesg = $ldap->search(
base => 'ou=Dogs,dc=unix,dc=dog',
filter => '(uid=' .$username. ')',
);
$mesg->code and die $mesg->error;
$mesg->count == 0 or die 'That username is already in use.';
$mesg = $ldap->search(
base => 'ou=Dogs,ou=Unverified,dc=unix,dc=dog',
filter => '(uid='. $username .')',
);
$mesg->code and die $mesg->error;
$mesg->count == 0 or die 'That username is already in use.';
$mesg = $ldap->modify(
$uidEntry,
replace => {
uidNumber => $nextUID + 1,
gidNumber => $nextGID + 1,
}
);
$mesg->code and die $mesg->error;
my $userDN = 'CN='.$username.',OU=Dogs,OU=Unverified,DC=unix,DC=dog';
$mesg = $ldap->add(
$userDN,
attrs => [
cn => $username,
mail => $username . '@unix.dog',
sshPublicKey => (split "\n", $pubkeys),
objectClass => [
'top',
'extensibleObject',
'inetOrgPerson',
'person',
'organizationalPerson',
'posixAccount',
'shadowAccount',
'uidObject',
'ldapPublicKey'
],
uid => $username,
uidNumber => $nextUID,
gidNumber => $nextGID,
homeDirectory => '/home/' . $username,
loginShell => '/bin/bash',
]
);
$mesg->code and die $mesg->error;
$mesg = $ldap->set_password(
user => $userDN,
newpasswd => $password,
);
$mesg->code and die $mesg->error;
my $groupDN = 'CN='.$username.',OU=Group,OU=Unverified,DC=unix,DC=dog';
$mesg = $ldap->add(
$groupDN,
attrs => [
cn => $username,
objectClass => [ 'groupOfNames', 'posixGroup' ],
gidNumber => $nextGID,
member => [ $userDN ],
memberUid => [ $username ],
]
);
$mesg->code and die $mesg->error;
my $message = Email::Simple->create(
header => [
From => 'registration@unix.dog',
To => 'alpha@unix.dog',
Subject => 'New Woof Registration',
],
body => "ARF WOOF!! There's a dog waiting at the door!
Woofname: $username
EMail: $email
More info: $bio
IP: $fromIP
Conformation LDIF:
dn: $userDN
changetype: moddn
newsuperior: ou=Dogs,dc=unix,dc=dog
deleteoldrdn: 1
-
dn: $groupDN
changetype: moddn
newsuperior: ou=Group,dc=unix,dc=dog
deleteoldrdn: 1"
);
Email::Sender::Simple->send($message);
})->then(sub (@results) {
$self->render('register/registerDone');
})->catch(sub ($err) {
$self->stash(err => $err);
$self->render('register/registerPage');
})->wait;
}
1;