001package systems.dmx.core.service.accesscontrol;
002
003import systems.dmx.core.util.JavaUtils;
004
005import org.codehaus.jettison.json.JSONObject;
006
007import com.sun.jersey.core.util.Base64;
008
009
010
011/**
012 * A pair of username and SHA256 encoded password.
013 */
014public class Credentials {
015
016    // ------------------------------------------------------------------------------------------------------- Constants
017
018    private static final String ENCODED_PASSWORD_PREFIX = "-SHA256-";
019
020    // ---------------------------------------------------------------------------------------------- Instance Variables
021
022    public String username;
023    public String password;             // SHA256 encoded
024    public String plaintextPassword;    // possibly uninitialized
025    public String methodName;           // possibly uninitialized
026
027    // ---------------------------------------------------------------------------------------------------- Constructors
028
029    /**
030     * Used to create an user account programmatically (via migration).
031     *
032     * @param   password    as plain text
033     */
034    public Credentials(String username, String password) {
035        this.username = username;
036        this.password = encodePassword(password);
037    }
038
039    /**
040     * Used to create an user account programmatically (via Webclient).
041     *
042     * Note: invoked from JAX-RS message body reader (see Webservice's ObjectProvider.java).
043     *
044     * @param   cred    A JSON object with 2 properties: "username" and "password".
045     *                  The password is expected to be SHA256 encoded.
046     */
047    public Credentials(JSONObject cred) {
048        try {
049            this.username = cred.getString("username");
050            this.password = cred.getString("password");
051        } catch (Exception e) {
052            throw new IllegalArgumentException("Illegal JSON argument " + cred, e);
053        }
054    }
055
056    /**
057     * Used to authorize a request.
058     */
059    public Credentials(String authHeader) {
060        String[] splitted = authHeader.split("\\s+");
061        if (splitted.length != 2) {
062            throw new IllegalArgumentException("Illegal Authorization header: \"" + authHeader + "\"");
063        }
064        String method = splitted[0];
065        String userAndPassword = splitted[1];
066        String[] values = new String(Base64.base64Decode(userAndPassword)).split(":");
067        // Note: for the browser's own login dialog:
068        //   values.length is 0 if neither a username nor a password is entered
069        //   values.length is 1 if no password is entered
070        String username = values.length > 0 ? values[0] : "";
071        String password = values.length > 1 ? values[1] : "";
072        this.username = username;
073        this.password = encodePassword(password);
074        this.plaintextPassword = password;
075        this.methodName = method;
076    }
077
078    // -------------------------------------------------------------------------------------------------- Public Methods
079
080    public String toString() {
081        return "username=\"" + username + "\", password=\""+ password + "\"";
082    }
083
084    // ------------------------------------------------------------------------------------------------- Private Methods
085
086    private String encodePassword(String password) {
087        return ENCODED_PASSWORD_PREFIX + JavaUtils.encodeSHA256(password);
088    }
089}