diff options
author | Saša Živkov <zivkov@gmail.com> | 2015-05-05 12:03:40 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2015-05-05 12:03:43 +0000 |
commit | 8ca666bdcc0431a4f41e854ebf49a4044ffa474c (patch) | |
tree | fdad1b114b4689bfdfa3e7f660f4b279b436a5b4 | |
parent | fa7880a804d99f3487bd934cdaf5852010fe39f3 (diff) | |
parent | c28da9bb21d1cd3b91c87ea0b2c9d74c97252e16 (diff) |
Merge changes from topic 'hybrid-openid-oauth-authentication-provider' into stable-2.10
* changes:
Hybrid OpenID/OAuth: Support switching identities
Hybrid OpenID/OAuth: Allow to link identity accross protocols
3 files changed, 40 insertions, 29 deletions
diff --git a/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/LoginForm.java b/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/LoginForm.java index 93031fef62..aea816e7c2 100644 --- a/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/LoginForm.java +++ b/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/LoginForm.java @@ -175,9 +175,9 @@ class LoginForm extends HttpServlet { oauthSession.logout(); } if ((isGerritLogin(req) - || oauthSession.isOAuthFinal(req)) - && !oauthSession.isLoggedIn()) { + || oauthSession.isOAuthFinal(req))) { oauthSession.setServiceProvider(oauthProvider); + oauthSession.setLinkMode(link); oauthSession.login(req, res, oauthProvider); } } @@ -303,7 +303,7 @@ class LoginForm extends HttpServlet { oauthServiceProviders.byPlugin(pluginName); for (Map.Entry<String, Provider<OAuthServiceProvider>> e : m.entrySet()) { - addProvider(providers, pluginName, e.getKey(), + addProvider(providers, link, pluginName, e.getKey(), e.getValue().get().getName()); } } @@ -326,13 +326,18 @@ class LoginForm extends HttpServlet { } } - private static void addProvider(Element form, String pluginName, - String id, String serviceName) { + private static void addProvider(Element form, boolean link, + String pluginName, String id, String serviceName) { Element div = form.getOwnerDocument().createElement("div"); div.setAttribute("id", id); Element hyperlink = form.getOwnerDocument().createElement("a"); - hyperlink.setAttribute("href", String.format("?id=%s_%s", + StringBuilder u = new StringBuilder(String.format("?id=%s_%s", pluginName, id)); + if (link) { + u.append("&link"); + } + hyperlink.setAttribute("href", u.toString()); + hyperlink.setTextContent(serviceName + " (" + pluginName + " plugin)"); div.appendChild(hyperlink); diff --git a/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/OAuthSessionOverOpenID.java b/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/OAuthSessionOverOpenID.java index a02f52d5d0..6d129bfd4f 100644 --- a/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/OAuthSessionOverOpenID.java +++ b/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/OAuthSessionOverOpenID.java @@ -27,11 +27,13 @@ import com.google.gerrit.httpd.CanonicalWebUrl; import com.google.gerrit.httpd.LoginUrlToken; import com.google.gerrit.httpd.WebSession; import com.google.gerrit.reviewdb.client.Account; +import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.account.AccountException; import com.google.gerrit.server.account.AccountManager; import com.google.gerrit.server.account.AuthResult; import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; +import com.google.inject.Provider; import com.google.inject.servlet.SessionScoped; import org.apache.commons.codec.binary.Base64; @@ -55,19 +57,23 @@ class OAuthSessionOverOpenID { private static final SecureRandom randomState = newRandomGenerator(); private final String state; private final DynamicItem<WebSession> webSession; + private final Provider<IdentifiedUser> identifiedUser; private final AccountManager accountManager; private final CanonicalWebUrl urlProvider; private OAuthServiceProvider serviceProvider; private OAuthToken token; private OAuthUserInfo user; private String redirectToken; + private boolean linkMode; @Inject OAuthSessionOverOpenID(DynamicItem<WebSession> webSession, + Provider<IdentifiedUser> identifiedUser, AccountManager accountManager, CanonicalWebUrl urlProvider) { this.state = generateRandomState(); this.webSession = webSession; + this.identifiedUser = identifiedUser; this.accountManager = accountManager; this.urlProvider = urlProvider; } @@ -82,10 +88,6 @@ class OAuthSessionOverOpenID { boolean login(HttpServletRequest request, HttpServletResponse response, OAuthServiceProvider oauth) throws IOException { - if (isLoggedIn()) { - return true; - } - log.debug("Login " + this); if (isOAuthFinal(request)) { @@ -96,7 +98,6 @@ class OAuthSessionOverOpenID { log.debug("Login-Retrieve-User " + this); token = oauth.getAccessToken(new OAuthVerifier(request.getParameter("code"))); - user = oauth.getUserInfo(token); if (isLoggedIn()) { @@ -124,6 +125,7 @@ class OAuthSessionOverOpenID { try { String claimedIdentifier = user.getClaimedIdentity(); Account.Id actualId = accountManager.lookup(user.getExternalId()); + // Use case 1: claimed identity was provided during handshake phase if (!Strings.isNullOrEmpty(claimedIdentifier)) { Account.Id claimedId = accountManager.lookup(claimedIdentifier); if (claimedId != null && actualId != null) { @@ -153,6 +155,18 @@ class OAuthSessionOverOpenID { return; } } + } else if (linkMode) { + // Use case 2: link mode activated from the UI + try { + accountManager.link(identifiedUser.get().getAccountId(), areq); + } catch (OrmException e) { + log.error("Cannot link: " + user.getExternalId() + + " to user identity: " + identifiedUser.get().getAccountId()); + rsp.sendError(HttpServletResponse.SC_FORBIDDEN); + return; + } finally { + linkMode = false; + } } areq.setUserName(user.getUserName()); areq.setEmailAddress(user.getEmailAddress()); @@ -213,4 +227,12 @@ class OAuthSessionOverOpenID { public OAuthServiceProvider getServiceProvider() { return serviceProvider; } + + public void setLinkMode(boolean linkMode) { + this.linkMode = linkMode; + } + + public boolean isLinkMode() { + return linkMode; + } } diff --git a/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/OAuthWebFilterOverOpenID.java b/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/OAuthWebFilterOverOpenID.java index 53fc889305..ff02419e92 100644 --- a/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/OAuthWebFilterOverOpenID.java +++ b/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/OAuthWebFilterOverOpenID.java @@ -17,7 +17,6 @@ package com.google.gerrit.httpd.auth.openid; import com.google.common.collect.Iterables; import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.extensions.registration.DynamicMap; -import com.google.gerrit.server.CurrentUser; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; @@ -34,7 +33,6 @@ import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; /** OAuth web filter uses active OAuth session to perform OAuth requests */ @@ -42,16 +40,13 @@ import javax.servlet.http.HttpSession; class OAuthWebFilterOverOpenID implements Filter { static final String GERRIT_LOGIN = "/login"; - private final Provider<CurrentUser> currentUserProvider; private final Provider<OAuthSessionOverOpenID> oauthSessionProvider; private final DynamicMap<OAuthServiceProvider> oauthServiceProviders; private OAuthServiceProvider ssoProvider; @Inject - OAuthWebFilterOverOpenID(Provider<CurrentUser> currentUserProvider, - DynamicMap<OAuthServiceProvider> oauthServiceProviders, + OAuthWebFilterOverOpenID(DynamicMap<OAuthServiceProvider> oauthServiceProviders, Provider<OAuthSessionOverOpenID> oauthSessionProvider) { - this.currentUserProvider = currentUserProvider; this.oauthServiceProviders = oauthServiceProviders; this.oauthSessionProvider = oauthSessionProvider; } @@ -69,15 +64,6 @@ class OAuthWebFilterOverOpenID implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; - HttpSession httpSession = ((HttpServletRequest) request).getSession(false); - if (currentUserProvider.get().isIdentifiedUser()) { - if (httpSession != null) { - httpSession.invalidate(); - } - chain.doFilter(request, response); - return; - } - HttpServletResponse httpResponse = (HttpServletResponse) response; OAuthSessionOverOpenID oauthSession = oauthSessionProvider.get(); @@ -85,9 +71,7 @@ class OAuthWebFilterOverOpenID implements Filter { ? oauthSession.getServiceProvider() : ssoProvider; - if ((isGerritLogin(httpRequest) - || oauthSession.isOAuthFinal(httpRequest)) - && !oauthSession.isLoggedIn()) { + if (isGerritLogin(httpRequest) || oauthSession.isOAuthFinal(httpRequest)) { if (service == null) { throw new IllegalStateException("service is unknown"); } |