Skip to content

Commit

Permalink
Merge remote-tracking branch 'oauth/master'
Browse files Browse the repository at this point in the history
* oauth/master:
  Update bazlets to most recent version
  Bazel: Simplify eclipse project generation
  Format Java files with google-java-format
  GitLabApi: Fix eclipse warnings
  HttpModule: Consistently use InitOAuth.CLIENT_ID constant
  Google OAuth provider: Allow multiple hosted domains
  • Loading branch information
davido committed Jul 9, 2017
2 parents 5ed3825 + 4a16d4c commit 880c4d2
Show file tree
Hide file tree
Showing 20 changed files with 335 additions and 428 deletions.
2 changes: 1 addition & 1 deletion WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ workspace(name = "com_github_davido_gerrit_oauth_provider")
load("//:bazlets.bzl", "load_bazlets")

load_bazlets(
commit = "0f87babe07a555425d829c6e7951e296e9e24579",
commit = "d1dd04380a2e41a32fca265c999936c35fcfae14",
# local_path = "/home/<user>/projects/bazlets",
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@

package com.googlesource.gerrit.plugins.oauth;

import static com.google.gerrit.server.OutputFormat.JSON;
import static java.lang.String.format;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static org.scribe.model.OAuthConstants.ACCESS_TOKEN;
import static org.scribe.model.OAuthConstants.CODE;

import com.google.common.io.BaseEncoding;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
Expand All @@ -28,21 +34,14 @@
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuthService;

import static com.google.gerrit.server.OutputFormat.JSON;
import static java.lang.String.format;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static org.scribe.model.OAuthConstants.ACCESS_TOKEN;
import static org.scribe.model.OAuthConstants.CODE;

public class BitbucketApi extends DefaultApi20 {

private static final String AUTHORIZE_URL =
"https://bitbucket.org/site/oauth2/authorize?client_id=%s&response_type=code";
private static final String ACCESS_TOKEN_ENDPOINT =
"https://bitbucket.org/site/oauth2/access_token";

public BitbucketApi() {
}
public BitbucketApi() {}

@Override
public String getAuthorizationUrl(OAuthConfig config) {
Expand Down Expand Up @@ -85,8 +84,8 @@ private BitbucketOAuthService(DefaultApi20 api, OAuthConfig config) {

@Override
public Token getAccessToken(Token token, Verifier verifier) {
OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(),
api.getAccessTokenEndpoint());
OAuthRequest request =
new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint());
request.addHeader("Authorization", prepareAuthorizationHeaderValue());
request.addBodyParameter(GRANT_TYPE, GRANT_TYPE_VALUE);
request.addBodyParameter(CODE, verifier.getValue());
Expand All @@ -97,7 +96,8 @@ public Token getAccessToken(Token token, Verifier verifier) {
}

throw new OAuthException(
String.format("Error response received: %s, HTTP status: %s",
String.format(
"Error response received: %s, HTTP status: %s",
response.getBody(), response.getCode()));
}

Expand Down Expand Up @@ -129,8 +129,7 @@ public String getAuthorizationUrl(Token token) {
}
}

private static final class BitbucketTokenExtractor
implements AccessTokenExtractor {
private static final class BitbucketTokenExtractor implements AccessTokenExtractor {

@Override
public Token extract(String response) {
Expand All @@ -139,15 +138,13 @@ public Token extract(String response) {
JsonObject jsonObject = json.getAsJsonObject();
JsonElement id = jsonObject.get(ACCESS_TOKEN);
if (id == null || id.isJsonNull()) {
throw new OAuthException(
"Response doesn't contain 'access_token' field");
throw new OAuthException("Response doesn't contain 'access_token' field");
}
JsonElement accessToken = jsonObject.get(ACCESS_TOKEN);
return new Token(accessToken.getAsString(), "");
}

throw new OAuthException(
String.format("Invalid JSON '%s': not a JSON Object", json));
throw new OAuthException(String.format("Invalid JSON '%s': not a JSON Object", json));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

package com.googlesource.gerrit.plugins.oauth;

import static com.google.gerrit.server.OutputFormat.JSON;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static org.slf4j.LoggerFactory.getLogger;

import com.google.common.base.CharMatcher;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider;
Expand All @@ -28,6 +32,7 @@
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
import org.scribe.builder.ServiceBuilder;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
Expand All @@ -37,37 +42,31 @@
import org.scribe.oauth.OAuthService;
import org.slf4j.Logger;

import java.io.IOException;

import static com.google.gerrit.server.OutputFormat.JSON;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static org.slf4j.LoggerFactory.getLogger;

@Singleton
public class BitbucketOAuthService implements OAuthServiceProvider {
private static final Logger log = getLogger(BitbucketOAuthService.class);
static final String CONFIG_SUFFIX = "-bitbucket-oauth";
private final static String BITBUCKET_PROVIDER_PREFIX = "bitbucket-oauth:";
private static final String PROTECTED_RESOURCE_URL =
"https://bitbucket.org/api/1.0/user/";
private static final String BITBUCKET_PROVIDER_PREFIX = "bitbucket-oauth:";
private static final String PROTECTED_RESOURCE_URL = "https://bitbucket.org/api/1.0/user/";
private final boolean fixLegacyUserId;
private final OAuthService service;

@Inject
BitbucketOAuthService(PluginConfigFactory cfgFactory,
BitbucketOAuthService(
PluginConfigFactory cfgFactory,
@PluginName String pluginName,
@CanonicalWebUrl Provider<String> urlProvider) {
PluginConfig cfg =
cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX);
PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX);

String canonicalWebUrl =
CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/";
String canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/";
fixLegacyUserId = cfg.getBoolean(InitOAuth.FIX_LEGACY_USER_ID, false);
service = new ServiceBuilder().provider(BitbucketApi.class)
.apiKey(cfg.getString(InitOAuth.CLIENT_ID))
.apiSecret(cfg.getString(InitOAuth.CLIENT_SECRET))
.callback(canonicalWebUrl + "oauth")
.build();
service =
new ServiceBuilder()
.provider(BitbucketApi.class)
.apiKey(cfg.getString(InitOAuth.CLIENT_ID))
.apiSecret(cfg.getString(InitOAuth.CLIENT_SECRET))
.callback(canonicalWebUrl + "oauth")
.build();
}

@Override
Expand All @@ -77,11 +76,12 @@ public OAuthUserInfo getUserInfo(OAuthToken token) throws IOException {
service.signRequest(t, request);
Response response = request.send();
if (response.getCode() != SC_OK) {
throw new IOException(String.format("Status %s (%s) for request %s",
response.getCode(), response.getBody(), request.getUrl()));
throw new IOException(
String.format(
"Status %s (%s) for request %s",
response.getCode(), response.getBody(), request.getUrl()));
}
JsonElement userJson =
JSON.newGson().fromJson(response.getBody(), JsonElement.class);
JsonElement userJson = JSON.newGson().fromJson(response.getBody(), JsonElement.class);
if (log.isDebugEnabled()) {
log.debug("User info response: {}", response.getBody());
}
Expand All @@ -99,14 +99,11 @@ public OAuthUserInfo getUserInfo(OAuthToken token) throws IOException {
BITBUCKET_PROVIDER_PREFIX + username,
username,
null,
displayName == null || displayName.isJsonNull()
? null
: displayName.getAsString(),
displayName == null || displayName.isJsonNull() ? null : displayName.getAsString(),
fixLegacyUserId ? username : null);
}

throw new IOException(
String.format("Invalid JSON '%s': not a JSON Object", userJson));
throw new IOException(String.format("Invalid JSON '%s': not a JSON Object", userJson));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
import org.scribe.utils.OAuthEncoder;

public class CasApi extends DefaultApi20 {
private static final String AUTHORIZE_URL =
"%s/oauth2.0/authorize?client_id=%s&redirect_uri=%s";
private static final String AUTHORIZE_URL = "%s/oauth2.0/authorize?client_id=%s&redirect_uri=%s";

private final String rootUrl;

Expand All @@ -35,7 +34,7 @@ public String getAccessTokenEndpoint() {

@Override
public String getAuthorizationUrl(OAuthConfig config) {
return String.format(AUTHORIZE_URL, rootUrl, config.getApiKey(),
OAuthEncoder.encode(config.getCallback()));
return String.format(
AUTHORIZE_URL, rootUrl, config.getApiKey(), OAuthEncoder.encode(config.getCallback()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;

import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.scribe.builder.ServiceBuilder;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
Expand All @@ -41,102 +42,89 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

import javax.servlet.http.HttpServletResponse;

@Singleton
class CasOAuthService implements OAuthServiceProvider {
private static final Logger log =
LoggerFactory.getLogger(CasOAuthService.class);
private static final Logger log = LoggerFactory.getLogger(CasOAuthService.class);
static final String CONFIG_SUFFIX = "-cas-oauth";
private final static String CAS_PROVIDER_PREFIX = "cas-oauth:";
private static final String PROTECTED_RESOURCE_URL =
"%s/oauth2.0/profile";
private static final String CAS_PROVIDER_PREFIX = "cas-oauth:";
private static final String PROTECTED_RESOURCE_URL = "%s/oauth2.0/profile";

private final String rootUrl;
private final boolean fixLegacyUserId;
private final OAuthService service;

@Inject
CasOAuthService(PluginConfigFactory cfgFactory,
CasOAuthService(
PluginConfigFactory cfgFactory,
@PluginName String pluginName,
@CanonicalWebUrl Provider<String> urlProvider) {
PluginConfig cfg = cfgFactory.getFromGerritConfig(
pluginName + CONFIG_SUFFIX);
PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX);
rootUrl = cfg.getString(InitOAuth.ROOT_URL);
String canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(
urlProvider.get()) + "/";
String canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/";
fixLegacyUserId = cfg.getBoolean(InitOAuth.FIX_LEGACY_USER_ID, false);
service = new ServiceBuilder()
.provider(new CasApi(rootUrl))
.apiKey(cfg.getString(InitOAuth.CLIENT_ID))
.apiSecret(cfg.getString(InitOAuth.CLIENT_SECRET))
.callback(canonicalWebUrl + "oauth")
.build();
service =
new ServiceBuilder()
.provider(new CasApi(rootUrl))
.apiKey(cfg.getString(InitOAuth.CLIENT_ID))
.apiSecret(cfg.getString(InitOAuth.CLIENT_SECRET))
.callback(canonicalWebUrl + "oauth")
.build();
}

@Override
public OAuthUserInfo getUserInfo(OAuthToken token) throws IOException {
final String protectedResourceUrl =
String.format(PROTECTED_RESOURCE_URL, rootUrl);
final String protectedResourceUrl = String.format(PROTECTED_RESOURCE_URL, rootUrl);
OAuthRequest request = new OAuthRequest(Verb.GET, protectedResourceUrl);
Token t =
new Token(token.getToken(), token.getSecret(), token.getRaw());
Token t = new Token(token.getToken(), token.getSecret(), token.getRaw());
service.signRequest(t, request);

Response response = request.send();
if (response.getCode() != HttpServletResponse.SC_OK) {
throw new IOException(String.format("Status %s (%s) for request %s",
response.getCode(), response.getBody(), request.getUrl()));
throw new IOException(
String.format(
"Status %s (%s) for request %s",
response.getCode(), response.getBody(), request.getUrl()));
}

if (log.isDebugEnabled()) {
log.debug("User info response: {}", response.getBody());
}

JsonElement userJson =
OutputFormat.JSON.newGson().fromJson(response.getBody(),
JsonElement.class);
OutputFormat.JSON.newGson().fromJson(response.getBody(), JsonElement.class);
if (!userJson.isJsonObject()) {
throw new IOException(String.format(
"Invalid JSON '%s': not a JSON Object", userJson));
throw new IOException(String.format("Invalid JSON '%s': not a JSON Object", userJson));
}
JsonObject jsonObject = userJson.getAsJsonObject();

JsonElement id = jsonObject.get("id");
if (id == null || id.isJsonNull()) {
throw new IOException(String.format(
"Response doesn't contain %s field", "id"));
throw new IOException(String.format("Response doesn't contain %s field", "id"));
}

JsonElement attrListJson = jsonObject.get("attributes");
if (attrListJson == null || !attrListJson.isJsonArray()) {
throw new IOException(String.format(
"Invalid JSON '%s': not a JSON Array", attrListJson));
throw new IOException(String.format("Invalid JSON '%s': not a JSON Array", attrListJson));
}

String email = null, name = null, login = null;
JsonArray attrJson = attrListJson.getAsJsonArray();
for (JsonElement elem : attrJson) {
if (elem == null || !elem.isJsonObject()) {
throw new IOException(String.format(
"Invalid JSON '%s': not a JSON Object", elem));
throw new IOException(String.format("Invalid JSON '%s': not a JSON Object", elem));
}
JsonObject obj = elem.getAsJsonObject();

String property = getStringElement(obj, "email");
if (property != null)
email = property;
if (property != null) email = property;
property = getStringElement(obj, "name");
if (property != null)
name = property;
if (property != null) name = property;
property = getStringElement(obj, "login");
if (property != null)
login = property;
if (property != null) login = property;
}

return new OAuthUserInfo(CAS_PROVIDER_PREFIX + id.getAsString(),
return new OAuthUserInfo(
CAS_PROVIDER_PREFIX + id.getAsString(),
login,
email,
name,
Expand All @@ -145,8 +133,7 @@ public OAuthUserInfo getUserInfo(OAuthToken token) throws IOException {

private String getStringElement(JsonObject o, String name) {
JsonElement elem = o.get(name);
if (elem == null || elem.isJsonNull())
return null;
if (elem == null || elem.isJsonNull()) return null;

return elem.getAsString();
}
Expand All @@ -155,8 +142,7 @@ private String getStringElement(JsonObject o, String name) {
public OAuthToken getAccessToken(OAuthVerifier rv) {
Verifier vi = new Verifier(rv.getValue());
Token to = service.getAccessToken(null, vi);
return new OAuthToken(to.getToken(),
to.getSecret(), to.getRawResponse());
return new OAuthToken(to.getToken(), to.getSecret(), to.getRawResponse());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ class DisabledOAuthLoginProvider implements OAuthLoginProvider {
}

@Override
public OAuthUserInfo login(String username, String secret)
throws IOException {
public OAuthUserInfo login(String username, String secret) throws IOException {
throw new UnsupportedOperationException(
"git over oauth is not implemented by " + pluginName + " plugin");
}
Expand Down
Loading

0 comments on commit 880c4d2

Please sign in to comment.