aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/App/Controller
diff options
context:
space:
mode:
Diffstat (limited to 'perllib/FixMyStreet/App/Controller')
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin.pm15
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin/DefectTypes.pm2
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin/ResponsePriorities.pm2
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin/Roles.pm96
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin/Users.pm177
5 files changed, 234 insertions, 58 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm
index 6167a16f5..5f18f8557 100644
--- a/perllib/FixMyStreet/App/Controller/Admin.pm
+++ b/perllib/FixMyStreet/App/Controller/Admin.pm
@@ -484,15 +484,14 @@ sub report_edit : Path('report_edit') : Args(1) {
$problem->resend;
$problem->update();
- $c->stash->{status_message} =
- '<p><em>' . _('That problem will now be resent.') . '</em></p>';
+ $c->stash->{status_message} = _('That problem will now be resent.');
$c->forward( 'log_edit', [ $id, 'problem', 'resend' ] );
}
elsif ( $c->get_param('mark_sent') ) {
$c->forward('/auth/check_csrf_token');
$problem->update({ whensent => \'current_timestamp' })->discard_changes;
- $c->stash->{status_message} = '<p><em>' . _('That problem has been marked as sent.') . '</em></p>';
+ $c->stash->{status_message} = _('That problem has been marked as sent.');
$c->forward( 'log_edit', [ $id, 'problem', 'marked sent' ] );
}
elsif ( $c->get_param('flaguser') ) {
@@ -571,8 +570,7 @@ sub report_edit : Path('report_edit') : Args(1) {
}
$c->forward( 'log_edit', [ $id, 'problem', 'edit' ] );
- $c->stash->{status_message} =
- '<p><em>' . _('Updated!') . '</em></p>';
+ $c->stash->{status_message} = _('Updated!');
# do this here otherwise lastupdate and confirmed times
# do not display correctly
@@ -833,7 +831,7 @@ sub template_edit : Path('templates') : Args(2) {
$template->update_or_insert;
$template->contact_response_templates->search({
- contact_id => { '!=' => \@new_contact_ids },
+ contact_id => { -not_in => \@new_contact_ids },
})->delete;
foreach my $contact_id (@new_contact_ids) {
$template->contact_response_templates->find_or_create({
@@ -921,13 +919,12 @@ sub update_edit : Path('update_edit') : Args(1) {
$self->remove_photo($c, $update, $remove_photo_param);
}
- $c->stash->{status_message} = '<p><em>' . _('Updated!') . '</em></p>';
+ $c->stash->{status_message} = _('Updated!');
# Must call update->hide while it's not hidden (so is_latest works)
if ($new_state eq 'hidden') {
my $outcome = $update->hide;
- $c->stash->{status_message} .=
- '<p><em>' . _('Problem marked as open.') . '</em></p>'
+ $c->stash->{status_message} .= _('Problem marked as open.')
if $outcome->{reopened};
}
diff --git a/perllib/FixMyStreet/App/Controller/Admin/DefectTypes.pm b/perllib/FixMyStreet/App/Controller/Admin/DefectTypes.pm
index ed9b40fd0..6c1a25e5a 100644
--- a/perllib/FixMyStreet/App/Controller/Admin/DefectTypes.pm
+++ b/perllib/FixMyStreet/App/Controller/Admin/DefectTypes.pm
@@ -76,7 +76,7 @@ sub edit : Path : Args(2) {
my @new_contact_ids = $c->get_param_list('categories');
@new_contact_ids = @{ mySociety::ArrayUtils::intersection(\@live_contact_ids, \@new_contact_ids) };
$defect_type->contact_defect_types->search({
- contact_id => { '!=' => \@new_contact_ids },
+ contact_id => { -not_in => \@new_contact_ids },
})->delete;
foreach my $contact_id (@new_contact_ids) {
$defect_type->contact_defect_types->find_or_create({
diff --git a/perllib/FixMyStreet/App/Controller/Admin/ResponsePriorities.pm b/perllib/FixMyStreet/App/Controller/Admin/ResponsePriorities.pm
index 2613f6ae0..5077fe78f 100644
--- a/perllib/FixMyStreet/App/Controller/Admin/ResponsePriorities.pm
+++ b/perllib/FixMyStreet/App/Controller/Admin/ResponsePriorities.pm
@@ -71,7 +71,7 @@ sub edit : Path : Args(2) {
my @live_contact_ids = map { $_->id } @live_contacts;
my @new_contact_ids = grep { $c->get_param("contacts[$_]") } @live_contact_ids;
$priority->contact_response_priorities->search({
- contact_id => { '!=' => \@new_contact_ids },
+ contact_id => { -not_in => \@new_contact_ids },
})->delete;
foreach my $contact_id (@new_contact_ids) {
$priority->contact_response_priorities->find_or_create({
diff --git a/perllib/FixMyStreet/App/Controller/Admin/Roles.pm b/perllib/FixMyStreet/App/Controller/Admin/Roles.pm
new file mode 100644
index 000000000..15c96a4ed
--- /dev/null
+++ b/perllib/FixMyStreet/App/Controller/Admin/Roles.pm
@@ -0,0 +1,96 @@
+package FixMyStreet::App::Controller::Admin::Roles;
+use Moose;
+use namespace::autoclean;
+
+BEGIN { extends 'Catalyst::Controller'; }
+
+use FixMyStreet::App::Form::Role;
+
+sub auto :Private {
+ my ($self, $c) = @_;
+
+ my $user = $c->user;
+ if ($user->is_superuser) {
+ $c->stash(rs => $c->model('DB::Role')->search_rs({}, { join => 'body', order_by => ['body.name', 'me.name'] }));
+ } elsif ($user->from_body) {
+ $c->stash(rs => $user->from_body->roles->search_rs({}, { order_by => 'name' }));
+ }
+}
+
+sub index :Path :Args(0) {
+ my ($self, $c) = @_;
+
+ my $p = $c->cobrand->available_permissions;
+ my %labels;
+ foreach my $group (sort keys %$p) {
+ my $group_vals = $p->{$group};
+ foreach (sort keys %$group_vals) {
+ $labels{$_} = $group_vals->{$_};
+ }
+ }
+
+ $c->stash(
+ roles => [ $c->stash->{rs}->all ],
+ labels => \%labels,
+ );
+}
+
+sub create :Local :Args(0) {
+ my ($self, $c, $id) = @_;
+
+ my $role = $c->stash->{rs}->new_result({});
+ return $self->form($c, $role);
+}
+
+sub item :PathPart('admin/roles') :Chained :CaptureArgs(1) {
+ my ($self, $c, $id) = @_;
+
+ my $obj = $c->stash->{rs}->find($id)
+ or $c->detach('/page_error_404_not_found', []);
+ $c->stash(obj => $obj);
+}
+
+sub edit :PathPart('') :Chained('item') :Args(0) {
+ my ($self, $c) = @_;
+ return $self->form($c, $c->stash->{obj});
+}
+
+sub form {
+ my ($self, $c, $role) = @_;
+
+ if ($c->get_param('delete_role')) {
+ $role->delete;
+ $c->response->redirect($c->uri_for($self->action_for('list')));
+ $c->detach;
+ }
+
+ my $perms = [];
+ my $p = $c->cobrand->available_permissions;
+ foreach my $group (sort keys %$p) {
+ my $group_vals = $p->{$group};
+ my @foo;
+ foreach (sort keys %$group_vals) {
+ push @foo, { value => $_, label => $group_vals->{$_} };
+ }
+ push @$perms, { group => $group, options => \@foo };
+ }
+ my $opts = {
+ field_list => [
+ '+permissions' => { options => $perms },
+ ],
+ };
+
+ if (!$c->user->is_superuser && $c->user->from_body) {
+ push @{$opts->{field_list}}, '+body', { inactive => 1 };
+ $opts->{body_id} = $c->user->from_body->id;
+ }
+
+ my $form = FixMyStreet::App::Form::Role->new(%$opts);
+ $c->stash(template => 'admin/roles/form.html', form => $form);
+ $form->process(item => $role, params => $c->req->params);
+ return unless $form->validated;
+
+ $c->response->redirect($c->uri_for($self->action_for('list')));
+}
+
+1;
diff --git a/perllib/FixMyStreet/App/Controller/Admin/Users.pm b/perllib/FixMyStreet/App/Controller/Admin/Users.pm
index 6af4ae831..e55a3d111 100644
--- a/perllib/FixMyStreet/App/Controller/Admin/Users.pm
+++ b/perllib/FixMyStreet/App/Controller/Admin/Users.pm
@@ -27,37 +27,69 @@ Admin pages for editing users
sub index :Path : Args(0) {
my ( $self, $c ) = @_;
- $c->detach('add') if $c->req->method eq 'POST'; # Add a user
-
- if (my $search = $c->get_param('search')) {
- $search = $self->trim($search);
- $search =~ s/^<(.*)>$/$1/; # In case email wrapped in <...>
- $c->stash->{searched} = $search;
-
- my $isearch = '%' . $search . '%';
- my $search_n = 0;
- $search_n = int($search) if $search =~ /^\d+$/;
-
- my $users = $c->cobrand->users->search(
- {
- -or => [
- email => { ilike => $isearch },
- phone => { ilike => $isearch },
- name => { ilike => $isearch },
- from_body => $search_n,
- ]
+ if ($c->req->method eq 'POST') {
+ my @uids = $c->get_param_list('uid');
+ my @role_ids = $c->get_param_list('roles');
+ my $user_rs = FixMyStreet::DB->resultset("User")->search({ id => \@uids });
+ foreach my $user ($user_rs->all) {
+ $user->admin_user_body_permissions->delete;
+ $user->user_roles->search({
+ role_id => { -not_in => \@role_ids },
+ })->delete;
+ foreach my $role (@role_ids) {
+ $user->user_roles->find_or_create({
+ role_id => $role,
+ });
}
- );
+ }
+ $c->stash->{status_message} = _('Updated!');
+ }
+
+ my $search = $c->get_param('search');
+ my $role = $c->get_param('role');
+ if ($search || $role) {
+ my $users = $c->cobrand->users;
+ my $isearch;
+ if ($search) {
+ $search = $self->trim($search);
+ $search =~ s/^<(.*)>$/$1/; # In case email wrapped in <...>
+ $c->stash->{searched} = $search;
+
+ $isearch = '%' . $search . '%';
+ my $search_n = 0;
+ $search_n = int($search) if $search =~ /^\d+$/;
+
+ $users = $users->search(
+ {
+ -or => [
+ email => { ilike => $isearch },
+ phone => { ilike => $isearch },
+ name => { ilike => $isearch },
+ from_body => $search_n,
+ ]
+ }
+ );
+ }
+ if ($role) {
+ $c->stash->{role_selected} = $role;
+ $users = $users->search({
+ role_id => $role,
+ }, {
+ join => 'user_roles',
+ });
+ }
+
my @users = $users->all;
$c->stash->{users} = [ @users ];
- $c->forward('/admin/add_flags', [ { email => { ilike => $isearch } } ]);
+ if ($search) {
+ $c->forward('/admin/add_flags', [ { email => { ilike => $isearch } } ]);
+ }
} else {
$c->forward('/auth/get_csrf_token');
$c->forward('/admin/fetch_all_bodies');
$c->cobrand->call_hook('admin_user_edit_extra_data');
-
# Admin users by default
my $users = $c->cobrand->users->search(
{ from_body => { '!=', undef } },
@@ -67,6 +99,14 @@ sub index :Path : Args(0) {
$c->stash->{users} = \@users;
}
+ my $rs;
+ if ($c->user->is_superuser) {
+ $rs = $c->model('DB::Role')->search_rs({}, { join => 'body', order_by => ['body.name', 'me.name'] });
+ } elsif ($c->user->from_body) {
+ $rs = $c->user->from_body->roles->search_rs({}, { order_by => 'name' });
+ }
+ $c->stash->{roles} = [ $rs->all ];
+
return 1;
}
@@ -113,9 +153,7 @@ sub add : Local : Args(0) {
$c->stash->{field_errors}->{username} = _('User already exists');
}
- return if %{$c->stash->{field_errors}};
-
- my $user = $c->model('DB::User')->create( {
+ my $user = $c->model('DB::User')->new( {
name => $c->get_param('name'),
email => $email ? $email : undef,
email_verified => $email && $email_v ? 1 : 0,
@@ -127,8 +165,11 @@ sub add : Local : Args(0) {
is_superuser => ( $c->user->is_superuser && $c->get_param('is_superuser') ) || 0,
} );
$c->stash->{user} = $user;
+
+ return if %{$c->stash->{field_errors}};
+
$c->forward('user_cobrand_extra_fields');
- $user->update;
+ $user->insert;
$c->forward( '/admin/log_edit', [ $user->id, 'user', 'edit' ] );
@@ -136,6 +177,18 @@ sub add : Local : Args(0) {
$c->res->redirect( $c->uri_for_action( 'admin/users/edit', $user->id ) );
}
+sub fetch_body_roles : Private {
+ my ($self, $c, $body ) = @_;
+
+ my $roles = $body->roles->search(undef, { order_by => 'name' });
+ unless ($roles) {
+ delete $c->stash->{roles}; # Body doesn't have any roles
+ return;
+ }
+
+ $c->stash->{roles} = [ $roles->all ];
+}
+
sub edit : Path : Args(1) {
my ( $self, $c, $id ) = @_;
@@ -157,11 +210,11 @@ sub edit : Path : Args(1) {
$c->forward('/admin/fetch_all_bodies');
$c->forward('/admin/fetch_body_areas', [ $user->from_body ]) if $user->from_body;
+ $c->forward('fetch_body_roles', [ $user->from_body ]) if $user->from_body;
$c->cobrand->call_hook('admin_user_edit_extra_data');
if ( defined $c->flash->{status_message} ) {
- $c->stash->{status_message} =
- '<p><em>' . $c->flash->{status_message} . '</em></p>';
+ $c->stash->{status_message} = $c->flash->{status_message};
}
$c->forward('/auth/check_csrf_token') if $c->get_param('submit');
@@ -270,26 +323,45 @@ sub edit : Path : Args(1) {
# If so, we need to re-fetch areas so the UI is up to date.
if ( $user->from_body && $user->from_body->id ne $c->stash->{fetched_areas_body_id} ) {
$c->forward('/admin/fetch_body_areas', [ $user->from_body ]);
+ $c->forward('fetch_body_roles', [ $user->from_body ]);
}
if (!$user->from_body) {
# Non-staff users aren't allowed any permissions or to be in an area
$user->admin_user_body_permissions->delete;
+ $user->user_roles->delete;
$user->area_ids(undef);
delete $c->stash->{areas};
+ delete $c->stash->{roles};
delete $c->stash->{fetched_areas_body_id};
} elsif ($c->stash->{available_permissions}) {
- my @all_permissions = map { keys %$_ } values %{ $c->stash->{available_permissions} };
- my @user_permissions = grep { $c->get_param("permissions[$_]") ? 1 : undef } @all_permissions;
- $user->admin_user_body_permissions->search({
- body_id => $user->from_body->id,
- permission_type => { '!=' => \@user_permissions },
- })->delete;
- foreach my $permission_type (@user_permissions) {
- $user->user_body_permissions->find_or_create({
+ my %valid_roles = map { $_->id => 1 } @{$c->stash->{roles}};
+ my @role_ids = grep { $valid_roles{$_} } $c->get_param_list('roles');
+ if (@role_ids) {
+ # Roles take precedence over permissions
+ $user->admin_user_body_permissions->delete;
+ $user->user_roles->search({
+ role_id => { -not_in => \@role_ids },
+ })->delete;
+ foreach my $role (@role_ids) {
+ $user->user_roles->find_or_create({
+ role_id => $role,
+ });
+ }
+ } else {
+ $user->user_roles->delete;
+ my @all_permissions = map { keys %$_ } values %{ $c->stash->{available_permissions} };
+ my @user_permissions = grep { $c->get_param("permissions[$_]") ? 1 : undef } @all_permissions;
+ $user->admin_user_body_permissions->search({
body_id => $user->from_body->id,
- permission_type => $permission_type,
- });
+ permission_type => { -not_in => \@user_permissions },
+ })->delete;
+ foreach my $permission_type (@user_permissions) {
+ $user->user_body_permissions->find_or_create({
+ body_id => $user->from_body->id,
+ permission_type => $permission_type,
+ });
+ }
}
}
@@ -303,7 +375,7 @@ sub edit : Path : Args(1) {
my @trusted_bodies = $c->get_param_list('trusted_bodies');
if ( $c->user->is_superuser ) {
$user->user_body_permissions->search({
- body_id => { '!=' => \@trusted_bodies },
+ body_id => { -not_in => \@trusted_bodies },
permission_type => 'trusted',
})->delete;
foreach my $body_id (@trusted_bodies) {
@@ -389,9 +461,8 @@ sub import :Local {
my $fh = $c->req->upload('csvfile')->fh;
$csv->getline($fh); # discard the header
while (my $row = $csv->getline($fh)) {
- my ($name, $email, $from_body, $permissions) = @$row;
+ my ($name, $email, $from_body, $permissions, $roles) = @$row;
$email = lc Utils::trim_text($email);
- my @permissions = split(/:/, $permissions);
my $user = FixMyStreet::DB->resultset("User")->find_or_new({ email => $email, email_verified => 1 });
if ($user->in_storage) {
@@ -403,12 +474,24 @@ sub import :Local {
$user->from_body($from_body || undef);
$user->update_or_insert;
- my @user_permissions = grep { $available_permissions{$_} } @permissions;
- foreach my $permission_type (@user_permissions) {
- $user->user_body_permissions->find_or_create({
- body_id => $user->from_body->id,
- permission_type => $permission_type,
- });
+ if ($roles) {
+ my @roles = split(/:/, $roles);
+ foreach my $role (@roles) {
+ $role = FixMyStreet::DB->resultset("Role")->find({
+ body_id => $user->from_body->id,
+ name => $role,
+ }) or next;
+ $user->add_to_roles($role);
+ }
+ } else {
+ my @permissions = split(/:/, $permissions);
+ my @user_permissions = grep { $available_permissions{$_} } @permissions;
+ foreach my $permission_type (@user_permissions) {
+ $user->user_body_permissions->find_or_create({
+ body_id => $user->from_body->id,
+ permission_type => $permission_type,
+ });
+ }
}
push @{$c->stash->{new_users}}, $user;