use of com.google.gerrit.server.account.AccountException in project gerrit by GerritCodeReview.
the class ConfirmEmail method apply.
@Override
public Response<?> apply(ConfigResource rsrc, Input input) throws AuthException, UnprocessableEntityException, AccountException, OrmException, IOException, ConfigInvalidException {
CurrentUser user = self.get();
if (!user.isIdentifiedUser()) {
throw new AuthException("Authentication required");
}
if (input == null) {
input = new Input();
}
if (input.token == null) {
throw new UnprocessableEntityException("missing token");
}
try {
EmailTokenVerifier.ParsedToken token = emailTokenVerifier.decode(input.token);
Account.Id accId = user.getAccountId();
if (accId.equals(token.getAccountId())) {
accountManager.link(accId, token.toAuthRequest());
return Response.none();
}
throw new UnprocessableEntityException("invalid token");
} catch (EmailTokenVerifier.InvalidTokenException e) {
throw new UnprocessableEntityException("invalid token");
} catch (AccountException e) {
throw new UnprocessableEntityException(e.getMessage());
}
}
use of com.google.gerrit.server.account.AccountException in project gerrit by GerritCodeReview.
the class Helper method queryForGroups.
Set<AccountGroup.UUID> queryForGroups(final DirContext ctx, String username, LdapQuery.Result account) throws NamingException {
final LdapSchema schema = getSchema(ctx);
final Set<String> groupDNs = new HashSet<>();
if (!schema.groupMemberQueryList.isEmpty()) {
final HashMap<String, String> params = new HashMap<>();
if (account == null) {
try {
account = findAccount(schema, ctx, username, false);
} catch (AccountException e) {
return Collections.emptySet();
}
}
for (String name : schema.groupMemberQueryList.get(0).getParameters()) {
params.put(name, account.get(name));
}
params.put(LdapRealm.USERNAME, username);
for (LdapQuery groupMemberQuery : schema.groupMemberQueryList) {
for (LdapQuery.Result r : groupMemberQuery.query(ctx, params, groupSearchLatencyTimer)) {
try (Timer0.Context ignored = groupExpansionLatencyTimer.start()) {
recursivelyExpandGroups(groupDNs, schema, ctx, r.getDN());
}
}
}
}
if (schema.accountMemberField != null) {
if (account == null || account.getAll(schema.accountMemberField) == null) {
try {
account = findAccount(schema, ctx, username, true);
} catch (AccountException e) {
return Collections.emptySet();
}
}
final Attribute groupAtt = account.getAll(schema.accountMemberField);
if (groupAtt != null) {
final NamingEnumeration<?> groups = groupAtt.getAll();
try {
while (groups.hasMore()) {
final String nextDN = (String) groups.next();
recursivelyExpandGroups(groupDNs, schema, ctx, nextDN);
}
} catch (PartialResultException e) {
// Ignored
}
}
}
final Set<AccountGroup.UUID> actual = new HashSet<>();
for (String dn : groupDNs) {
actual.add(AccountGroup.uuid(LDAP_UUID + dn));
}
if (actual.isEmpty()) {
return Collections.emptySet();
}
return ImmutableSet.copyOf(actual);
}
use of com.google.gerrit.server.account.AccountException in project gerrit by GerritCodeReview.
the class OAuthRealm method authenticate.
/**
* Authenticates with the {@link OAuthLoginProvider} specified in the authentication request.
*
* <p>{@link AccountManager} calls this method without password if authenticity of the user has
* already been established. In that case we can skip the authentication request to the {@code
* OAuthLoginService}.
*
* @param who the authentication request.
* @return the authentication request with resolved email address and display name in case the
* authenticity of the user could be established; otherwise {@code who} is returned unchanged.
* @throws AccountException if the authentication request with the OAuth2 server failed or no
* {@code OAuthLoginProvider} was available to handle the request.
*/
@Override
public AuthRequest authenticate(AuthRequest who) throws AccountException {
if (Strings.isNullOrEmpty(who.getPassword())) {
return who;
}
if (Strings.isNullOrEmpty(who.getAuthPlugin()) || Strings.isNullOrEmpty(who.getAuthProvider())) {
throw new AccountException("Cannot authenticate");
}
OAuthLoginProvider loginProvider = loginProviders.get(who.getAuthPlugin(), who.getAuthProvider());
if (loginProvider == null) {
throw new AccountException("Cannot authenticate");
}
OAuthUserInfo userInfo;
try {
userInfo = loginProvider.login(who.getUserName().orElse(null), who.getPassword());
} catch (IOException e) {
throw new AccountException("Cannot authenticate", e);
}
if (userInfo == null) {
throw new AccountException("Cannot authenticate");
}
if (!Strings.isNullOrEmpty(userInfo.getEmailAddress()) && (!who.getUserName().isPresent() || !allowsEdit(AccountFieldName.REGISTER_NEW_EMAIL))) {
who.setEmailAddress(userInfo.getEmailAddress());
}
if (!Strings.isNullOrEmpty(userInfo.getDisplayName()) && (Strings.isNullOrEmpty(who.getDisplayName()) || !allowsEdit(AccountFieldName.FULL_NAME))) {
who.setDisplayName(userInfo.getDisplayName());
}
return who;
}
use of com.google.gerrit.server.account.AccountException in project gerrit by GerritCodeReview.
the class LdapAuthBackend method authenticate.
@Override
public AuthUser authenticate(AuthRequest req) throws MissingCredentialsException, InvalidCredentialsException, UnknownUserException, UserNotAllowedException, AuthException {
if (!req.getUsername().isPresent() || !req.getPassword().isPresent()) {
throw new MissingCredentialsException();
}
String username = lowerCaseUsername ? req.getUsername().map(u -> u.toLowerCase(Locale.US)).get() : req.getUsername().get();
try {
final DirContext ctx;
if (authConfig.getAuthType() == AuthType.LDAP_BIND) {
ctx = helper.authenticate(username, req.getPassword().get());
} else {
ctx = helper.open();
}
try {
final Helper.LdapSchema schema = helper.getSchema(ctx);
final LdapQuery.Result m = helper.findAccount(schema, ctx, username, false);
if (authConfig.getAuthType() == AuthType.LDAP) {
// We found the user account, but we need to verify
// the password matches it before we can continue.
//
helper.close(helper.authenticate(m.getDN(), req.getPassword().get()));
}
return new AuthUser(AuthUser.UUID.create(username), username);
} finally {
helper.close(ctx);
}
} catch (AccountException e) {
logger.atSevere().withCause(e).log("Cannot query LDAP to authenticate user");
throw new InvalidCredentialsException("Cannot query LDAP for account", e);
} catch (IOException | NamingException e) {
logger.atSevere().withCause(e).log("Cannot query LDAP to authenticate user");
throw new AuthException("Cannot query LDAP for account", e);
} catch (LoginException e) {
logger.atSevere().withCause(e).log("Cannot authenticate server via JAAS");
throw new AuthException("Cannot query LDAP for account", e);
}
}
use of com.google.gerrit.server.account.AccountException in project gerrit by GerritCodeReview.
the class OpenIdServiceImpl method doAuth.
/**
* Called by {@link OpenIdLoginServlet} doGet, doPost
*/
void doAuth(HttpServletRequest req, HttpServletResponse rsp) throws Exception {
if (OMODE_CANCEL.equals(req.getParameter(OPENID_MODE))) {
cancel(req, rsp);
return;
}
// Process the authentication response.
//
final SignInMode mode = signInMode(req);
final String openidIdentifier = req.getParameter("openid.identity");
final String claimedIdentifier = req.getParameter(P_CLAIMED);
final String returnToken = req.getParameter(P_TOKEN);
final boolean remember = "1".equals(req.getParameter(P_REMEMBER));
final String rediscoverIdentifier = claimedIdentifier != null ? claimedIdentifier : openidIdentifier;
final State state;
if (!isAllowedOpenID(rediscoverIdentifier) || !isAllowedOpenID(openidIdentifier) || (claimedIdentifier != null && !isAllowedOpenID(claimedIdentifier))) {
cancelWithError(req, rsp, "Provider not allowed");
return;
}
state = init(req, rediscoverIdentifier, mode, remember, returnToken);
if (state == null) {
// Re-discovery must have failed, we can't run a login.
//
cancel(req, rsp);
return;
}
final String returnTo = req.getParameter("openid.return_to");
if (returnTo != null && returnTo.contains("openid.rpnonce=")) {
// Some providers (claimid.com) seem to embed these request
// parameters into our return_to URL, and then give us them
// in the return_to request parameter. But not all.
//
state.retTo.put("openid.rpnonce", req.getParameter("openid.rpnonce"));
state.retTo.put("openid.rpsig", req.getParameter("openid.rpsig"));
}
final VerificationResult result = manager.verify(state.retTo.toString(), new ParameterList(req.getParameterMap()), state.discovered);
if (result.getVerifiedId() == null) /* authentication failure */
{
if ("Nonce verification failed.".equals(result.getStatusMsg())) {
// We might be suffering from clock skew on this system.
//
logger.atSevere().log("OpenID failure: %s Likely caused by clock skew on this server," + " install/configure NTP.", result.getStatusMsg());
cancelWithError(req, rsp, result.getStatusMsg());
} else if (result.getStatusMsg() != null) {
// Authentication failed.
//
logger.atSevere().log("OpenID failure: %s", result.getStatusMsg());
cancelWithError(req, rsp, result.getStatusMsg());
} else {
// Assume authentication was canceled.
//
cancel(req, rsp);
}
return;
}
final Message authRsp = result.getAuthResponse();
SRegResponse sregRsp = null;
FetchResponse fetchRsp = null;
if (0 <= papeMaxAuthAge) {
PapeResponse ext;
boolean unsupported = false;
try {
ext = (PapeResponse) authRsp.getExtension(PapeMessage.OPENID_NS_PAPE);
} catch (MessageException err) {
// Far too many providers are unable to provide PAPE extensions
// right now. Instead of blocking all of them log the error and
// let the authentication complete anyway.
//
logger.atSevere().withCause(err).log("Invalid PAPE response from %s", openidIdentifier);
unsupported = true;
ext = null;
}
if (!unsupported && ext == null) {
logger.atSevere().log("No PAPE extension response from %s", openidIdentifier);
cancelWithError(req, rsp, "OpenID provider does not support PAPE.");
return;
}
}
if (authRsp.hasExtension(SRegMessage.OPENID_NS_SREG)) {
final MessageExtension ext = authRsp.getExtension(SRegMessage.OPENID_NS_SREG);
if (ext instanceof SRegResponse) {
sregRsp = (SRegResponse) ext;
}
}
if (authRsp.hasExtension(AxMessage.OPENID_NS_AX)) {
final MessageExtension ext = authRsp.getExtension(AxMessage.OPENID_NS_AX);
if (ext instanceof FetchResponse) {
fetchRsp = (FetchResponse) ext;
}
}
final com.google.gerrit.server.account.AuthRequest areq = authRequestFactory.create(externalIdKeyFactory.parse(openidIdentifier));
if (sregRsp != null) {
areq.setDisplayName(sregRsp.getAttributeValue("fullname"));
areq.setEmailAddress(sregRsp.getAttributeValue("email"));
} else if (fetchRsp != null) {
final String firstName = fetchRsp.getAttributeValue("FirstName");
final String lastName = fetchRsp.getAttributeValue("LastName");
final StringBuilder n = new StringBuilder();
if (firstName != null && firstName.length() > 0) {
n.append(firstName);
}
if (lastName != null && lastName.length() > 0) {
if (n.length() > 0) {
n.append(' ');
}
n.append(lastName);
}
areq.setDisplayName(n.length() > 0 ? n.toString() : null);
areq.setEmailAddress(fetchRsp.getAttributeValue("Email"));
}
if (openIdDomains != null && !openIdDomains.isEmpty()) {
// 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) {
logger.atSevere().log("Domain disallowed: %s", 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
// link between the two, so set one up if not present.
//
Optional<Account.Id> claimedId = accountManager.lookup(claimedIdentifier);
Optional<Account.Id> actualId = accountManager.lookup(areq.getExternalIdKey().get());
if (claimedId.isPresent() && actualId.isPresent()) {
if (claimedId.get().equals(actualId.get())) {
// Both link to the same account, that's what we expected.
} else {
// This is (for now) a fatal error. There are two records
// for what might be the same user.
//
logger.atSevere().log("OpenID accounts disagree over user identity:\n" + " Claimed ID: %s is %s\n" + " Delgate ID: %s is %s", claimedId.get(), claimedIdentifier, actualId.get(), areq.getExternalIdKey());
cancelWithError(req, rsp, "Contact site administrator");
return;
}
} else if (!claimedId.isPresent() && actualId.isPresent()) {
// Older account, the actual was already created but the claimed
// was missing due to a bug in Gerrit. Link the claimed.
//
final com.google.gerrit.server.account.AuthRequest linkReq = authRequestFactory.create(externalIdKeyFactory.parse(claimedIdentifier));
linkReq.setDisplayName(areq.getDisplayName());
linkReq.setEmailAddress(areq.getEmailAddress());
accountManager.link(actualId.get(), linkReq);
} else if (claimedId.isPresent() && !actualId.isPresent()) {
// Claimed account already exists, but it smells like the user has
// changed their delegate to point to a different provider. Link
// the new provider.
//
accountManager.link(claimedId.get(), areq);
} else {
// Both are null, we are going to create a new account below.
}
}
try {
final com.google.gerrit.server.account.AuthResult arsp;
switch(mode) {
case REGISTER:
case SIGN_IN:
arsp = accountManager.authenticate(areq);
final Cookie lastId = new Cookie(OpenIdUrls.LASTID_COOKIE, "");
lastId.setPath(req.getContextPath() + "/login/");
if (remember) {
lastId.setValue(rediscoverIdentifier);
lastId.setMaxAge(LASTID_AGE);
} else {
lastId.setMaxAge(0);
}
rsp.addCookie(lastId);
webSession.get().login(arsp, remember);
if (arsp.isNew() && claimedIdentifier != null) {
final com.google.gerrit.server.account.AuthRequest linkReq = authRequestFactory.create(externalIdKeyFactory.parse(claimedIdentifier));
linkReq.setDisplayName(areq.getDisplayName());
linkReq.setEmailAddress(areq.getEmailAddress());
accountManager.link(arsp.getAccountId(), linkReq);
}
callback(arsp.isNew(), req, rsp);
break;
case LINK_IDENTIY:
{
arsp = accountManager.link(identifiedUser.get().getAccountId(), areq);
webSession.get().login(arsp, remember);
callback(false, req, rsp);
break;
}
}
} catch (AccountException e) {
logger.atSevere().withCause(e).log("OpenID authentication failure");
cancelWithError(req, rsp, "Contact site administrator");
}
}
Aggregations