diff options
Diffstat (limited to 'gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/OpenIdServiceImpl.java')
-rw-r--r-- | gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/OpenIdServiceImpl.java | 93 |
1 files changed, 53 insertions, 40 deletions
diff --git a/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/OpenIdServiceImpl.java b/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/OpenIdServiceImpl.java index 09a5d1043b..5d74166e52 100644 --- a/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/OpenIdServiceImpl.java +++ b/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/OpenIdServiceImpl.java @@ -15,23 +15,18 @@ package com.google.gerrit.httpd.auth.openid; import com.google.gerrit.common.PageLinks; -import com.google.gerrit.common.auth.SignInMode; -import com.google.gerrit.common.auth.openid.DiscoveryResult; -import com.google.gerrit.common.auth.openid.OpenIdProviderPattern; -import com.google.gerrit.common.auth.openid.OpenIdService; import com.google.gerrit.common.auth.openid.OpenIdUrls; +import com.google.gerrit.httpd.CanonicalWebUrl; import com.google.gerrit.httpd.WebSession; import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.UrlEncoded; import com.google.gerrit.server.account.AccountException; import com.google.gerrit.server.account.AccountManager; -import com.google.gerrit.server.account.AuthMethod; +import com.google.gerrit.server.auth.openid.OpenIdProviderPattern; import com.google.gerrit.server.config.AuthConfig; -import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.ConfigUtil; import com.google.gerrit.server.config.GerritServerConfig; -import com.google.gwtjsonrpc.common.AsyncCallback; import com.google.gwtorm.client.KeyUtil; import com.google.inject.Inject; import com.google.inject.Provider; @@ -68,13 +63,12 @@ import java.net.URL; import java.util.List; import java.util.concurrent.TimeUnit; -import javax.annotation.Nullable; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Singleton -class OpenIdServiceImpl implements OpenIdService { +class OpenIdServiceImpl { private static final Logger log = LoggerFactory.getLogger(OpenIdServiceImpl.class); @@ -98,10 +92,11 @@ class OpenIdServiceImpl implements OpenIdService { private final Provider<WebSession> webSession; private final Provider<IdentifiedUser> identifiedUser; - private final Provider<String> urlProvider; + private final CanonicalWebUrl urlProvider; private final AccountManager accountManager; private final ConsumerManager manager; private final List<OpenIdProviderPattern> allowedOpenIDs; + private final List<String> openIdDomains; /** Maximum age, in seconds, before forcing re-authentication of account. */ private final int papeMaxAuthAge; @@ -109,7 +104,7 @@ class OpenIdServiceImpl implements OpenIdService { @Inject OpenIdServiceImpl(final Provider<WebSession> cf, final Provider<IdentifiedUser> iu, - @CanonicalWebUrl @Nullable final Provider<String> up, + CanonicalWebUrl up, @GerritServerConfig final Config config, final AuthConfig ac, final AccountManager am) throws ConsumerException, MalformedURLException { @@ -143,24 +138,18 @@ class OpenIdServiceImpl implements OpenIdService { accountManager = am; manager = new ConsumerManager(); allowedOpenIDs = ac.getAllowedOpenIDs(); + openIdDomains = ac.getOpenIdDomains(); papeMaxAuthAge = (int) ConfigUtil.getTimeUnit(config, // "auth", null, "maxOpenIdSessionAge", -1, TimeUnit.SECONDS); } @SuppressWarnings("unchecked") - public void discover(final String openidIdentifier, final SignInMode mode, - final boolean remember, final String returnToken, - final AsyncCallback<DiscoveryResult> cb) { - if (!isAllowedOpenID(openidIdentifier)) { - cb.onSuccess(new DiscoveryResult(DiscoveryResult.Status.NOT_ALLOWED)); - return; - } - + DiscoveryResult discover(HttpServletRequest req, String openidIdentifier, + final SignInMode mode, final boolean remember, final String returnToken) { final State state; - state = init(openidIdentifier, mode, remember, returnToken); + state = init(req, openidIdentifier, mode, remember, returnToken); if (state == null) { - cb.onSuccess(new DiscoveryResult(DiscoveryResult.Status.NO_PROVIDER)); - return; + return new DiscoveryResult(DiscoveryResult.Status.NO_PROVIDER); } final AuthRequest aReq; @@ -188,16 +177,15 @@ class OpenIdServiceImpl implements OpenIdService { } } catch (MessageException e) { log.error("Cannot create OpenID redirect for " + openidIdentifier, e); - cb.onSuccess(new DiscoveryResult(DiscoveryResult.Status.ERROR)); - return; + return new DiscoveryResult(DiscoveryResult.Status.ERROR); } catch (ConsumerException e) { log.error("Cannot create OpenID redirect for " + openidIdentifier, e); - cb.onSuccess(new DiscoveryResult(DiscoveryResult.Status.ERROR)); - return; + return new DiscoveryResult(DiscoveryResult.Status.ERROR); } - cb.onSuccess(new DiscoveryResult(aReq.getDestinationUrl(false), // - aReq.getParameterMap())); + return new DiscoveryResult( + aReq.getDestinationUrl(false), + aReq.getParameterMap()); } private boolean requestRegistration(final AuthRequest aReq) { @@ -208,7 +196,6 @@ class OpenIdServiceImpl implements OpenIdService { // registration information, in case the identity is new to us. // return true; - } // We might already have this account on file. Look for it. @@ -221,7 +208,7 @@ class OpenIdServiceImpl implements OpenIdService { } } - /** Called by {@link OpenIdLoginServlet} doGet, doPost */ + /** Called by {@link OpenIdLoginForm} doGet, doPost */ void doAuth(final HttpServletRequest req, final HttpServletResponse rsp) throws Exception { if (OMODE_CANCEL.equals(req.getParameter(OPENID_MODE))) { @@ -247,7 +234,7 @@ class OpenIdServiceImpl implements OpenIdService { return; } - state = init(rediscoverIdentifier, mode, remember, returnToken); + state = init(req, rediscoverIdentifier, mode, remember, returnToken); if (state == null) { // Re-discovery must have failed, we can't run a login. // @@ -356,6 +343,32 @@ class OpenIdServiceImpl implements OpenIdService { areq.setEmailAddress(fetchRsp.getAttributeValue("Email")); } + if (openIdDomains != null && openIdDomains.size() > 0) { + // Administrator limited email domains, which can be used for OpenID. + // Login process will only work if the passed email matches one + // of these domains. + // + final String email = areq.getEmailAddress(); + int emailAtIndex = email.lastIndexOf("@"); + if (emailAtIndex >= 0 && emailAtIndex < email.length() - 1) { + final String emailDomain = email.substring(emailAtIndex); + + boolean match = false; + for (String domain : openIdDomains) { + if (emailDomain.equalsIgnoreCase(domain)) { + match = true; + break; + } + } + + if (!match) { + log.error("Domain disallowed: " + emailDomain); + cancelWithError(req, rsp, "Domain disallowed"); + return; + } + } + } + if (claimedIdentifier != null) { // The user used a claimed identity which has delegated to the verified // identity we have in our AuthRequest above. We still should have a @@ -409,7 +422,7 @@ class OpenIdServiceImpl implements OpenIdService { arsp = accountManager.authenticate(areq); final Cookie lastId = new Cookie(OpenIdUrls.LASTID_COOKIE, ""); - lastId.setPath(req.getContextPath() + "/"); + lastId.setPath(req.getContextPath() + "/login/"); if (remember) { lastId.setValue(rediscoverIdentifier); lastId.setMaxAge(LASTID_AGE); @@ -417,7 +430,7 @@ class OpenIdServiceImpl implements OpenIdService { lastId.setMaxAge(0); } rsp.addCookie(lastId); - webSession.get().login(arsp, AuthMethod.COOKIE, remember); + webSession.get().login(arsp, remember); if (arsp.isNew() && claimedIdentifier != null) { final com.google.gerrit.server.account.AuthRequest linkReq = new com.google.gerrit.server.account.AuthRequest( @@ -431,7 +444,7 @@ class OpenIdServiceImpl implements OpenIdService { case LINK_IDENTIY: { arsp = accountManager.link(identifiedUser.get().getAccountId(), areq); - webSession.get().login(arsp, AuthMethod.COOKIE, remember); + webSession.get().login(arsp, remember); callback(false, req, rsp); break; } @@ -468,7 +481,7 @@ class OpenIdServiceImpl implements OpenIdService { } final StringBuilder rdr = new StringBuilder(); - rdr.append(urlProvider.get()); + rdr.append(urlProvider.get(req)); rdr.append('#'); if (isNew && !token.startsWith(PageLinks.REGISTER + "/")) { rdr.append(PageLinks.REGISTER); @@ -493,7 +506,7 @@ class OpenIdServiceImpl implements OpenIdService { webSession.get().logout(); } final StringBuilder rdr = new StringBuilder(); - rdr.append(urlProvider.get()); + rdr.append(urlProvider.get(req)); rdr.append('#'); rdr.append("SignInFailure"); rdr.append(','); @@ -503,8 +516,8 @@ class OpenIdServiceImpl implements OpenIdService { rsp.sendRedirect(rdr.toString()); } - private State init(final String openidIdentifier, final SignInMode mode, - final boolean remember, final String returnToken) { + private State init(HttpServletRequest req, final String openidIdentifier, + final SignInMode mode, final boolean remember, final String returnToken) { final List<?> list; try { list = manager.discover(openidIdentifier); @@ -516,7 +529,7 @@ class OpenIdServiceImpl implements OpenIdService { return null; } - final String contextUrl = urlProvider.get(); + final String contextUrl = urlProvider.get(req); final DiscoveryInformation discovered = manager.associate(list); final UrlEncoded retTo = new UrlEncoded(contextUrl + RETURN_URL); retTo.put(P_MODE, mode.name()); @@ -532,7 +545,7 @@ class OpenIdServiceImpl implements OpenIdService { return new State(discovered, retTo, contextUrl); } - private boolean isAllowedOpenID(final String id) { + boolean isAllowedOpenID(final String id) { for (final OpenIdProviderPattern pattern : allowedOpenIDs) { if (pattern.matches(id)) { return true; |