diff options
Diffstat (limited to 'perllib/FixMyStreet/App/Controller/Admin.pm')
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Admin.pm | 390 |
1 files changed, 319 insertions, 71 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm index 63d892fc4..e5c0133cf 100644 --- a/perllib/FixMyStreet/App/Controller/Admin.pm +++ b/perllib/FixMyStreet/App/Controller/Admin.pm @@ -175,7 +175,7 @@ sub questionnaire : Path('questionnaire') : Args(0) { ); - my %questionnaire_counts = map { $_->get_column( 'reported' ) => $_->get_column( 'questionnaire_count' ) } $questionnaires->all; + my %questionnaire_counts = map { ( $_->get_column( 'reported' ) || -1 ) => $_->get_column( 'questionnaire_count' ) } $questionnaires->all; $questionnaire_counts{1} ||= 0; $questionnaire_counts{0} ||= 0; $questionnaire_counts{total} = $questionnaire_counts{0} + $questionnaire_counts{1}; @@ -450,9 +450,11 @@ sub search_reports : Path('search_reports') { } ); + # we need to pass this in as an array as we can't + # query the object in the template as the quoting + # will have been turned off $c->stash->{problems} = [ $problems->all ]; - $c->stash->{edit_council_contacts} = 1 if ( grep {$_ eq 'councilcontacts'} keys %{$c->stash->{allowed_pages}}); @@ -501,6 +503,7 @@ sub report_edit : Path('report_edit') : Args(1) { $c->forward('get_token'); $c->forward('check_page_allowed'); + $c->forward('check_email_for_abuse', [ $problem->user->email ] ); $c->stash->{updates} = [ $c->model('DB::Comment') @@ -517,6 +520,17 @@ sub report_edit : Path('report_edit') : Args(1) { $c->forward( 'log_edit', [ $id, 'problem', 'resend' ] ); } + elsif ( $c->req->param('flaguser') ) { + $c->forward('flag_user'); + $c->stash->{problem}->discard_changes; + } + elsif ( $c->req->param('removeuserflag') ) { + $c->forward('remove_user_flag'); + $c->stash->{problem}->discard_changes; + } + elsif ( $c->req->param('banuser') ) { + $c->forward('ban_user'); + } elsif ( $c->req->param('submit') ) { $c->forward('check_token'); @@ -536,12 +550,15 @@ sub report_edit : Path('report_edit') : Args(1) { $done = 1; } + my $flagged = $c->req->param('flagged') ? 1 : 0; + # do this here so before we update the values in problem if ( $c->req->param('anonymous') ne $problem->anonymous || $c->req->param('name') ne $problem->name || $c->req->param('email') ne $problem->user->email || $c->req->param('title') ne $problem->title - || $c->req->param('detail') ne $problem->detail ) + || $c->req->param('detail') ne $problem->detail + || $flagged != $problem->flagged ) { $edited = 1; } @@ -551,6 +568,7 @@ sub report_edit : Path('report_edit') : Args(1) { $problem->detail( $c->req->param('detail') ); $problem->state( $c->req->param('state') ); $problem->name( $c->req->param('name') ); + $problem->flagged( $flagged ); if ( $c->req->param('email') ne $problem->user->email ) { my $user = $c->model('DB::User')->find_or_create( @@ -598,7 +616,6 @@ sub report_edit : Path('report_edit') : Args(1) { return 1; } - sub search_users: Path('search_users') : Args(0) { my ( $self, $c ) = @_; @@ -629,6 +646,129 @@ sub search_users: Path('search_users') : Args(0) { return 1; } +sub update_edit : Path('update_edit') : Args(1) { + my ( $self, $c, $id ) = @_; + + my ( $site_res_sql, $site_key, $site_restriction ) = + $c->cobrand->site_restriction; + my $update = $c->model('DB::Comment')->search( + { + id => $id, + %{$site_restriction}, + } + )->first; + + $c->detach( '/page_error_404_not_found', + [ _('The requested URL was not found on this server.') ] ) + unless $update; + + $c->forward('get_token'); + $c->forward('check_page_allowed'); + + $c->stash->{update} = $update; + + $c->forward('check_email_for_abuse', [ $update->user->email ] ); + + if ( $c->req->param('banuser') ) { + $c->forward('ban_user'); + } + elsif ( $c->req->param('flaguser') ) { + $c->forward('flag_user'); + $c->stash->{update}->discard_changes; + } + elsif ( $c->req->param('removeuserflag') ) { + $c->forward('remove_user_flag'); + $c->stash->{update}->discard_changes; + } + elsif ( $c->req->param('submit') ) { + $c->forward('check_token'); + + my $old_state = $update->state; + my $new_state = $c->req->param('state'); + + my $edited = 0; + + # $update->name can be null which makes ne unhappy + my $name = $update->name || ''; + + if ( $c->req->param('name') ne $name + || $c->req->param('email') ne $update->user->email + || $c->req->param('anonymous') ne $update->anonymous + || $c->req->param('text') ne $update->text ){ + $edited = 1; + } + + if ( $c->req->param('remove_photo') ) { + $update->photo(undef); + } + + $update->name( $c->req->param('name') || '' ); + $update->text( $c->req->param('text') ); + $update->anonymous( $c->req->param('anonymous') ); + $update->state( $c->req->param('state') ); + + if ( $c->req->param('email') ne $update->user->email ) { + my $user = + $c->model('DB::User') + ->find_or_create( { email => $c->req->param('email') } ); + + $user->insert unless $user->in_storage; + $update->user($user); + } + + if ( $new_state eq 'confirmed' and $old_state eq 'unconfirmed' ) { + $update->confirmed( \'ms_current_timestamp()' ); + } + + $update->update; + + $c->stash->{status_message} = '<p><em>' . _('Updated!') . '</em></p>'; + + # If we're hiding an update, see if it marked as fixed and unfix if so + if ( $new_state eq 'hidden' && $update->mark_fixed ) { + if ( $update->problem->state eq 'fixed' ) { + $update->problem->state('confirmed'); + $update->problem->update; + } + + $c->stash->{status_message} .= + '<p><em>' . _('Problem marked as open.') . '</em></p>'; + } + + if ( $new_state ne $old_state ) { + $c->forward( 'log_edit', + [ $update->id, 'update', 'state_change' ] ); + } + + if ($edited) { + $c->forward( 'log_edit', [ $update->id, 'update', 'edit' ] ); + } + + } + + return 1; +} + +sub search_abuse : Path('search_abuse') : Args(0) { + my ( $self, $c ) = @_; + + $c->forward('check_page_allowed'); + + my $search = $c->req->param('search'); + + if ($search) { + my $emails = $c->model('DB::Abuse')->search( + { + email => { ilike => "\%$search\%" } + } + ); + + $c->stash->{emails} = [ $emails->all ]; + } + + return 1; +} + sub user_edit : Path('user_edit') : Args(1) { my ( $self, $c, $id ) = @_; @@ -674,6 +814,89 @@ sub user_edit : Path('user_edit') : Args(1) { return 1; } +sub list_flagged : Path('list_flagged') : Args(0) { + my ( $self, $c ) = @_; + + $c->forward('check_page_allowed'); + + my $problems = $c->model('DB::Problem')->search( { flagged => 1 } ); + + # pass in as array ref as using same template as search_reports + # which has to use an array ref for sql quoting reasons + $c->stash->{problems} = [ $problems->all ]; + + my $users = $c->model('DB::User')->search( { flagged => 1 } ); + + $c->stash->{users} = $users; + + return 1; +} + +sub stats : Path('stats') : Args(0) { + my ( $self, $c ) = @_; + + $c->forward('check_page_allowed'); + + if ( $c->req->param('getcounts') ) { + + my ( $start_date, $end_date, @errors ); + + eval { + $start_date = DateTime->new( + year => $c->req->param('start_date_year'), + month => $c->req->param('start_date_month'), + day => $c->req->param('start_date_day'), + ); + }; + + push @errors, _('Invalid start date') if $@; + + eval { + $end_date = DateTime->new( + year => $c->req->param('end_date_year'), + month => $c->req->param('end_date_month'), + day => $c->req->param('end_date_day'), + ); + }; + + push @errors, _('Invalid end date') if $@; + + $c->stash->{errors} = \@errors; + $c->stash->{start_date} = $start_date; + $c->stash->{end_date} = $end_date; + + $c->stash->{unconfirmed} = $c->req->param('unconfirmed') eq 'on' ? 1 : 0; + + return 1 if @errors; + + my $field = 'confirmed'; + + $field = 'created' if $c->req->param('unconfirmed'); + + my $one_day = DateTime::Duration->new( days => 1 ); + + my $p = $c->model('DB::Problem')->search( + { + -AND => [ + $field => { '>=', $start_date}, + $field => { '<=', $end_date + $one_day }, + ], + }, + { + select => [ 'state', { 'count' => 'me.id' } ], + as => [qw/state count/], + group_by => [ 'state' ], + order_by => [ 'state' ], + } + ); + + # in case the total_report count is 0 + $c->stash->{show_count} = 1; + $c->stash->{states} = $p; + } + + return 1; +} =head2 set_allowed_pages @@ -695,11 +918,15 @@ sub set_allowed_pages : Private { 'timeline' => [_('Timeline'), 3], 'questionnaire' => [_('Survey Results'), 4], 'search_users' => [_('Search Users'), 5], - 'council_contacts' => [undef, undef], - 'council_edit' => [undef, undef], - 'report_edit' => [undef, undef], - 'update_edit' => [undef, undef], + 'search_abuse' => [_('Search Abuse'), 5], + 'list_flagged' => [_('List Flagged'), 6], + 'stats' => [_('Stats'), 6], 'user_edit' => [undef, undef], + 'council_contacts' => [undef, undef], + 'council_edit' => [undef, undef], + 'report_edit' => [undef, undef], + 'update_edit' => [undef, undef], + 'abuse_edit' => [undef, undef], } } @@ -769,94 +996,115 @@ sub log_edit : Private { )->insert(); } -sub update_edit : Path('update_edit') : Args(1) { - my ( $self, $c, $id ) = @_; +=head2 ban_user - my ( $site_res_sql, $site_key, $site_restriction ) = - $c->cobrand->site_restriction; - my $update = $c->model('DB::Comment')->search( - { - id => $id, - %{$site_restriction}, - } - )->first; +Add the email address in the email param of the request object to +the abuse table if they are not already in there and sets status_message +accordingly - $c->detach( '/page_error_404_not_found', - [ _('The requested URL was not found on this server.') ] ) - unless $update; +=cut - $c->forward('get_token'); - $c->forward('check_page_allowed'); +sub ban_user : Private { + my ( $self, $c ) = @_; - $c->stash->{update} = $update; + my $email = $c->req->param('email'); - my $status_message = ''; - if ( $c->req->param('submit') ) { - $c->forward('check_token'); + return unless $email; - my $old_state = $update->state; - my $new_state = $c->req->param('state'); + my $abuse = $c->model('DB::Abuse')->find_or_new({ email => $email }); - my $edited = 0; + if ( $abuse->in_storage ) { + $c->stash->{status_message} = _('Email already in abuse list'); + } else { + $abuse->insert; + $c->stash->{status_message} = _('Email added to abuse list'); + } - # $update->name can be null which makes ne unhappy - my $name = $update->name || ''; + $c->stash->{email_in_abuse} = 1; - if ( $c->req->param('name') ne $name - || $c->req->param('email') ne $update->user->email - || $c->req->param('anonymous') ne $update->anonymous - || $c->req->param('text') ne $update->text ){ - $edited = 1; - } + return 1; +} - if ( $c->req->param('remove_photo') ) { - $update->photo(undef); - } +=head2 flag_user - $update->name( $c->req->param('name') || '' ); - $update->text( $c->req->param('text') ); - $update->anonymous( $c->req->param('anonymous') ); - $update->state( $c->req->param('state') ); +Sets the flag on a user with the given email - if ( $c->req->param('email') ne $update->user->email ) { - my $user = - $c->model('DB::User') - ->find_or_create( { email => $c->req->param('email') } ); +=cut - $user->insert unless $user->in_storage; - $update->user($user); - } +sub flag_user : Private { + my ( $self, $c ) = @_; - $update->update; + my $email = $c->req->param('email'); - $status_message = '<p><em>' . _('Updated!') . '</em></p>'; + return unless $email; - # If we're hiding an update, see if it marked as fixed and unfix if so - if ( $new_state eq 'hidden' && $update->mark_fixed ) { - if ( $update->problem->is_fixed ) { - $update->problem->state('confirmed'); - $update->problem->update; - } + my $user = $c->model('DB::User')->find({ email => $email }); - $status_message .= - '<p><em>' . _('Problem marked as open.') . '</em></p>'; - } + if ( !$user ) { + $c->stash->{status_message} = _('Could not find user'); + } else { + $user->flagged(1); + $user->update; + $c->stash->{status_message} = _('User flagged'); + } - if ( $new_state ne $old_state ) { - $c->forward( 'log_edit', - [ $update->id, 'update', 'state_change' ] ); - } + $c->stash->{user_flagged} = 1; - if ($edited) { - $c->forward( 'log_edit', [ $update->id, 'update', 'edit' ] ); - } + return 1; +} + +=head2 remove_user_flag + +Remove the flag on a user with the given email + +=cut +sub remove_user_flag : Private { + my ( $self, $c ) = @_; + + my $email = $c->req->param('email'); + + return unless $email; + + my $user = $c->model('DB::User')->find({ email => $email }); + + if ( !$user ) { + $c->stash->{status_message} = _('Could not find user'); + } else { + $user->flagged(0); + $user->update; + $c->stash->{status_message} = _('User flag removed'); } - $c->stash->{status_message} = $status_message; return 1; } + +=head2 check_email_for_abuse + + $c->forward('check_email_for_abuse', [ $email ] ); + +Checks if $email is in the abuse table and sets email_in_abuse accordingly + +=cut + +sub check_email_for_abuse : Private { + my ( $self, $c, $email ) =@_; + + my $is_abuse = $c->model('DB::Abuse')->find({ email => $email }); + + $c->stash->{email_in_abuse} = 1 if $is_abuse; + + return 1; +} + +=head2 check_page_allowed + +Checks if the current catalyst action is in the list of allowed pages and +if not then redirects to 404 error page. + +=cut + sub check_page_allowed : Private { my ( $self, $c ) = @_; |