/hudson-core/src/main/java/hudson/cli/ClientAuthenticationCache.java
http://github.com/hudson/hudson · Java · 126 lines · 79 code · 14 blank · 33 comment · 4 complexity · 7f6163305a5c079af5fa84629da46155 MD5 · raw file
- package hudson.cli;
- import hudson.FilePath;
- import hudson.FilePath.FileCallable;
- import hudson.model.Hudson;
- import hudson.model.Hudson.MasterComputer;
- import hudson.os.PosixAPI;
- import hudson.remoting.Callable;
- import hudson.remoting.Channel;
- import hudson.remoting.VirtualChannel;
- import hudson.util.Secret;
- import org.acegisecurity.Authentication;
- import org.acegisecurity.AuthenticationException;
- import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
- import org.acegisecurity.userdetails.UserDetails;
- import org.springframework.dao.DataAccessException;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.io.Serializable;
- import java.util.Properties;
- /**
- * Represents the authentication credential store of the CLI client.
- *
- * <p>
- * This object encapsulates a remote manipulation of the credential store.
- * We store encrypted user names.
- *
- * @author Kohsuke Kawaguchi
- * @since 1.351
- */
- public class ClientAuthenticationCache implements Serializable {
- /**
- * Where the store should be placed.
- */
- private final FilePath store;
- /**
- * Loaded contents of the store.
- */
- private final Properties props = new Properties();
- public ClientAuthenticationCache(Channel channel) throws IOException, InterruptedException {
- store = (channel==null ? MasterComputer.localChannel : channel).call(new Callable<FilePath, IOException>() {
- public FilePath call() throws IOException {
- File home = new File(System.getProperty("user.home"));
- return new FilePath(new File(home, ".hudson/cli-credentials"));
- }
- });
- if (store.exists()) {
- props.load(store.read());
- }
- }
- /**
- * Gets the persisted authentication for this Hudson.
- *
- * @return {@link Hudson#ANONYMOUS} if no such credential is found, or if the stored credential is invalid.
- */
- public Authentication get() {
- Hudson h = Hudson.getInstance();
- Secret userName = Secret.decrypt(props.getProperty(getPropertyKey()));
- if (userName==null) return Hudson.ANONYMOUS; // failed to decrypt
- try {
- UserDetails u = h.getSecurityRealm().loadUserByUsername(userName.toString());
- return new UsernamePasswordAuthenticationToken(u.getUsername(), u.getPassword(), u.getAuthorities());
- } catch (AuthenticationException e) {
- return Hudson.ANONYMOUS;
- } catch (DataAccessException e) {
- return Hudson.ANONYMOUS;
- }
- }
- /**
- * Computes the key that identifies this Hudson among other Hudsons that the user has a credential for.
- */
- private String getPropertyKey() {
- String url = Hudson.getInstance().getRootUrl();
- if (url!=null) return url;
- return Secret.fromString("key").toString();
- }
- /**
- * Persists the specified authentication.
- */
- public void set(Authentication a) throws IOException, InterruptedException {
- Hudson h = Hudson.getInstance();
- // make sure that this security realm is capable of retrieving the authentication by name,
- // as it's not required.
- UserDetails u = h.getSecurityRealm().loadUserByUsername(a.getName());
- props.setProperty(getPropertyKey(), Secret.fromString(u.getUsername()).getEncryptedValue());
- save();
- }
- /**
- * Removes the persisted credential, if there's one.
- */
- public void remove() throws IOException, InterruptedException {
- if (props.remove(getPropertyKey())!=null)
- save();
- }
- private void save() throws IOException, InterruptedException {
- store.act(new FileCallable<Void>() {
- public Void invoke(File f, VirtualChannel channel) throws IOException, InterruptedException {
- f.getParentFile().mkdirs();
- OutputStream os = new FileOutputStream(f);
- try {
- props.store(os,"Credential store");
- } finally {
- os.close();
- }
- // try to protect this file from other users, if we can.
- PosixAPI.get().chmod(f.getAbsolutePath(),0600);
- return null;
- }
- });
- }
- }