aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/DB/Result/User.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perllib/FixMyStreet/DB/Result/User.pm')
-rw-r--r--perllib/FixMyStreet/DB/Result/User.pm147
1 files changed, 111 insertions, 36 deletions
diff --git a/perllib/FixMyStreet/DB/Result/User.pm b/perllib/FixMyStreet/DB/Result/User.pm
index d01ba92d0..b0a05d0b7 100644
--- a/perllib/FixMyStreet/DB/Result/User.pm
+++ b/perllib/FixMyStreet/DB/Result/User.pm
@@ -24,22 +24,30 @@ __PACKAGE__->add_columns(
},
"email",
{ data_type => "text", is_nullable => 1 },
- "email_verified",
- { data_type => "boolean", default_value => \"false", is_nullable => 0 },
"name",
{ data_type => "text", is_nullable => 1 },
"phone",
{ data_type => "text", is_nullable => 1 },
- "phone_verified",
- { data_type => "boolean", default_value => \"false", is_nullable => 0 },
"password",
{ data_type => "text", default_value => "", is_nullable => 0 },
- "from_body",
- { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
"flagged",
{ data_type => "boolean", default_value => \"false", is_nullable => 0 },
+ "from_body",
+ { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
+ "title",
+ { data_type => "text", is_nullable => 1 },
+ "facebook_id",
+ { data_type => "bigint", is_nullable => 1 },
+ "twitter_id",
+ { data_type => "bigint", is_nullable => 1 },
"is_superuser",
{ data_type => "boolean", default_value => \"false", is_nullable => 0 },
+ "extra",
+ { data_type => "text", is_nullable => 1 },
+ "email_verified",
+ { data_type => "boolean", default_value => \"false", is_nullable => 0 },
+ "phone_verified",
+ { data_type => "boolean", default_value => \"false", is_nullable => 0 },
"created",
{
data_type => "timestamp",
@@ -54,16 +62,10 @@ __PACKAGE__->add_columns(
is_nullable => 0,
original => { default_value => \"now()" },
},
- "title",
- { data_type => "text", is_nullable => 1 },
- "twitter_id",
- { data_type => "bigint", is_nullable => 1 },
- "facebook_id",
- { data_type => "bigint", is_nullable => 1 },
- "extra",
- { data_type => "text", is_nullable => 1 },
"area_ids",
{ data_type => "integer[]", is_nullable => 1 },
+ "oidc_ids",
+ { data_type => "text[]", is_nullable => 1 },
);
__PACKAGE__->set_primary_key("id");
__PACKAGE__->add_unique_constraint("users_facebook_id_key", ["facebook_id"]);
@@ -121,10 +123,16 @@ __PACKAGE__->has_many(
{ "foreign.user_id" => "self.id" },
{ cascade_copy => 0, cascade_delete => 0 },
);
+__PACKAGE__->has_many(
+ "user_roles",
+ "FixMyStreet::DB::Result::UserRole",
+ { "foreign.user_id" => "self.id" },
+ { cascade_copy => 0, cascade_delete => 0 },
+);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:BCCqv3JCec8psuRk/SdCJQ
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-06-20 16:31:44
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Ryb6giJm/7N7svg/d+2GeA
# These are not fully unique constraints (they only are when the *_verified
# is true), but this is managed in ResultSet::User's find() wrapper.
@@ -136,6 +144,7 @@ __PACKAGE__->rabx_column('extra');
use Moo;
use Text::CSV;
+use List::MoreUtils 'uniq';
use FixMyStreet::SMS;
use mySociety::EmailUtil;
use namespace::clean -except => [ 'meta' ];
@@ -143,6 +152,7 @@ use namespace::clean -except => [ 'meta' ];
with 'FixMyStreet::Roles::Extra';
__PACKAGE__->many_to_many( planned_reports => 'user_planned_reports', 'report' );
+__PACKAGE__->many_to_many( roles => 'user_roles', 'role' );
sub cost {
FixMyStreet->test_mode ? 1 : 12;
@@ -153,10 +163,30 @@ __PACKAGE__->add_columns(
encode_column => 1,
encode_class => 'Crypt::Eksblowfish::Bcrypt',
encode_args => { cost => cost() },
- encode_check_method => 'check_password',
+ encode_check_method => '_check_password',
},
);
+sub check_password {
+ my $self = shift;
+ my $cobrand = $self->result_source->schema->cobrand;
+ if ($cobrand->moniker eq 'tfl') {
+ my $col_v = $self->get_extra_metadata('tfl_password');
+ return unless defined $col_v;
+ $self->_column_encoders->{password}->($_[0], $col_v) eq $col_v;
+ } else {
+ $self->_check_password(@_);
+ }
+}
+
+around password => sub {
+ my ($orig, $self) = (shift, shift);
+ if (@_) {
+ $self->set_extra_metadata(last_password_change => time());
+ }
+ $self->$orig(@_);
+};
+
=head2 username
Returns a verified email or phone for this user, preferring email,
@@ -188,6 +218,15 @@ sub latest_anonymity {
return $obj ? $obj->anonymous : 0;
}
+sub latest_visible_problem {
+ my $self = shift;
+ return $self->problems->search({
+ state => [ FixMyStreet::DB::Result::Problem->visible_states() ]
+ }, {
+ order_by => { -desc => 'id' }
+ })->single;
+}
+
=head2 check_for_errors
$error_hashref = $user->check_for_errors();
@@ -298,7 +337,11 @@ sub body {
sub moderating_user_name {
my $self = shift;
- return $self->body || _('an administrator');
+ my $body = $self->body;
+ if ( $body && $body eq 'Isle of Wight Council' ) {
+ $body = 'Island Roads';
+ }
+ return $body || _('an administrator');
}
=head2 belongs_to_body
@@ -375,7 +418,18 @@ has body_permissions => (
lazy => 1,
default => sub {
my $self = shift;
- return [ $self->user_body_permissions->all ];
+ my $perms = [];
+ foreach my $role ($self->roles->all) {
+ push @$perms, map { {
+ body_id => $role->body_id,
+ permission => $_,
+ } } @{$role->permissions};
+ }
+ push @$perms, map { {
+ body_id => $_->body_id,
+ permission => $_->permission_type,
+ } } $self->user_body_permissions->all;
+ return $perms;
},
);
@@ -392,8 +446,8 @@ sub permissions {
return unless $self->belongs_to_body($body_id);
- my @permissions = grep { $_->body_id == $self->from_body->id } @{$self->body_permissions};
- return { map { $_->permission_type => 1 } @permissions };
+ my @permissions = grep { $_->{body_id} == $self->from_body->id } @{$self->body_permissions};
+ return { map { $_->{permission} => 1 } @permissions };
}
sub has_permission_to {
@@ -404,18 +458,15 @@ sub has_permission_to {
my $cobrand = $self->result_source->schema->cobrand;
my $cobrand_perms = $cobrand->available_permissions;
my %available = map { %$_ } values %$cobrand_perms;
- # The 'trusted' permission is never set in the cobrand's
- # available_permissions (see note there in Default.pm) so include it here.
- $available{trusted} = 1;
return 0 unless $available{$permission_type};
return 1 if $self->is_superuser;
- return 0 if !$body_ids || (ref $body_ids && !@$body_ids);
- $body_ids = [ $body_ids ] unless ref $body_ids;
+ return 0 if !$body_ids || (ref $body_ids eq 'ARRAY' && !@$body_ids);
+ $body_ids = [ $body_ids ] unless ref $body_ids eq 'ARRAY';
my %body_ids = map { $_ => 1 } @$body_ids;
foreach (@{$self->body_permissions}) {
- return 1 if $_->permission_type eq $permission_type && $body_ids{$_->body_id};
+ return 1 if $_->{permission} eq $permission_type && $body_ids{$_->{body_id}};
}
return 0;
}
@@ -464,7 +515,7 @@ sub admin_user_body_permissions {
sub has_2fa {
my $self = shift;
- return $self->is_superuser && $self->get_extra_metadata('2fa_secret');
+ return $self->get_extra_metadata('2fa_secret');
}
sub contributing_as {
@@ -516,6 +567,7 @@ sub anonymize_account {
title => undef,
twitter_id => undef,
facebook_id => undef,
+ oidc_ids => undef,
});
}
@@ -565,14 +617,6 @@ sub is_planned_report {
return scalar grep { $_->report_id == $id } @{$self->active_user_planned_reports};
}
-sub update_reputation {
- my ( $self, $change ) = @_;
-
- my $reputation = $self->get_extra_metadata('reputation') || 0;
- $self->set_extra_metadata( reputation => $reputation + $change);
- $self->update;
-}
-
has categories => (
is => 'ro',
lazy => 1,
@@ -621,4 +665,35 @@ sub in_area {
return $self->areas_hash->{$area};
}
+has roles_hash => (
+ is => 'ro',
+ lazy => 1,
+ default => sub {
+ my $self = shift;
+ my %ids = map { $_->role_id => 1 } $self->user_roles->all;
+ return \%ids;
+ },
+);
+
+sub in_role {
+ my ($self, $role) = @_;
+ return $self->roles_hash->{$role};
+}
+
+sub add_oidc_id {
+ my ($self, $oidc_id) = @_;
+
+ my $oidc_ids = $self->oidc_ids || [];
+ my @oidc_ids = uniq ( $oidc_id, @$oidc_ids );
+ $self->oidc_ids(\@oidc_ids);
+}
+
+sub remove_oidc_id {
+ my ($self, $oidc_id) = @_;
+
+ my $oidc_ids = $self->oidc_ids || [];
+ my @oidc_ids = grep { $_ ne $oidc_id } @$oidc_ids;
+ $self->oidc_ids(scalar @oidc_ids ? \@oidc_ids : undef);
+}
+
1;