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; } }