Don't fail when GitHub has no access to orgs

When GitHub OAuth scope is configured to denied access to the Teams
and organisations, do not show an error page and just fails gracefully
still allowing to list the user's repos.

Change-Id: I1d2266ea846bb261edbfc10e4c13733219e77205
diff --git a/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubLogin.java b/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubLogin.java
index 1625b81..f9cdf80 100644
--- a/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubLogin.java
+++ b/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubLogin.java
@@ -67,7 +67,7 @@
 
   public GHMyself getMyself() throws IOException {
     if (isLoggedIn()) {
-      return getHub().getMyself();
+      return new GitHubMyselfWrapper(getHub().getMyself());
     }
     return null;
   }
diff --git a/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubMyselfWrapper.java b/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubMyselfWrapper.java
new file mode 100644
index 0000000..2336521
--- /dev/null
+++ b/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubMyselfWrapper.java
@@ -0,0 +1,286 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.github.oauth;
+
+import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.kohsuke.github.GHEmail;
+import org.kohsuke.github.GHEventInfo;
+import org.kohsuke.github.GHGist;
+import org.kohsuke.github.GHKey;
+import org.kohsuke.github.GHMyself;
+import org.kohsuke.github.GHOrganization;
+import org.kohsuke.github.GHPersonSet;
+import org.kohsuke.github.GHRepository;
+import org.kohsuke.github.GHTeam;
+import org.kohsuke.github.GHUser;
+import org.kohsuke.github.GHVerifiedKey;
+import org.kohsuke.github.PagedIterable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GitHubMyselfWrapper extends GHMyself {
+  private static final Logger log = LoggerFactory.getLogger(GitHubMyselfWrapper.class);
+
+  private final GHMyself wrapped;
+
+  public GitHubMyselfWrapper(GHMyself wrapped) {
+    this.wrapped = wrapped;
+  }
+
+  @Override
+  public List<String> getEmails() throws IOException {
+    return wrapped.getEmails();
+  }
+
+  @Override
+  public List<GHEmail> getEmails2() throws IOException {
+    return wrapped.getEmails2();
+  }
+
+  @Override
+  public List<GHKey> getPublicKeys() throws IOException {
+    return wrapped.getPublicKeys();
+  }
+
+  @Override
+  public List<GHVerifiedKey> getPublicVerifiedKeys() throws IOException {
+    return wrapped.getPublicVerifiedKeys();
+  }
+
+  @Override
+  public GHPersonSet<GHOrganization> getAllOrganizations() throws IOException {
+    try {
+      return wrapped.getAllOrganizations();
+    } catch (IOException e) {
+      log.warn("Unable to list all organizations for user {}", getLogin(), e);
+      return new GHPersonSet<>();
+    }
+  }
+
+  @Override
+  public Map<String, GHRepository> getAllRepositories() throws IOException {
+    return wrapped.getAllRepositories();
+  }
+
+  @Override
+  public PagedIterable<GHRepository> listRepositories() {
+    return wrapped.listRepositories();
+  }
+
+  @Override
+  public PagedIterable<GHRepository> listRepositories(int pageSize) {
+    return wrapped.listRepositories(pageSize);
+  }
+
+  @Override
+  public PagedIterable<GHRepository> listRepositories(int pageSize, RepositoryListFilter repoType) {
+    return wrapped.listRepositories(pageSize, repoType);
+  }
+
+  @Override
+  public PagedIterable<GHRepository> listAllRepositories() {
+    return wrapped.listAllRepositories();
+  }
+
+  @Override
+  public void follow() throws IOException {
+    wrapped.follow();
+  }
+
+  @Override
+  public void unfollow() throws IOException {
+    wrapped.unfollow();
+  }
+
+  @Override
+  @WithBridgeMethods({Set.class})
+  public GHPersonSet<GHUser> getFollows() throws IOException {
+    return wrapped.getFollows();
+  }
+
+  @Override
+  @WithBridgeMethods({Set.class})
+  public GHPersonSet<GHUser> getFollowers() throws IOException {
+    return wrapped.getFollowers();
+  }
+
+  @Override
+  public PagedIterable<GHRepository> listSubscriptions() {
+    return wrapped.listSubscriptions();
+  }
+
+  @Override
+  public boolean isMemberOf(GHOrganization org) {
+    return wrapped.isMemberOf(org);
+  }
+
+  @Override
+  public boolean isMemberOf(GHTeam team) {
+    return wrapped.isMemberOf(team);
+  }
+
+  @Override
+  public boolean isPublicMemberOf(GHOrganization org) {
+    return wrapped.isPublicMemberOf(org);
+  }
+
+  @Override
+  @WithBridgeMethods({Set.class})
+  public GHPersonSet<GHOrganization> getOrganizations() throws IOException {
+    try {
+      return wrapped.getOrganizations();
+    } catch (IOException e) {
+      log.warn("Unable to list organizations for user {}", getLogin(), e);
+      return new GHPersonSet<>();
+    }
+  }
+
+  @Override
+  public PagedIterable<GHEventInfo> listEvents() throws IOException {
+    return wrapped.listEvents();
+  }
+
+  @Override
+  public PagedIterable<GHGist> listGists() throws IOException {
+    return wrapped.listGists();
+  }
+
+  @Override
+  public String toString() {
+    return wrapped.toString();
+  }
+
+  @Override
+  public int hashCode() {
+    return wrapped.hashCode();
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    return wrapped.equals(obj);
+  }
+
+  @Override
+  public Map<String, GHRepository> getRepositories() throws IOException {
+    return wrapped.getRepositories();
+  }
+
+  @Override
+  public Iterable<List<GHRepository>> iterateRepositories(int pageSize) {
+    return wrapped.iterateRepositories(pageSize);
+  }
+
+  @Override
+  public GHRepository getRepository(String name) throws IOException {
+    return wrapped.getRepository(name);
+  }
+
+  @Override
+  public String getGravatarId() {
+    return wrapped.getGravatarId();
+  }
+
+  @Override
+  public String getAvatarUrl() {
+    return wrapped.getAvatarUrl();
+  }
+
+  @Override
+  public String getLogin() {
+    return wrapped.getLogin();
+  }
+
+  @Override
+  public String getName() throws IOException {
+    return wrapped.getName();
+  }
+
+  @Override
+  public String getCompany() throws IOException {
+    return wrapped.getCompany();
+  }
+
+  @Override
+  public String getLocation() throws IOException {
+    return wrapped.getLocation();
+  }
+
+  @Override
+  public Date getCreatedAt() throws IOException {
+    return wrapped.getCreatedAt();
+  }
+
+  @Override
+  public Date getUpdatedAt() throws IOException {
+    return wrapped.getUpdatedAt();
+  }
+
+  @Override
+  public String getBlog() throws IOException {
+    return wrapped.getBlog();
+  }
+
+  @Override
+  public URL getHtmlUrl() {
+    return wrapped.getHtmlUrl();
+  }
+
+  @Override
+  public String getEmail() throws IOException {
+    return wrapped.getEmail();
+  }
+
+  @Override
+  public int getPublicGistCount() throws IOException {
+    return wrapped.getPublicGistCount();
+  }
+
+  @Override
+  public int getPublicRepoCount() throws IOException {
+    return wrapped.getPublicRepoCount();
+  }
+
+  @Override
+  public int getFollowingCount() throws IOException {
+    return wrapped.getFollowingCount();
+  }
+
+  @Override
+  public int getFollowersCount() throws IOException {
+    return wrapped.getFollowersCount();
+  }
+
+  @Override
+  @WithBridgeMethods(
+      value = {String.class},
+      adapterMethod = "urlToString")
+  public URL getUrl() {
+    return wrapped.getUrl();
+  }
+
+  @Override
+  @WithBridgeMethods(
+      value = {String.class},
+      adapterMethod = "intToString")
+  public int getId() {
+    return wrapped.getId();
+  }
+}