package nl.minicom.gitolite.manager.models;
import java.util.Comparator;
import java.util.Map;
import nl.minicom.gitolite.manager.exceptions.ModificationException;
import nl.minicom.gitolite.manager.models.Recorder.Modification;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
/**
* This class represents a user in Gitolite.
*
* @author Michael de Jong <<a href="mailto:michaelj@minicom.nl">michaelj@minicom.nl</a>>
*/
public final class User implements Identifiable {
static final Comparator<User> SORT_BY_NAME = new Comparator<User>() {
@Override
public int compare(User arg0, User arg1) {
return arg0.getName().compareTo(arg1.getName());
}
};
private final String name;
private final Map<String, String> keys;
private final Recorder recorder;
/**
* Constructs a new {@link User} object with the provided name and public key.
*
* @param name
* The name of the user.
*/
User(String name) {
this(name, new Recorder());
}
/**
* Constructs a new {@link User} object with the provided name and public key.
*
* @param name
* The name of the user.
*
* @param recorder
* The {@link Recorder} to use when recording changes of this {@link User}.
*/
User(String name, Recorder recorder) {
Preconditions.checkNotNull(name);
Preconditions.checkArgument(!name.isEmpty());
Preconditions.checkArgument(name.matches("^\\w[\\w._\\@+-]+$"), "\"" + name + "\" is not a valid user name");
Preconditions.checkNotNull(recorder);
this.name = name;
this.recorder = recorder;
this.keys = Maps.newTreeMap();
}
/**
* @return
* The name of the {@link User}.
*/
public String getName() {
return name;
}
/**
* This method allows you to set (and override existing) SSH keys for this particular {@link User}.
*
* @param name
* The name of the key. This may not be NULL.
*
* @param content
* The content of the public key file. This may not be NULL.
*/
public void setKey(final String name, final String content) {
Preconditions.checkNotNull(name);
Preconditions.checkNotNull(content);
Preconditions.checkArgument(name.matches("^[\\w._+-]*$"), "\"" + name + "\" is not a valid key name");
Preconditions.checkArgument(content.matches("^ssh-rsa\\s.+$"));
synchronized (keys) {
keys.put(name, content);
}
recorder.append(new Modification("Setting key: '%s' for user: '%s'", name, getName()) {
@Override
public void apply(Config config) throws ModificationException {
config.getUser(getName()).setKey(name, content);
}
});
}
/**
* @return
* An {@link Map} of SSH keys for this user. The key of the {@link Map}
* is the name of the key, and the value is the contents of the associated key file.
*/
public ImmutableMap<String, String> getKeys() {
synchronized (keys) {
return ImmutableMap.copyOf(keys);
}
}
/**
* This method removes the SSH key with the specified name from this {@link User} object.
*
* @param name
* The name of the SSH key to remove.
*/
public void removeKey(final String name) {
Preconditions.checkNotNull(name);
synchronized (keys) {
keys.remove(name);
}
recorder.append(new Modification("Removing key: '%s' for user: '%s'", name, getName()) {
@Override
public void apply(Config config) throws ModificationException {
config.getUser(getName()).removeKey(name);
}
});
}
@Override
public int hashCode() {
return new HashCodeBuilder()
.append(name)
.toHashCode();
}
@Override
public boolean equals(Object other) {
if (!(other instanceof User)) {
return false;
}
return new EqualsBuilder()
.append(name, ((User) other).name)
.isEquals();
}
}