diff options
author | Matthew Somerville <matthew-github@dracos.co.uk> | 2018-08-29 13:52:29 +0100 |
---|---|---|
committer | Matthew Somerville <matthew-github@dracos.co.uk> | 2018-08-29 13:52:29 +0100 |
commit | e8e104d411004b1a447197aa2a31abe9311f304e (patch) | |
tree | 3691450c3d91223911f18d519e6b17a812dc9a74 /perllib | |
parent | 527ce8a87e68759346fc3e6981c05a3ca4cfe71c (diff) | |
parent | c90b7fdc9b46e4aa444346e2c4ba0be0838f1506 (diff) |
Merge branch 'issues/collideoscope/30-user-moderation'
Diffstat (limited to 'perllib')
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Moderate.pm | 201 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Report.pm | 2 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/User.pm | 27 |
3 files changed, 91 insertions, 139 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Moderate.pm b/perllib/FixMyStreet/App/Controller/Moderate.pm index 86143b5ea..45a303309 100644 --- a/perllib/FixMyStreet/App/Controller/Moderate.pm +++ b/perllib/FixMyStreet/App/Controller/Moderate.pm @@ -42,6 +42,7 @@ sub moderate : Chained('/') : PathPart('moderate') : CaptureArgs(0) { } sub report : Chained('moderate') : PathPart('report') : CaptureArgs(1) { my ($self, $c, $id) = @_; my $problem = $c->model('DB::Problem')->find($id); + $c->detach unless $problem; my $cobrand_base = $c->cobrand->base_url_for_report( $problem ); my $report_uri = $cobrand_base . $problem->url; @@ -49,9 +50,8 @@ sub report : Chained('moderate') : PathPart('report') : CaptureArgs(1) { $c->stash->{report_uri} = $report_uri; $c->res->redirect( $report_uri ); # this will be the final endpoint after all processing... - # ... and immediately, if the user isn't authorized + # ... and immediately, if the user isn't logged in $c->detach unless $c->user_exists; - $c->detach unless $c->user->has_permission_to(moderate => $problem->bodies_str_ids); $c->forward('/auth/check_csrf_token'); @@ -69,13 +69,16 @@ sub report : Chained('moderate') : PathPart('report') : CaptureArgs(1) { sub moderate_report : Chained('report') : PathPart('') : Args(0) { my ($self, $c) = @_; + # Make sure user can moderate this report + $c->detach unless $c->user->can_moderate($c->stash->{problem}); + $c->forward('report_moderate_hide'); my @types = grep $_, - $c->forward('report_moderate_title'), - $c->forward('report_moderate_detail'), - $c->forward('report_moderate_anon'), - $c->forward('report_moderate_photo'); + $c->forward('moderate_text', [ 'title' ]), + $c->forward('moderate_text', [ 'detail' ]), + $c->forward('moderate_boolean', [ 'anonymous', 'show_name' ]), + $c->forward('moderate_boolean', [ 'photo' ]); $c->detach( 'report_moderate_audit', \@types ) } @@ -135,82 +138,71 @@ sub report_moderate_hide : Private { } } -sub report_moderate_title : Private { - my ( $self, $c ) = @_; - - my $problem = $c->stash->{problem} or die; - my $original = $c->stash->{problem_original}; +sub moderate_text : Private { + my ($self, $c, $thing) = @_; + + my ($object, $original, $param); + my $thing_for_original_table = $thing; + if (my $comment = $c->stash->{comment}) { + $object = $comment; + $original = $c->stash->{comment_original}; + $param = 'update_'; + # Update 'text' field is stored in original table's 'detail' field + $thing_for_original_table = 'detail' if $thing eq 'text'; + } else { + $object = $c->stash->{problem}; + $original = $c->stash->{problem_original}; + $param = 'problem_'; + } - my $old_title = $problem->title; - my $original_title = $original->title; + my $old = $object->$thing; + my $original_thing = $original->$thing_for_original_table; - my $title = $c->get_param('problem_revert_title') ? - $original_title - : $c->get_param('problem_title'); + my $new = $c->get_param($param . 'revert_' . $thing) ? + $original_thing + : $c->get_param($param . $thing); - if ($title ne $old_title) { + if ($new ne $old) { $original->insert unless $original->in_storage; - $problem->update({ title => $title }); - return 'title'; + $object->update({ $thing => $new }); + return $thing_for_original_table; } return; } -sub report_moderate_detail : Private { - my ( $self, $c ) = @_; - - my $problem = $c->stash->{problem} or die; - my $original = $c->stash->{problem_original}; - - my $old_detail = $problem->detail; - my $original_detail = $original->detail; - my $detail = $c->get_param('problem_revert_detail') ? - $original_detail - : $c->get_param('problem_detail'); - - if ($detail ne $old_detail) { - $original->insert unless $original->in_storage; - $problem->update({ detail => $detail }); - return 'detail'; +sub moderate_boolean : Private { + my ( $self, $c, $thing, $reverse ) = @_; + + my ($object, $original, $param); + if (my $comment = $c->stash->{comment}) { + $object = $comment; + $original = $c->stash->{comment_original}; + $param = 'update_'; + } else { + $object = $c->stash->{problem}; + $original = $c->stash->{problem_original}; + $param = 'problem_'; } - return; -} - -sub report_moderate_anon : Private { - my ( $self, $c ) = @_; - - my $problem = $c->stash->{problem} or die; - my $original = $c->stash->{problem_original}; - - my $show_user = $c->get_param('problem_show_name') ? 1 : 0; - my $anonymous = $show_user ? 0 : 1; - my $old_anonymous = $problem->anonymous ? 1 : 0; - if ($anonymous != $old_anonymous) { + return if $thing eq 'photo' && !$original->photo; - $original->insert unless $original->in_storage; - $problem->update({ anonymous => $anonymous }); - return 'anonymous'; + my $new; + if ($reverse) { + $new = $c->get_param($param . $reverse) ? 0 : 1; + } else { + $new = $c->get_param($param . $thing) ? 1 : 0; } - return; -} - -sub report_moderate_photo : Private { - my ( $self, $c ) = @_; - - my $problem = $c->stash->{problem} or die; - my $original = $c->stash->{problem_original}; - - return unless $original->photo; + my $old = $object->$thing ? 1 : 0; - my $show_photo = $c->get_param('problem_show_photo') ? 1 : 0; - my $old_show_photo = $problem->photo ? 1 : 0; - - if ($show_photo != $old_show_photo) { + if ($new != $old) { $original->insert unless $original->in_storage; - $problem->update({ photo => $show_photo ? $original->photo : undef }); - return 'photo'; + if ($thing eq 'photo') { + $object->update({ $thing => $new ? $original->photo : undef }); + } else { + $object->update({ $thing => $new }); + } + return $thing; } return; } @@ -219,6 +211,9 @@ sub update : Chained('report') : PathPart('update') : CaptureArgs(1) { my ($self, $c, $id) = @_; my $comment = $c->stash->{problem}->comments->find($id); + # Make sure user can moderate this update + $c->detach unless $comment && $c->user->can_moderate($comment); + my $original = $comment->find_or_new_related( moderation_original_data => { detail => $comment->text, photo => $comment->photo, @@ -234,9 +229,9 @@ sub moderate_update : Chained('update') : PathPart('') : Args(0) { $c->forward('update_moderate_hide'); my @types = grep $_, - $c->forward('update_moderate_detail'), - $c->forward('update_moderate_anon'), - $c->forward('update_moderate_photo'); + $c->forward('moderate_text', [ 'text' ]), + $c->forward('moderate_boolean', [ 'anonymous', 'show_name' ]), + $c->forward('moderate_boolean', [ 'photo' ]); $c->detach( 'update_moderate_audit', \@types ) } @@ -274,72 +269,6 @@ sub update_moderate_hide : Private { return; } -sub update_moderate_detail : Private { - my ( $self, $c ) = @_; - - my $problem = $c->stash->{problem} or die; - my $comment = $c->stash->{comment} or die; - my $original = $c->stash->{comment_original}; - - my $old_detail = $comment->text; - my $original_detail = $original->detail; - my $detail = $c->get_param('update_revert_detail') ? - $original_detail - : $c->get_param('update_detail'); - - if ($detail ne $old_detail) { - $original->insert unless $original->in_storage; - $comment->update({ text => $detail }); - return 'detail'; - } - return; -} - -sub update_moderate_anon : Private { - my ( $self, $c ) = @_; - - my $problem = $c->stash->{problem} or die; - my $comment = $c->stash->{comment} or die; - my $original = $c->stash->{comment_original}; - - my $show_user = $c->get_param('update_show_name') ? 1 : 0; - my $anonymous = $show_user ? 0 : 1; - my $old_anonymous = $comment->anonymous ? 1 : 0; - - if ($anonymous != $old_anonymous) { - $original->insert unless $original->in_storage; - $comment->update({ anonymous => $anonymous }); - return 'anonymous'; - } - return; -} - -sub update_moderate_photo : Private { - my ( $self, $c ) = @_; - - my $problem = $c->stash->{problem} or die; - my $comment = $c->stash->{comment} or die; - my $original = $c->stash->{comment_original}; - - return unless $original->photo; - - my $show_photo = $c->get_param('update_show_photo') ? 1 : 0; - my $old_show_photo = $comment->photo ? 1 : 0; - - if ($show_photo != $old_show_photo) { - $original->insert unless $original->in_storage; - $comment->update({ photo => $show_photo ? $original->photo : undef }); - return 'photo'; - } -} - -sub return_text : Private { - my ($self, $c, $text) = @_; - - $c->res->content_type('text/plain; charset=utf-8'); - $c->res->body( $text // '' ); -} - __PACKAGE__->meta->make_immutable; 1; diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index e285687bc..854dbf3ea 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -140,7 +140,7 @@ sub load_problem_or_display_error : Private { } $c->stash->{problem} = $problem; - if ( $c->user_exists && $c->user->has_permission_to(moderate => $problem->bodies_str_ids) ) { + if ( $c->user_exists && $c->user->can_moderate($problem) ) { $c->stash->{problem_original} = $problem->find_or_new_related( moderation_original_data => { title => $problem->title, diff --git a/perllib/FixMyStreet/DB/Result/User.pm b/perllib/FixMyStreet/DB/Result/User.pm index 5ba597f74..5afd9d89c 100644 --- a/perllib/FixMyStreet/DB/Result/User.pm +++ b/perllib/FixMyStreet/DB/Result/User.pm @@ -330,6 +330,26 @@ sub split_name { return { first => $first || '', last => $last || '' }; } +sub can_moderate { + my ($self, $object, %perms) = @_; + + my ($type, $ids); + if ($object->isa("FixMyStreet::DB::Result::Comment")) { + $type = 'update'; + $ids = $object->problem->bodies_str_ids; + } else { + $type = 'problem'; + $ids = $object->bodies_str_ids; + } + + my $staff_perm = exists($perms{staff}) ? $perms{staff} : $self->has_permission_to(moderate => $ids); + return 1 if $staff_perm; + + # See if the cobrand wants to allow it in some circumstance + my $cobrand = $self->result_source->schema->cobrand; + return $cobrand->call_hook('moderate_permission', $self, $type => $object); +} + has body_permissions => ( is => 'ro', lazy => 1, @@ -340,13 +360,16 @@ has body_permissions => ( ); sub permissions { - my ($self, $c, $body_id) = @_; + my ($self, $problem) = @_; + my $cobrand = $self->result_source->schema->cobrand; if ($self->is_superuser) { - my $perms = $c->cobrand->available_permissions; + my $perms = $cobrand->available_permissions; return { map { %$_ } values %$perms }; } + my $body_id = $problem->bodies_str; + return unless $self->belongs_to_body($body_id); my @permissions = grep { $_->body_id == $self->from_body->id } @{$self->body_permissions}; |