Skip to content

Commit 4d8c523

Browse files
committed
Pull-request importer screen.
GitHub pull request importer screen: repos configured in Gerrit for replication with GitHub are scanned and list of opened GitHub pull requests are displayed for selection. Pull requests previously imported in Gerrit are omitted from the list. Pull requests with new commits are displayed, as the new commits will be imported as new dependent changes. Change-Id: I7e6a02859e6d5a7e76691b52625cdcacd2da2960
1 parent 7f7f7c3 commit 4d8c523

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1870
-297
lines changed

github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubLogin.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import java.io.IOException;
1818
import java.util.Arrays;
19+
import java.util.Set;
1920
import java.util.SortedSet;
2021
import java.util.TreeSet;
2122

@@ -48,24 +49,30 @@ public class GitHubLogin {
4849
private GHMyself myself;
4950

5051
public GHMyself getMyself() {
51-
return myself;
52+
if (isLoggedIn(scopesSet)) {
53+
return myself;
54+
} else {
55+
return null;
56+
}
5257
}
5358

5459
@Inject
5560
public GitHubLogin(OAuthProtocol oauth) {
5661
this.oauth = oauth;
5762
}
5863

59-
public GitHubLogin(GitHub hub, AccessToken token) {
64+
public GitHubLogin(GitHub hub, AccessToken token, Scope... scopes) {
6065
this.hub = hub;
6166
this.token = token;
67+
this.scopesSet = new TreeSet<OAuthProtocol.Scope>(Arrays.asList(scopes));
6268
}
6369

6470
public boolean isLoggedIn(Scope... scopes) {
65-
SortedSet<Scope> inputScopes =
66-
new TreeSet<OAuthProtocol.Scope>(Arrays.asList(scopes));
67-
boolean loggedIn =
68-
scopesSet.equals(inputScopes) && token != null && hub != null;
71+
return isLoggedIn(new TreeSet<Scope>(Arrays.asList(scopes)));
72+
}
73+
74+
public boolean isLoggedIn(Set<Scope> scopes) {
75+
boolean loggedIn = scopesSet.equals(scopes) && token != null && hub != null;
6976
if (loggedIn) {
7077
try {
7178
myself = hub.getMyself();

github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/OAuthConfig.java renamed to github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubOAuthConfig.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
import com.googlesource.gerrit.plugins.github.oauth.OAuthProtocol.Scope;
3030

3131
@Singleton
32-
public class OAuthConfig {
32+
public class GitHubOAuthConfig {
33+
protected static final String CONF_SECTION = "github";
3334
private static final String LOGIN_OAUTH_AUTHORIZE = "/login/oauth/authorize";
3435
private static final String GITHUB_URL = "https://github.com";
3536
public static final String OAUTH_FINAL = "/oauth";
@@ -52,26 +53,30 @@ public class OAuthConfig {
5253
public final List<OAuthProtocol.Scope> scopes;
5354

5455
@Inject
55-
public OAuthConfig(@GerritServerConfig Config config)
56+
public GitHubOAuthConfig(@GerritServerConfig Config config)
5657
throws MalformedURLException {
5758
httpHeader = config.getString("auth", null, "httpHeader");
5859
httpDisplaynameHeader = config.getString("auth", null, "httpDisplaynameHeader");
5960
httpEmailHeader = config.getString("auth", null, "httpEmailHeader");
60-
gitHubUrl =
61-
Objects.firstNonNull(config.getString("github", null, "url"),
62-
GITHUB_URL);
63-
gitHubClientId = config.getString("github", null, "clientId");
64-
gitHubClientSecret = config.getString("github", null, "clientSecret");
61+
gitHubUrl = dropTrailingSlash(
62+
Objects.firstNonNull(config.getString(CONF_SECTION, null, "url"),
63+
GITHUB_URL));
64+
gitHubClientId = config.getString(CONF_SECTION, null, "clientId");
65+
gitHubClientSecret = config.getString(CONF_SECTION, null, "clientSecret");
6566
gitHubOAuthUrl = getUrl(gitHubUrl, LOGIN_OAUTH_AUTHORIZE);
6667
gitHubOAuthAccessTokenUrl = getUrl(gitHubUrl, LOGIN_OAUTH_ACCESS_TOKEN);
67-
logoutRedirectUrl = config.getString("github", null, "logoutRedirectUrl");
68+
logoutRedirectUrl = config.getString(CONF_SECTION, null, "logoutRedirectUrl");
6869
oAuthFinalRedirectUrl =
6970
getUrl(config.getString("gerrit", null, "canonicalWebUrl"), OAUTH_FINAL);
7071

7172
enabled =
7273
config.getString("auth", null, "type").equalsIgnoreCase(
7374
AuthType.HTTP.toString());
74-
scopes = parseScopes(config.getString("github", null, "scopes"));
75+
scopes = parseScopes(config.getString(CONF_SECTION, null, "scopes"));
76+
}
77+
78+
private String dropTrailingSlash(String url) {
79+
return (url.endsWith("/") ? url.substring(0, url.length()-1):url);
7580
}
7681

7782
private List<Scope> parseScopes(String scopesString) {

github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/OAuthFilter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ public class OAuthFilter implements Filter {
4242
.getLogger(OAuthFilter.class);
4343
private static final String GERRIT_COOKIE_NAME = "GerritAccount";
4444

45-
private final OAuthConfig config;
45+
private final GitHubOAuthConfig config;
4646
private final OAuthCookieProvider cookieProvider;
4747
private final OAuthProtocol oauth;
4848

4949
@Inject
50-
public OAuthFilter(OAuthConfig config) {
50+
public OAuthFilter(GitHubOAuthConfig config) {
5151
this.config = config;
5252
this.cookieProvider = new OAuthCookieProvider(new TokenCipher());
5353
HttpClient httpClient;

github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/OAuthProtocol.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,25 @@ private Scope(final String value) {
6060
private static final Logger log = LoggerFactory
6161
.getLogger(OAuthProtocol.class);
6262

63-
private final OAuthConfig config;
63+
private final GitHubOAuthConfig config;
6464
private final HttpClient http;
6565
private final Gson gson;
6666

6767
public static class AccessToken {
6868
public String access_token;
6969
public String token_type;
70+
71+
public AccessToken() {
72+
}
73+
74+
public AccessToken(String token, String type) {
75+
this.access_token = token;
76+
this.token_type = type;
77+
}
7078
}
7179

7280
@Inject
73-
public OAuthProtocol(OAuthConfig config, HttpClient httpClient, Gson gson) {
81+
public OAuthProtocol(GitHubOAuthConfig config, HttpClient httpClient, Gson gson) {
7482
this.config = config;
7583
this.http = httpClient;
7684
this.gson = gson;
@@ -128,11 +136,11 @@ public boolean wasInitiatedByMe(HttpServletRequest request) {
128136
}
129137

130138
public boolean isOAuthLogin(HttpServletRequest request) {
131-
return request.getRequestURI().indexOf(OAuthConfig.OAUTH_LOGIN) >= 0;
139+
return request.getRequestURI().indexOf(GitHubOAuthConfig.OAUTH_LOGIN) >= 0;
132140
}
133141

134142
public boolean isOAuthLogout(HttpServletRequest request) {
135-
return request.getRequestURI().indexOf(OAuthConfig.OAUTH_LOGOUT) >= 0;
143+
return request.getRequestURI().indexOf(GitHubOAuthConfig.OAUTH_LOGOUT) >= 0;
136144
}
137145

138146
public GitHubLogin loginPhase2(HttpServletRequest request,
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright (C) 2013 The Android Open Source Project
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
package com.google.gerrit.server.account;
15+
16+
import java.io.IOException;
17+
18+
import org.apache.http.HttpStatus;
19+
import org.kohsuke.github.GHUser;
20+
21+
import com.google.gerrit.extensions.restapi.BadRequestException;
22+
import com.google.gerrit.extensions.restapi.ResourceConflictException;
23+
import com.google.gerrit.extensions.restapi.Response;
24+
import com.google.gerrit.extensions.restapi.TopLevelResource;
25+
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
26+
import com.google.gerrit.reviewdb.client.Account;
27+
import com.google.gerrit.server.account.CreateAccount.Factory;
28+
import com.google.gwtorm.server.OrmException;
29+
import com.google.inject.Inject;
30+
31+
public class AccountImpoter {
32+
private Factory createAccountFactory;
33+
34+
@Inject
35+
public AccountImpoter(CreateAccount.Factory createAccountFactory) {
36+
this.createAccountFactory = createAccountFactory;
37+
}
38+
39+
public Account.Id importAccount(GHUser user) throws IOException,
40+
BadRequestException, ResourceConflictException,
41+
UnprocessableEntityException, OrmException {
42+
CreateAccount createAccount = createAccountFactory.create(user.getLogin());
43+
CreateAccount.Input accountInput = new CreateAccount.Input();
44+
accountInput.email = user.getEmail();
45+
accountInput.name = user.getName();
46+
accountInput.username = user.getLogin();
47+
Response<AccountInfo> accountResponse =
48+
(Response<AccountInfo>) createAccount.apply(TopLevelResource.INSTANCE,
49+
accountInput);
50+
if (accountResponse.statusCode() == HttpStatus.SC_CREATED) {
51+
return accountResponse.value()._id;
52+
} else {
53+
throw new IOException("Cannot import GitHub account " + user.getLogin()
54+
+ ": HTTP Status " + accountResponse.statusCode());
55+
}
56+
}
57+
}

github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/GitHubConfig.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,32 @@
1313
// limitations under the License.
1414
package com.googlesource.gerrit.plugins.github;
1515

16+
import java.io.File;
17+
import java.net.MalformedURLException;
1618
import java.util.HashMap;
1719

1820
import org.eclipse.jgit.lib.Config;
1921

2022
import com.google.gerrit.server.config.GerritServerConfig;
23+
import com.google.gerrit.server.config.SitePaths;
2124
import com.google.inject.Inject;
2225
import com.google.inject.Singleton;
26+
import com.googlesource.gerrit.plugins.github.oauth.GitHubOAuthConfig;
2327

2428
@Singleton
25-
public class GitHubConfig {
29+
public class GitHubConfig extends GitHubOAuthConfig {
2630

27-
private static final String CONF_SECTION = "github";
2831
private static final String CONF_WIZARD_FLOW = "wizardFlow";
2932
private HashMap<String, String> wizardFromTo = new HashMap<String, String>();
3033
private static final String FROM_TO_SEPARATOR = "=>";
3134

35+
public final File gitDir;
36+
37+
3238
@Inject
33-
public GitHubConfig(@GerritServerConfig Config config) {
39+
public GitHubConfig(@GerritServerConfig Config config, final SitePaths site)
40+
throws MalformedURLException {
41+
super(config);
3442
String[] wizardFlows =
3543
config.getStringList(CONF_SECTION, null, CONF_WIZARD_FLOW);
3644
for (String fromTo : wizardFlows) {
@@ -40,6 +48,10 @@ public GitHubConfig(@GerritServerConfig Config config) {
4048
fromTo.substring(sepPos + FROM_TO_SEPARATOR.length() + 1).trim();
4149
wizardFromTo.put(fromPage, toPage);
4250
}
51+
gitDir = site.resolve(config.getString("gerrit", null, "basePath"));
52+
if (gitDir == null) {
53+
throw new IllegalStateException("gerrit.basePath must be configured");
54+
}
4355
}
4456

4557
private int getSepPos(String fromTo) {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright (C) 2013 The Android Open Source Project
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
package com.googlesource.gerrit.plugins.github;
15+
16+
import java.lang.annotation.ElementType;
17+
import java.lang.annotation.Retention;
18+
import java.lang.annotation.RetentionPolicy;
19+
import java.lang.annotation.Target;
20+
21+
import com.google.inject.BindingAnnotation;
22+
23+
@Target({ElementType.PARAMETER, ElementType.FIELD})
24+
@Retention(RetentionPolicy.RUNTIME)
25+
@BindingAnnotation
26+
public @interface GitHubURL {
27+
28+
}

github-plugin/src/main/java/com/googlesrouce/gerrit/plugins/github/git/GitConfig.java renamed to github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/GitHubURLProvider.java

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,23 @@
1111
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
14-
package com.googlesrouce.gerrit.plugins.github.git;
14+
package com.googlesource.gerrit.plugins.github;
1515

16-
import java.io.File;
17-
18-
import org.eclipse.jgit.lib.Config;
19-
20-
import com.google.gerrit.server.config.GerritServerConfig;
21-
import com.google.gerrit.server.config.SitePaths;
2216
import com.google.inject.Inject;
23-
import com.google.inject.Singleton;
17+
import com.google.inject.Provider;
2418

25-
@Singleton
26-
public class GitConfig {
19+
public class GitHubURLProvider implements Provider<String> {
2720

28-
public final File gitDir;
21+
private String gitHubUrl;
2922

30-
public GitConfig(File gitDir) {
31-
this.gitDir = gitDir;
23+
@Inject
24+
public GitHubURLProvider(GitHubConfig gitHubConfig) {
25+
this.gitHubUrl = gitHubConfig.gitHubUrl;
3226
}
3327

34-
@Inject
35-
public GitConfig(final SitePaths site, @GerritServerConfig final Config cfg) {
36-
gitDir = site.resolve(cfg.getString("gerrit", null, "basePath"));
37-
if (gitDir == null) {
38-
throw new IllegalStateException("gerrit.basePath must be configured");
39-
}
28+
@Override
29+
public String get() {
30+
return gitHubUrl;
4031
}
32+
4133
}

github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/GuiceHttpModule.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import com.googlesource.gerrit.plugins.github.oauth.GitHubHttpProvider;
2222
import com.googlesource.gerrit.plugins.github.pullsync.PullRequestsServlet;
2323
import com.googlesource.gerrit.plugins.github.replication.RemoteSiteUser;
24-
import com.googlesource.gerrit.plugins.github.velocity.PluginVelocityModelFilter;
2524
import com.googlesource.gerrit.plugins.github.velocity.VelocityStaticServlet;
2625
import com.googlesource.gerrit.plugins.github.velocity.VelocityViewServlet;
2726
import com.googlesource.gerrit.plugins.github.wizard.VelocityControllerServlet;
@@ -40,8 +39,5 @@ protected void configureServlets() {
4039
serve("*.gh").with(VelocityControllerServlet.class);
4140

4241
filter("*").through(GitHubOAuthFilter.class);
43-
filter("*.html").through(PluginVelocityModelFilter.class);
44-
45-
4642
}
4743
}

github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/GuiceModule.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import com.googlesource.gerrit.plugins.github.velocity.PluginVelocityRuntimeProvider;
2424
import com.googlesrouce.gerrit.plugins.github.git.CreateProjectStep;
2525
import com.googlesrouce.gerrit.plugins.github.git.GitCloneStep;
26+
import com.googlesrouce.gerrit.plugins.github.git.PullRequestImportJob;
27+
import com.googlesrouce.gerrit.plugins.github.git.PullRequestImporter;
2628
import com.googlesrouce.gerrit.plugins.github.git.ReplicateProjectStep;
2729

2830
public class GuiceModule extends AbstractModule {
@@ -34,10 +36,13 @@ protected void configure() {
3436
CreateProjectStep.class).build(CreateProjectStep.Factory.class));
3537
install(new FactoryModuleBuilder().implement(ReplicateProjectStep.class,
3638
ReplicateProjectStep.class).build(ReplicateProjectStep.Factory.class));
39+
install(new FactoryModuleBuilder().implement(PullRequestImportJob.class,
40+
PullRequestImportJob.class).build(PullRequestImportJob.Factory.class));
3741

3842
bind(RuntimeInstance.class).annotatedWith(
3943
Names.named("PluginRuntimeInstance")).toProvider(
4044
PluginVelocityRuntimeProvider.class);
41-
45+
46+
bind(String.class).annotatedWith(GitHubURL.class).toProvider(GitHubURLProvider.class);
4247
}
4348
}

0 commit comments

Comments
 (0)