]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 1619609 - Update /rest/whoami to return group membership, and support authenticat...
authorbyron jones <byron@glob.com.au>
Fri, 6 Mar 2020 16:11:16 +0000 (00:11 +0800)
committerGitHub <noreply@github.com>
Fri, 6 Mar 2020 16:11:16 +0000 (11:11 -0500)
Bugzilla/WebService/Constants.pm
Bugzilla/WebService/User.pm

index 92be217946ddba5ae22211180be5be7dbad177e0..fdd0d907698f0f3b9659f1b1709a6c867bbb3cf8 100644 (file)
@@ -330,6 +330,7 @@ use constant API_AUTH_HEADERS => {
   X_BUGZILLA_PASSWORD => 'Bugzilla_password',
   X_BUGZILLA_API_KEY  => 'Bugzilla_api_key',
   X_BUGZILLA_TOKEN    => 'Bugzilla_token',
+  X_PHABRICATOR_TOKEN => 'Phabricator_token',  # 'whoami' only
 };
 
 1;
index 8a68e35ee7ace36e7730cc3ed4098b417f1a3059..d6dd8ba88f4f3885755d8867d7febba218dacbdc 100644 (file)
@@ -17,13 +17,16 @@ use Bugzilla;
 use Bugzilla::Constants;
 use Bugzilla::Error;
 use Bugzilla::Group;
+use Bugzilla::Logging;
 use Bugzilla::User;
 use Bugzilla::Util qw(trim detaint_natural);
 use Bugzilla::WebService::Util qw(filter filter_wants validate
   translate params_to_objects);
 use Bugzilla::Hook;
 
+use Mojo::UserAgent ();
 use List::Util qw(first);
+use Try::Tiny;
 
 # Don't need auth to login
 use constant LOGIN_EXEMPT => {login => 1, offer_account_by_email => 1,};
@@ -489,7 +492,7 @@ sub mfa_enroll {
 
 sub whoami {
   my ($self, $params) = @_;
-  my $user = Bugzilla->login(LOGIN_REQUIRED);
+  my $user = _user_from_phab_token() || Bugzilla->login(LOGIN_REQUIRED);
   return filter(
     $params,
     {
@@ -498,10 +501,56 @@ sub whoami {
       nick       => $self->type('string',  $user->nick),
       name       => $self->type('email',   $user->login),
       mfa_status => $self->type('boolean', !!$user->mfa),
+      groups     => [map { $_->name } @{$user->groups}],
     }
   );
 }
 
+sub _user_from_phab_token {
+
+  # BMO - If a token is provided in the X-PHABRICATOR-TOKEN header, we use that
+  # to request the associated email address from Phabricator via its
+  # `user.whoami` endpoint.
+
+  # only if PhabBugz is configure and X-PHABRICATOR-TOKEN is provided
+  (my $phab_url = Bugzilla->params->{phabricator_base_uri}) =~ s{/$}{};
+  my $phab_token = Bugzilla->input_params->{Phabricator_token};
+  return undef unless $phab_url && $phab_token;
+
+  try {
+    # query phabricator's whoami endpoint
+    my $res = _ua()
+      ->get("$phab_url/api/user.whoami" => form => {'api.token' => $phab_token});
+    my $ph_whoami = $res->result->json;
+
+    # treat any phabricator generated error as an invalid api-key
+    if (my $error = $ph_whoami->{error_info}) {
+      ThrowUserError("api_key_not_valid");
+    }
+
+    # load user from primaryEmail
+    return Bugzilla::User->new(
+      {name => $ph_whoami->{result}->{primaryEmail}, cache => 1})
+      || ThrowUserError("api_key_not_valid");
+  }
+  catch {
+    WARN("Request to $phab_url failed: $_");
+    ThrowUserError("api_key_not_valid");
+  };
+}
+
+sub _ua {
+  my $ua = Mojo::UserAgent->new(request_timeout => 10);
+  $ua->transactor->name('BMO user.whoami shim');
+  if (my $proxy = Bugzilla->params->{proxy_url}) {
+    $ua->proxy->http($proxy)->https($proxy);
+  }
+  else {
+    $ua->proxy->detect();
+  }
+  return $ua;
+}
+
 1;
 
 __END__