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;