Skip to content

Commit

Permalink
Refactor zone id handling at dao layer
Browse files Browse the repository at this point in the history
  • Loading branch information
fhanik committed Jan 25, 2016
1 parent 41cb379 commit e319144
Show file tree
Hide file tree
Showing 21 changed files with 413 additions and 194 deletions.
@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Cloud Foundry * Cloud Foundry
* Copyright (c) [2009-2014] Pivotal Software, Inc. All Rights Reserved. * Copyright (c) [2009-2014] Pivotal Software, Inc. All Rights Reserved.
* *
* This product is licensed to you under the Apache License, Version 2.0 (the "License"). * This product is licensed to you under the Apache License, Version 2.0 (the "License").
Expand All @@ -12,6 +12,7 @@
*******************************************************************************/ *******************************************************************************/
package org.cloudfoundry.identity.uaa.account; package org.cloudfoundry.identity.uaa.account;


import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.cloudfoundry.identity.uaa.authentication.UaaPrincipal; import org.cloudfoundry.identity.uaa.authentication.UaaPrincipal;
Expand All @@ -24,12 +25,15 @@
import org.cloudfoundry.identity.uaa.scim.ScimUser; import org.cloudfoundry.identity.uaa.scim.ScimUser;
import org.cloudfoundry.identity.uaa.scim.exception.InvalidPasswordException; import org.cloudfoundry.identity.uaa.scim.exception.InvalidPasswordException;
import org.cloudfoundry.identity.uaa.user.UaaAuthority; import org.cloudfoundry.identity.uaa.user.UaaAuthority;
import org.cloudfoundry.identity.uaa.user.UaaUserDatabase;
import org.cloudfoundry.identity.uaa.util.JsonUtils;
import org.cloudfoundry.identity.uaa.util.UaaUrlUtils; import org.cloudfoundry.identity.uaa.util.UaaUrlUtils;
import org.cloudfoundry.identity.uaa.zone.IdentityZone; import org.cloudfoundry.identity.uaa.zone.IdentityZone;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder; import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.savedrequest.SavedRequest; import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
Expand All @@ -44,8 +48,11 @@
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.Map;
import java.util.regex.Pattern; import java.util.regex.Pattern;


import static org.springframework.util.StringUtils.hasText;

