aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/App/Controller/Admin/Users.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perllib/FixMyStreet/App/Controller/Admin/Users.pm')
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin/Users.pm177
1 files changed, 130 insertions, 47 deletions
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;