package Smolder::Control::Admin::Developers; use strict; use warnings; use base 'Smolder::Control'; use Smolder::DB::Project; use Smolder::DB::Developer; use Smolder::Email; use Smolder::Constraints qw(email unsigned_int length_max length_between bool unique_field_value); use Email::Valid; =head1 NAME Smolder::Control::Admin::Developers =head1 DESCRIPTION Controller module for Admin activities concerning Developers =cut sub setup { my $self = shift; $self->start_mode('list'); $self->run_modes( [ qw( add process_add edit process_edit list delete reset_pw details ) ] ); } sub require_group { 'admin' } =head1 RUN MODES =head2 reset_pw Allow an admin to reset the password of a developer to a new random string and then email the new password to the developer. Uses the F template for the email and the F for displaying the result. =cut sub reset_pw { my $self = shift; my $dev = Smolder::DB::Developer->retrieve($self->param('id')); return $self->error_message("Developer no longer exists!") unless $dev; my $email = $dev->email; my $user = $dev->username; my $new_pw = $dev->reset_password(); # send the email my $error = Smolder::Email->send_mime_mail( name => 'reset_pw', to => $email, subject => 'Reset of password by Admin', tt_params => { developer => $dev, new_pw => $new_pw, }, ); if ($error) { $self->add_message( msg => "Could not send email to '$user'. Please check error logs!", type => 'warning', ); $self->log->warning("Could not send 'reset_pw' email to $email - $error"); } else { $self->add_message(msg => "Password for '$user' has been reset and an email sent with their new password."); } return ' '; } =head2 edit Show the edit form to allow an admin to edit the data about a developer. Uses the F template. =cut sub edit { my ($self, $err_msgs) = @_; my $developer = Smolder::DB::Developer->retrieve($self->param('id')); my $output; # if we have any error messages, then just re-fill the form # and show them if ($err_msgs) { $err_msgs->{developer} = $developer; $output = HTML::FillInForm->new->fill( scalarref => $self->tt_process($err_msgs), qobject => $self->query, ); # else get the developer in question } else { my %developer_data = $developer->vars(); $output = HTML::FillInForm->new->fill( scalarref => $self->tt_process({developer => $developer}), fdat => \%developer_data, ); } return $output; } =head2 process_edit Processes the incoming data from the C mode and update the developers info in the database if validation passes. Uses the F template. =cut sub process_edit { my $self = shift; my $id = $self->param('id'); my $form = { required => [qw(username fname lname email admin)], constraint_methods => { username => [length_max(255), unique_field_value('developer', 'username', $id),], fname => length_max(255), lname => length_max(255), email => email(), admin => bool(), }, }; my $results = $self->check_rm('edit', $form) || return $self->check_rm_error_page; my $valid = $results->valid(); my $developer = Smolder::DB::Developer->retrieve($id); return $self->error_message("Developer no longer exists!") unless $developer; $developer->set(%$valid); # we need to eval{} since we don't want there to be duplicate usernames (id) eval { $developer->update }; # if there was a problem. if ($@) { # if it was a duplicate developer, then we can handle that if (Smolder::Conf->unique_failure_msg($@)) { return $self->edit({err_unique_username => 1}); # else it's something else, so just throw it again } else { die $@; } } # now show the successful message $self->add_message(msg => "User '" . $developer->username . "' has been successfully updated."); return $self->add_json_header(list_changed => 1); } =head2 list Show a list of all developers. Uses the F template. =cut sub list { my $self = shift; my $cgi = $self->query(); my @developers = Smolder::DB::Developer->search(guest => 0); my %tt_params; $tt_params{developers} = \@developers if (@developers); return $self->tt_process(\%tt_params); } =head2 add Show the add form for adding a new developer. Uses the F template. =cut sub add { my ($self, $tt_params) = @_; $tt_params ||= {}; return $self->tt_process($tt_params); } =head2 process_add Process the incoming data from the C mode and add it to the database if validation passes. Uses the F. =cut sub process_add { my $self = shift; my $form = { required => [qw(username email password admin)], optional => [qw(fname lname)], constraint_methods => { username => [length_max(255), unique_field_value('developer', 'username'),], fname => length_max(255), lname => length_max(255), email => email(), password => length_between(4, 255), admin => bool(), }, }; my $results = $self->check_rm('add', $form) || return $self->check_rm_error_page; my $valid = $results->valid(); # create a new preference for this developer; my $pref = Smolder::DB::Preference->create(); $valid->{preference} = $pref; my $developer; # we need to eval{} since we don't want there to be duplicate usernames eval { $developer = Smolder::DB::Developer->create($valid) }; # if there was a problem. if ($@) { # if it was a duplicate developer, then we can handle that if (Smolder::Conf->unique_failure_msg($@)) { return $self->add({err_unique_username => 1}); # else it's something else, so just throw it again } else { die $@; } } # now show the successful message $self->add_message(msg => "New user '" . $developer->username . "' successfully created."); return $self->add_json_header(list_changed => 1); } =head2 delete Delete a Developer and all data associated with him. If successful returns the C mode. =cut sub delete { my $self = shift; my $id = $self->param('id'); my $developer = Smolder::DB::Developer->retrieve($id); if ($developer) { # remove all reports from this developer my @smokes = $developer->smoke_reports(); foreach my $smoke (@smokes) { $smoke->delete_files(); } my $username = $developer->username; $developer->delete(); $self->add_message(msg => "User '$username' has been successfully deleted."); } return $self->list(); } =head2 details Show the details of a developer. Uses the F template. =cut sub details { my ($self, $developer, $action) = @_; my $new; # if we weren't given a developer, then get it from the query string if (!$developer) { my $id = $self->param('id'); $new = 0; $developer = Smolder::DB::Developer->retrieve($id); return $self->error_message("Can't find Developer with id '$id'!") unless $developer; } else { $new = 1; } my %tt_params = (developer => $developer); $tt_params{$action} = 1 if ($action); return $self->tt_process(\%tt_params); } 1;