package org.multibit.mbm.model; import com.google.common.collect.Sets; import org.multibit.mbm.auth.Authority; import org.multibit.mbm.utils.ObjectUtils; import java.util.Arrays; import java.util.Set; import java.util.UUID; /** * <p>DTO to provide the following to Resources:</p> * <ul> * <li>Provision of state for a single User as viewed by the Customer</li> * </ul> * <p>This is used when the client needs to authenticate the user, and when proxying * requests upstream to MBM.</p> * * @since 0.0.1 *   */ public class ClientUser { /** * Numerical ID to allow faster indexing (for internal use) */ protected Long id = null; /** * <p>UUID to allow public User reference without * revealing a sequential ID that could be guessed. * Typically used as an API key</p> */ protected String apiKey = null; /** * <p>Used as a shared secret to authenticate this user to the upstream server. Typically * part of an HMAC authentication scheme.</p> */ protected String secretKey = null; /** * <p>A user password (not plaintext and optional for anonymity reasons)</p> */ protected String passwordDigest = null; /** * <p>A username (optional for anonymity reasons)</p> */ protected String username = null; /** * A shared secret between this client the user's browser that is revoked when the session ends */ private UUID sessionToken; private Set<Authority> cachedAuthorities=Sets.newLinkedHashSet(); /** * @return The internal unique ID */ public Long getId() { return id; } public void setId(Long id) { this.id = id; } /** * @return The public API key used when identifying the user during HMAC authentication */ public String getApiKey() { return apiKey; } public void setApiKey(String apiKey) { this.apiKey = apiKey; } /** * @return The private shared secret for upstream communications */ public String getSecretKey() { return secretKey; } public void setSecretKey(String secretKey) { this.secretKey = secretKey; } /** * @return The user name to authenticate with the client */ public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } /** * @return The digested password to provide authentication between the user and the client */ public String getPasswordDigest() { return passwordDigest; } /** * <h3>Note that it is expected that Jasypt or similar is used prior to storage</h3> * @param passwordDigest The password digest */ public void setPasswordDigest(String passwordDigest) { this.passwordDigest = passwordDigest; } /** * @return The session key */ public UUID getSessionToken() { return sessionToken; } public void setSessionToken(UUID sessionToken) { this.sessionToken = sessionToken; } /** * @return The set of authorities for this user */ public Set<Authority> getCachedAuthorities() { return cachedAuthorities; } public void setCachedAuthorities(Authority[] cachedAuthorities) { this.cachedAuthorities = Sets.newLinkedHashSet(Arrays.asList(cachedAuthorities)); } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final ClientUser other = (ClientUser) obj; return ObjectUtils.isEqual( apiKey, other.apiKey, secretKey, other.secretKey ); } @Override public int hashCode() { return ObjectUtils.getHashCode(apiKey); } /** * @param authorities The required authorities * @return True if the user has all the required authorities * */ public boolean hasAllAuthorities(Authority[] authorities) { Set<Authority> requiredAuthorities = Sets.newHashSet(authorities); return getCachedAuthorities().containsAll(requiredAuthorities); } }