summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--extensions/PhabBugz/lib/User.pm194
1 files changed, 194 insertions, 0 deletions
diff --git a/extensions/PhabBugz/lib/User.pm b/extensions/PhabBugz/lib/User.pm
new file mode 100644
index 000000000..0441c281b
--- /dev/null
+++ b/extensions/PhabBugz/lib/User.pm
@@ -0,0 +1,194 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This Source Code Form is "Incompatible With Secondary Licenses", as
+# defined by the Mozilla Public License, v. 2.0.
+
+package Bugzilla::Extension::PhabBugz::User;
+
+use 5.10.1;
+use Moo;
+
+use Bugzilla::User;
+
+use Bugzilla::Extension::PhabBugz::Util qw(request);
+
+use List::Util qw(first);
+use Types::Standard -all;
+use Type::Utils;
+
+#########################
+# Initialization #
+#########################
+
+has 'id' => ( is => 'ro', isa => Int );
+has 'type' => ( is => 'ro', isa => Str );
+has 'phid' => ( is => 'ro', isa => Str );
+has 'name' => ( is => 'ro', isa => Str );
+has 'realname' => ( is => 'ro', isa => Str );
+has 'creation_ts' => ( is => 'ro', isa => Int );
+has 'modification_ts' => ( is => 'ro', isa => Int );
+has 'roles' => ( is => 'ro', isa => ArrayRef [Str] );
+has 'view_policy' => ( is => 'ro', isa => Str );
+has 'edit_policy' => ( is => 'ro', isa => Str );
+has 'bugzilla_id' => ( is => 'ro', isa => Maybe [Int] );
+has 'bugzilla_user' => ( is => 'lazy' );
+
+sub BUILDARGS {
+ my ( $class, $params ) = @_;
+
+ $params->{name} = $params->{fields}->{username};
+ $params->{realname} = $params->{fields}->{realName};
+ $params->{creation_ts} = $params->{fields}->{dateCreated};
+ $params->{modification_ts} = $params->{fields}->{dateModified};
+ $params->{roles} = $params->{fields}->{roles};
+ $params->{view_policy} = $params->{fields}->{policy}->{view};
+ $params->{edit_policy} = $params->{fields}->{policy}->{edit};
+
+ delete $params->{fields};
+
+ my $external_accounts =
+ $params->{attachments}{'external-accounts'}{'external-accounts'};
+ if ($external_accounts) {
+ my $bug_user = first { $_->{type} ne 'bmo' } @$external_accounts;
+ $params->{bugzilla_id} = $bug_user->{id};
+ }
+
+ delete $params->{attachments};
+
+ return $params;
+}
+
+# {
+# "data": [
+# {
+# "id": 2,
+# "type": "USER",
+# "phid": "PHID-USER-h4aqihzqsnytz7nsegsr",
+# "fields": {
+# "username": "phab-bot",
+# "realName": "Phabricator Automation",
+# "roles": [
+# "admin",
+# "verified",
+# "approved",
+# "activated"
+# ],
+# "dateCreated": 1512573120,
+# "dateModified": 1512574523,
+# "policy": {
+# "view": "public",
+# "edit": "no-one"
+# }
+# },
+# "attachments": {
+# "external-accounts": {
+# "external-accounts": [
+# {
+# "id": "9",
+# "type": "bmo"
+# }
+# ]
+# }
+# }
+# }
+# ],
+# "maps": {},
+# "query": {
+# "queryKey": null
+# },
+# "cursor": {
+# "limit": 100,
+# "after": null,
+# "before": null,
+# "order": null
+# }
+# }
+
+sub new_from_query {
+ my ( $class, $params ) = @_;
+ my $matches = $class->match($params);
+ return $matches->[0];
+}
+
+sub match {
+ my ( $class, $params ) = @_;
+
+ # BMO id search takes precedence if bugzilla_ids is used.
+ my $bugzilla_ids = delete $params->{bugzilla_ids};
+ if ($bugzilla_ids) {
+ my $bugzilla_data =
+ $class->get_phab_bugzilla_ids( { ids => $bugzilla_ids } );
+ $params->{phids} = [ map { $_->{phid} } @$bugzilla_data ];
+ }
+
+ return [] if !$params->{phids};
+
+ # Look for BMO external user id in external-accounts attachment
+ my $data = {
+ constraints => { phids => $params->{phids} },
+ attachments => { external_accounts => 1 }
+ };
+
+ my $phab_users = [];
+ my $result = request( 'user.search', $data );
+
+ if ( exists $result->{result}{data} && @{ $result->{result}{data} } ) {
+ foreach my $user ( @{ $result->{result}{data} } ) {
+ push @$phab_users, $class->new($user);
+ }
+ }
+
+ return $phab_users;
+}
+
+#################
+# Accessors #
+#################
+
+sub _build_bugzilla_user {
+ my ($self) = @_;
+ return undef unless $self->bugzilla_id;
+ return Bugzilla::User->new( { id => $self->bugzilla_id, cache => 1 } );
+}
+
+sub get_phab_bugzilla_ids {
+ my ( $class, $params ) = @_;
+
+ my $memcache = Bugzilla->memcached;
+
+ # Try to find the values in memcache first
+ my @results;
+ my %bugzilla_ids = map { $_ => 1 } @{ $params->{ids} };
+ foreach my $bugzilla_id ( keys %bugzilla_ids ) {
+ my $phid =
+ $memcache->get( { key => "phab_user_bugzilla_id_" . $bugzilla_id } );
+ if ($phid) {
+ push @results, { id => $bugzilla_id, phid => $phid };
+ delete $bugzilla_ids{$bugzilla_id};
+ }
+ }
+
+ if (%bugzilla_ids) {
+ $params->{ids} = [ keys %bugzilla_ids ];
+
+ my $result = request( 'bugzilla.account.search', $params );
+
+ # Store new values in memcache for later retrieval
+ foreach my $user ( @{ $result->{result} } ) {
+ $memcache->set(
+ {
+ key => "phab_user_bugzilla_id_" . $user->{id},
+ value => $user->{phid}
+ }
+ );
+ push @results, $user;
+ }
+ }
+
+ return \@results;
+}
+
+1;
+