package CatDap::Controller::register; use Moose; use namespace::autoclean; use Email::Valid; use Data::UUID; BEGIN {extends 'Catalyst::Controller'; } =head1 NAME CatDap::Controller::register - Catalyst Controller =head1 DESCRIPTION Catalyst Controller. =head1 METHODS =cut =head2 index =cut sub index :Path :Args(0) : Form { my ( $self, $c ) = @_; my $lang = choose_language($c); #my $form = Catalyst::Controller::HTML::FormFu->form(); #$c->response->body('Matched CatDap::Controller::register in register.'); } sub check : Local { my ( $self, $c ) = @_; my %details = %{$c->request->params}; my $username = lc($c->request->params->{uid}); my @errors; $c->stash(errors => []); # Check username, start with letter, followed by letters or numbers my $login_regex = ${$c->config}{'register'}{'login_regex'}; if ($username !~ /$login_regex/) { push @errors, $c->loc('Invalid username'); } my $email = $c->request->params->{mail1}; if (! Email::Valid->address($email)) { push @errors, $c->loc('Invalid email address'); } if ($email ne $c->request->params->{mail2}) { push @errors, $c->loc('Addresses do not match'); } if (! $c->validate_captcha($c->req->param('validate'))){ push @errors, $c->loc('Incorrect validation text, please try again'); } if ( ! open( my $etcpasswd, "/etc/passwd")) { push @errors, $c->loc('Cannot check /etc/passwd, please warn system administrators'); } else { if ( grep { /^$username:/ } <$etcpasswd> ) { push @errors, $c->loc('Invalid username, already used by system'); } close($etcpasswd); } if ( grep /^$username$/, @{${$c->config}{'register'}{'login_blacklist'}}) { push @errors, $c->loc('Username is not authorized to be used'); } if ($c->request->params->{gn} !~ /^[\p{IsAlnum}'\- ]+$/) { push @errors, $c->loc( 'The first name supplied contains illegal characters' ); } if ($c->request->params->{sn} !~ /^[\p{IsAlnum}'\- ]+$/) { push @errors, $c->loc( 'The surname supplied contains illegal characters' ); } if (@errors) { $c->stash(errors => \@errors); $c->stash(template => 'register/index.tt'); return; } # check in LDAP now that we have validated username and email my $mesg = $c->model('Proxy')->search("(mail=$email)"); if ($mesg->entries()) { push @errors,$c->loc( 'An account already exists with this email address' ); } $mesg = $c->model('Proxy')->search("(uid=$username)"); if ($mesg->entries()) { push @errors,$c->loc('An account already exists with this username'); } if (@errors) { $c->stash(errors => \@errors); $c->stash(template => 'register/index.tt'); return; } my $dn = "uid=$username,${$c->config}{'Model::Proxy'}{'base'}"; my $ug = Data::UUID->new; my $password = $ug->create_str(); my $cn = $c->request->params->{gn} . " " . $c->request->params->{sn}; my $lang = choose_language($c); $c->log->info("Creating account for user $username"); $mesg = $c->model('Proxy')->add($dn, attr => [ objectclass => [ 'inetOrgPerson' ], sn => $c->request->params->{sn}, gn => $c->request->params->{gn}, cn => $cn, mail => $email, pwdReset => 'TRUE', userPassword => $password, preferredLanguage => $lang, ] ); if ($mesg->code) { push @errors,$mesg->error; $c->log->info( sprintf("Creating DN $dn failed: %s", $mesg->error) ); $c->stash(errors => \@errors); $c->stash(template => 'register/index.tt'); return ; } $c->stash( email => { 'to' => $email, 'from' => ${$c->config}{'emailfrom'}, 'subject' => ${$c->config}{'apptitle'} . " - " . $c->loc('Activation'), 'template' => 'activation.tt', }, cn => $cn, url => $c->uri_for('/user/firstlogin') . "?username=$username&key=$password", ); $c->log->info("Sending activation mail for user $username to $email"); $c->forward( $c->view('Email::Template') ); if ( @{ $c->error } ) { my $errors = join "\n",@{ $c->error }; $c->log->info("Sending activation mail to $email failed: $errors"); $c->response->body($c->loc('An error occured sending the email, but your account was created. Please try the password recovery process if you entered the correct email address. Errors [_1]', $errors)); $c->error(0); # Reset the error condition if you need to } $c->stash(template => 'register/complete.tt'); } sub captcha : Local { my ($self, $c) = @_; return $c->create_captcha(); } sub choose_language : Private { my $c = shift; my $langs = join ',',@{$c->languages}; # FIXME heuristic for correcting languages, we may want a different strategy # in future in conjunction with server-side constraints with slapo-constraint. # E.g. we could have a languages container with mapping from browser locale # codes (preferredLanguage, which is multi-valued), to a single value # (e.g. mageiaselectedLanguage, or similar). Then use a uri-based constraint on # with mageiaSelectedLanguage as the attribute # Also to be considered, pushing all the languages to preferredLanguage, but # then do we use ordering? my $lang = ${$c->languages}[0]; if ($lang !~ /^\w\w\w?(-\w+)?$/) { $lang = 'en'; } # Partial list of lang-variant locales where localisation is different if ($lang !~ /^(en-gb|en-us|pt-br|no-\w+|zh-\w+)$/) { $lang =~ s/^(\w+)-\w+$/$1/; } $c->log->debug("Browser languages: $langs,using preferred language: $lang"); $c->log->debug("Selected language $lang not default " . $c->language) if $lang ne $c->language; return $lang; } =head1 AUTHOR Buchan Milne =head1 LICENSE This library is free software. You can redistribute it and/or modify it under the same terms as Perl itself. =cut __PACKAGE__->meta->make_immutable; 1;