@Controller @Controller
public class ResetPasswordController { public class ResetPasswordController {
protected final Log logger = LogFactory.getLog(getClass()); protected final Log logger = LogFactory.getLog(getClass());
Expand All @@ -57,20 +64,23 @@ public class ResetPasswordController {
private final String brand; private final String brand;
private final Pattern emailPattern; private final Pattern emailPattern;
private final ExpiringCodeStore codeStore; private final ExpiringCodeStore codeStore;
private final UaaUserDatabase userDatabase;


public ResetPasswordController(ResetPasswordService resetPasswordService, public ResetPasswordController(ResetPasswordService resetPasswordService,
MessageService messageService, MessageService messageService,
TemplateEngine templateEngine, TemplateEngine templateEngine,
UaaUrlUtils uaaUrlUtils, UaaUrlUtils uaaUrlUtils,
String brand, String brand,
ExpiringCodeStore codeStore) { ExpiringCodeStore codeStore,
UaaUserDatabase userDatabase) {
this.resetPasswordService = resetPasswordService; this.resetPasswordService = resetPasswordService;
this.messageService = messageService; this.messageService = messageService;
this.templateEngine = templateEngine; this.templateEngine = templateEngine;
this.uaaUrlUtils = uaaUrlUtils; this.uaaUrlUtils = uaaUrlUtils;
this.brand = brand; this.brand = brand;
emailPattern = Pattern.compile("^\\S+@\\S+\\.\\S+$"); emailPattern = Pattern.compile("^\\S+@\\S+\\.\\S+$");
this.codeStore = codeStore; this.codeStore = codeStore;
this.userDatabase = userDatabase;
} }


@RequestMapping(value = "/forgot_password", method = RequestMethod.GET) @RequestMapping(value = "/forgot_password", method = RequestMethod.GET)
Expand Down Expand Up @@ -162,7 +172,7 @@ public String resetPasswordPage(Model model,
@RequestParam("code") String code, @RequestParam("code") String code,
@RequestParam("email") String email) { @RequestParam("email") String email) {


ExpiringCode expiringCode = codeStore.retrieveCode(code); ExpiringCode expiringCode = validateUserAndClient(codeStore.retrieveCode(code));
if (expiringCode==null) { if (expiringCode==null) {
return handleUnprocessableEntity(model, response, "message_code", "bad_code"); return handleUnprocessableEntity(model, response, "message_code", "bad_code");
} else { } else {
Expand All @@ -173,6 +183,30 @@ public String resetPasswordPage(Model model,
} }
} }


public ExpiringCode validateUserAndClient(ExpiringCode code) {
if (code==null) {
logger.debug("reset_password ExpiringCode object is null. Aborting.");
return null;
}
if (!hasText(code.getData())) {
logger.debug("reset_password ExpiringCode["+code.getCode()+"] data string is null or empty. Aborting.");
return null;
}
Map<String,String> data = JsonUtils.readValue(code.getData(), new TypeReference<Map<String,String>>() {});
if (!hasText(data.get("user_id"))) {
logger.debug("reset_password ExpiringCode["+code.getCode()+"] user_id string is null or empty. Aborting.");
return null;
}
String userId = data.get("user_id");
try {
userDatabase.retrieveUserById(userId);
} catch (UsernameNotFoundException e) {
logger.debug("reset_password ExpiringCode["+code.getCode()+"] user_id is invalid. Aborting.");
return null;
}
return code;
}

@RequestMapping(value = "/reset_password.do", method = RequestMethod.POST) @RequestMapping(value = "/reset_password.do", method = RequestMethod.POST)
public String resetPassword(Model model, public String resetPassword(Model model,
@RequestParam("code") String code, @RequestParam("code") String code,
Expand Down
@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Cloud Foundry * Cloud Foundry
* Copyright (c) [2009-2014] Pivotal Software, Inc. All Rights Reserved. * Copyright (c) [2009-2014] Pivotal Software, Inc. All Rights Reserved.
* *
* This product is licensed to you under the Apache License, Version 2.0 (the "License"). * This product is licensed to you under the Apache License, Version 2.0 (the "License").
Expand All @@ -17,43 +17,58 @@
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.cloudfoundry.identity.uaa.authentication.AuthzAuthenticationRequest; import org.cloudfoundry.identity.uaa.authentication.AuthzAuthenticationRequest;
import org.cloudfoundry.identity.uaa.authentication.InvalidCodeException;
import org.cloudfoundry.identity.uaa.authentication.UaaAuthentication; import org.cloudfoundry.identity.uaa.authentication.UaaAuthentication;
import org.cloudfoundry.identity.uaa.authentication.UaaAuthenticationDetails; import org.cloudfoundry.identity.uaa.authentication.UaaAuthenticationDetails;
import org.cloudfoundry.identity.uaa.authentication.UaaPrincipal; import org.cloudfoundry.identity.uaa.authentication.UaaPrincipal;
import org.cloudfoundry.identity.uaa.codestore.ExpiringCode; import org.cloudfoundry.identity.uaa.codestore.ExpiringCode;
import org.cloudfoundry.identity.uaa.codestore.ExpiringCodeStore; import org.cloudfoundry.identity.uaa.codestore.ExpiringCodeStore;
import org.cloudfoundry.identity.uaa.codestore.ExpiringCodeType; import org.cloudfoundry.identity.uaa.codestore.ExpiringCodeType;
import org.cloudfoundry.identity.uaa.constants.OriginKeys;
import org.cloudfoundry.identity.uaa.authentication.InvalidCodeException;
import org.cloudfoundry.identity.uaa.user.UaaAuthority; import org.cloudfoundry.identity.uaa.user.UaaAuthority;
import org.cloudfoundry.identity.uaa.user.UaaUser;
import org.cloudfoundry.identity.uaa.user.UaaUserDatabase;
import org.cloudfoundry.identity.uaa.util.JsonUtils; import org.cloudfoundry.identity.uaa.util.JsonUtils;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.oauth2.common.util.OAuth2Utils; import org.springframework.security.oauth2.common.util.OAuth2Utils;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.NoSuchClientException;


import java.util.Map; import java.util.Map;


/** /**
* @author Dave Syer * @author Dave Syer
* *
*/ */
public class AutologinAuthenticationManager implements AuthenticationManager { public class AutologinAuthenticationManager implements AuthenticationManager {


private Log logger = LogFactory.getLog(getClass()); private Log logger = LogFactory.getLog(getClass());


private ExpiringCodeStore codeStore; private ExpiringCodeStore codeStore;
private ClientDetailsService clientDetailsService;
private UaaUserDatabase userDatabase;


public void setExpiringCodeStore(ExpiringCodeStore expiringCodeStore) { public void setExpiringCodeStore(ExpiringCodeStore expiringCodeStore) {
this.codeStore= expiringCodeStore; this.codeStore= expiringCodeStore;
} }


public void setClientDetailsService(ClientDetailsService clientDetailsService) {
this.clientDetailsService = clientDetailsService;
}

public void setUserDatabase(UaaUserDatabase userDatabase) {
this.userDatabase = userDatabase;
}

public ExpiringCode doRetrieveCode(String code) { public ExpiringCode doRetrieveCode(String code) {
return codeStore.retrieveCode(code); return codeStore.retrieveCode(code);
} }




@Override @Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException { public Authentication authenticate(Authentication authentication) throws AuthenticationException {


Expand Down Expand Up @@ -81,25 +96,33 @@ public Authentication authenticate(Authentication authentication) throws Authent
throw new BadCredentialsException("JsonConversion error", x); throw new BadCredentialsException("JsonConversion error", x);
} }


String origin; String userId = codeData.get("user_id");
String userId; String clientId = codeData.get(OAuth2Utils.CLIENT_ID);
String username;
String clientId;
username = codeData.get("username");
origin = codeData.get(OriginKeys.ORIGIN);
userId = codeData.get("user_id");
clientId = codeData.get(OAuth2Utils.CLIENT_ID);


if (clientId == null) { if (clientId == null) {
throw new BadCredentialsException("Cannot redeem provided code for user, client id missing"); throw new BadCredentialsException("Cannot redeem provided code for user, client id missing");
} }


try {
clientDetailsService.loadClientByClientId(clientId);
} catch (NoSuchClientException x) {
throw new BadCredentialsException("Cannot redeem provided code for user, client is missing");
}

UaaUser user = null;

try {
user = userDatabase.retrieveUserById(userId);
} catch (UsernameNotFoundException e) {
throw new BadCredentialsException("Cannot redeem provided code for user, user is missing");
}

UaaAuthenticationDetails details = (UaaAuthenticationDetails) authentication.getDetails(); UaaAuthenticationDetails details = (UaaAuthenticationDetails) authentication.getDetails();
if (!clientId.equals(details.getClientId())) { if (!clientId.equals(details.getClientId())) {
throw new BadCredentialsException("Cannot redeem provided code for user, client mismatch"); throw new BadCredentialsException("Cannot redeem provided code for user, client mismatch");
} }


UaaPrincipal principal = new UaaPrincipal(userId,username,null,origin,null, IdentityZoneHolder.get().getId()); UaaPrincipal principal = new UaaPrincipal(user);


return new UaaAuthentication( return new UaaAuthentication(
principal, principal,
Expand Down
Expand Up @@ -12,11 +12,6 @@
*******************************************************************************/ *******************************************************************************/
package org.cloudfoundry.identity.uaa.client; package org.cloudfoundry.identity.uaa.client;


import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.cloudfoundry.identity.uaa.resources.QueryableResourceManager; import org.cloudfoundry.identity.uaa.resources.QueryableResourceManager;
Expand All @@ -26,11 +21,16 @@
import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder; import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.RowMapper;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.security.oauth2.provider.ClientDetails; import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService; import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;


import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

public class JdbcQueryableClientDetailsService extends AbstractQueryable<ClientDetails> implements public class JdbcQueryableClientDetailsService extends AbstractQueryable<ClientDetails> implements
QueryableResourceManager<ClientDetails> { QueryableResourceManager<ClientDetails> {


Expand Down Expand Up @@ -63,11 +63,13 @@ protected String getTableName() {


@Override @Override
public List<ClientDetails> query(String filter, String sortBy, boolean ascending) { public List<ClientDetails> query(String filter, String sortBy, boolean ascending) {
if (StringUtils.hasText(filter)) { //validate syntax
filter += " and"; getQueryConverter().convert(filter, sortBy, ascending);
if (StringUtils.hasText(filter)) {
filter = "(" + filter + ") and ";
} }
filter += " identity_zone_id eq \""+IdentityZoneHolder.get().getId()+"\""; filter += " identity_zone_id eq \""+IdentityZoneHolder.get().getId()+"\"";
return super.query(filter, sortBy, ascending); return super.query(filter, sortBy, ascending);
} }


@Override @Override
Expand Down
Expand Up @@ -18,6 +18,7 @@
import org.cloudfoundry.identity.uaa.audit.event.SystemDeletable; import org.cloudfoundry.identity.uaa.audit.event.SystemDeletable;
import org.cloudfoundry.identity.uaa.util.JsonUtils; import org.cloudfoundry.identity.uaa.util.JsonUtils;
import org.cloudfoundry.identity.uaa.util.ObjectUtils; import org.cloudfoundry.identity.uaa.util.ObjectUtils;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder;
import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException; import org.springframework.dao.DuplicateKeyException;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
Expand Down Expand Up @@ -48,13 +49,13 @@ public class JdbcIdentityProviderProvisioning implements IdentityProviderProvisi


public static final String ID_PROVIDER_UPDATE_FIELDS = "version,lastmodified,name,type,config,active".replace(",","=?,")+"=?"; public static final String ID_PROVIDER_UPDATE_FIELDS = "version,lastmodified,name,type,config,active".replace(",","=?,")+"=?";


public static final String UPDATE_IDENTITY_PROVIDER_SQL = "update identity_provider set " + ID_PROVIDER_UPDATE_FIELDS + " where id=?"; public static final String UPDATE_IDENTITY_PROVIDER_SQL = "update identity_provider set " + ID_PROVIDER_UPDATE_FIELDS + " where id=? and identity_zone_id=?";


public static final String DELETE_IDENTITY_PROVIDER_BY_ORIGIN_SQL = "delete from identity_provider where identity_zone_id=? and origin_key = ?"; public static final String DELETE_IDENTITY_PROVIDER_BY_ORIGIN_SQL = "delete from identity_provider where identity_zone_id=? and origin_key = ?";


public static final String DELETE_IDENTITY_PROVIDER_BY_ZONE_SQL = "delete from identity_provider where identity_zone_id=?"; public static final String DELETE_IDENTITY_PROVIDER_BY_ZONE_SQL = "delete from identity_provider where identity_zone_id=?";


public static final String IDENTITY_PROVIDER_BY_ID_QUERY = "select " + ID_PROVIDER_FIELDS + " from identity_provider " + "where id=?"; public static final String IDENTITY_PROVIDER_BY_ID_QUERY = "select " + ID_PROVIDER_FIELDS + " from identity_provider " + "where id=? and identity_zone_id=?";


public static final String IDENTITY_PROVIDER_BY_ORIGIN_QUERY = "select " + ID_PROVIDER_FIELDS + " from identity_provider " + "where origin_key=? and identity_zone_id=? "; public static final String IDENTITY_PROVIDER_BY_ORIGIN_QUERY = "select " + ID_PROVIDER_FIELDS + " from identity_provider " + "where origin_key=? and identity_zone_id=? ";


Expand All @@ -69,7 +70,7 @@ public JdbcIdentityProviderProvisioning(JdbcTemplate jdbcTemplate) {


@Override @Override
public IdentityProvider retrieve(String id) { public IdentityProvider retrieve(String id) {
IdentityProvider identityProvider = jdbcTemplate.queryForObject(IDENTITY_PROVIDER_BY_ID_QUERY, mapper, id); IdentityProvider identityProvider = jdbcTemplate.queryForObject(IDENTITY_PROVIDER_BY_ID_QUERY, mapper, id, IdentityZoneHolder.get().getId());
return identityProvider; return identityProvider;
} }


Expand Down Expand Up @@ -123,6 +124,7 @@ public void setValues(PreparedStatement ps) throws SQLException {
@Override @Override
public IdentityProvider update(final IdentityProvider identityProvider) { public IdentityProvider update(final IdentityProvider identityProvider) {
validate(identityProvider); validate(identityProvider);
final String zoneId = IdentityZoneHolder.get().getId();
jdbcTemplate.update(UPDATE_IDENTITY_PROVIDER_SQL, new PreparedStatementSetter() { jdbcTemplate.update(UPDATE_IDENTITY_PROVIDER_SQL, new PreparedStatementSetter() {
@Override @Override
public void setValues(PreparedStatement ps) throws SQLException { public void setValues(PreparedStatement ps) throws SQLException {
Expand All @@ -134,6 +136,7 @@ public void setValues(PreparedStatement ps) throws SQLException {
ps.setString(pos++, JsonUtils.writeValueAsString(identityProvider.getConfig())); ps.setString(pos++, JsonUtils.writeValueAsString(identityProvider.getConfig()));
ps.setBoolean(pos++, identityProvider.isActive()); ps.setBoolean(pos++, identityProvider.isActive());
ps.setString(pos++, identityProvider.getId().trim()); ps.setString(pos++, identityProvider.getId().trim());
ps.setString(pos++, zoneId);
} }
}); });
return retrieve(identityProvider.getId()); return retrieve(identityProvider.getId());
Expand Down
@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Cloud Foundry * Cloud Foundry
* Copyright (c) [2009-2014] Pivotal Software, Inc. All Rights Reserved. * Copyright (c) [2009-2014] Pivotal Software, Inc. All Rights Reserved.
* *
* This product is licensed to you under the Apache License, Version 2.0 (the "License"). * This product is licensed to you under the Apache License, Version 2.0 (the "License").
Expand All @@ -12,8 +12,6 @@
*******************************************************************************/ *******************************************************************************/
package org.cloudfoundry.identity.uaa.resources.jdbc; package org.cloudfoundry.identity.uaa.resources.jdbc;


import java.util.List;

import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.cloudfoundry.identity.uaa.resources.Queryable; import org.cloudfoundry.identity.uaa.resources.Queryable;
Expand All @@ -22,6 +20,8 @@
import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;


import java.util.List;

public abstract class AbstractQueryable<T> implements Queryable<T> { public abstract class AbstractQueryable<T> implements Queryable<T> {


private NamedParameterJdbcTemplate jdbcTemplate; private NamedParameterJdbcTemplate jdbcTemplate;
Expand Down Expand Up @@ -51,7 +51,7 @@ public void setQueryConverter(SearchQueryConverter queryConverter) {
* The maximum number of items fetched from the database in one hit. If less * The maximum number of items fetched from the database in one hit. If less
* than or equal to zero, then there is no * than or equal to zero, then there is no
* limit. * limit.
* *
* @param pageSize the page size to use for backing queries (default 200) * @param pageSize the page size to use for backing queries (default 200)
*/ */
public void setPageSize(int pageSize) { public void setPageSize(int pageSize) {
Expand Down Expand Up @@ -102,9 +102,14 @@ public List<T> query(String filter, String sortBy, boolean ascending) {
} }


protected String getQuerySQL(String filter, SearchQueryConverter.ProcessedFilter where) { protected String getQuerySQL(String filter, SearchQueryConverter.ProcessedFilter where) {
return filter == null || filter.trim().length()==0 ? if (filter == null || filter.trim().length()==0) {
getBaseSqlQuery() : return getBaseSqlQuery();
getBaseSqlQuery() + " where " + where.getSql(); }
if (where.hasOrderBy()) {
return getBaseSqlQuery() + " where (" + where.getSql().replace(where.ORDER_BY, ")"+where.ORDER_BY);
} else {
return getBaseSqlQuery() + " where (" + where.getSql() + ")";
}
} }


protected abstract String getBaseSqlQuery(); protected abstract String getBaseSqlQuery();
Expand Down

0 comments on commit e319144

Please sign in to comment.