package jenkins.security;
import hudson.model.User;
import hudson.security.SecurityRealm;
import hudson.security.UserMayOrMayNotExistException;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UserDetailsService;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.springframework.dao.DataAccessException;
import static java.util.Collections.*;
/**
* {@link UserDetailsService} for those {@link SecurityRealm}
* that doesn't allow query of other users.
*
* When the backend responds with {@link UserMayOrMayNotExistException}, we try to replace that with
* information stored in {@link LastGrantedAuthoritiesProperty}.
*
* @author Kohsuke Kawaguchi
*/
public class ImpersonatingUserDetailsService implements UserDetailsService {
private final UserDetailsService base;
public ImpersonatingUserDetailsService(UserDetailsService base) {
this.base = base;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
try {
return base.loadUserByUsername(username);
} catch (UserMayOrMayNotExistException e) {
return attemptToImpersonate(username, e);
} catch (DataAccessException e) {
return attemptToImpersonate(username, e);
}
}
protected UserDetails attemptToImpersonate(String username, RuntimeException e) {
// this backend cannot tell if the user name exists or not. so substitute by what we know
User u = User.getById(username, false);
if (u!=null) {
LastGrantedAuthoritiesProperty p = u.getProperty(LastGrantedAuthoritiesProperty.class);
if (p!=null)
return new org.acegisecurity.userdetails.User(username,"",true,true,true,true,
p.getAuthorities());
}
throw e;
}
}