All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.launchkey.sdk.auth.AuthenticationManager Maven / Gradle / Ivy

Go to download

SDK for interacting with the LaunchKey distributed authentication and authorization platform

There is a newer version: 4.0.0
Show newest version
package com.launchkey.sdk.auth;

import com.launchkey.sdk.Util;
import com.launchkey.sdk.crypto.Crypto;
import com.launchkey.sdk.http.AuthControllerInterface;
import com.launchkey.sdk.http.JSONResponse;
import net.sf.json.JSONObject;

import java.text.SimpleDateFormat;
import java.util.Date;

public class AuthenticationManager {
    private static final String AUTHENTICATE = "Authenticate";
    private static final String REVOKE = "Revoke";
    private static final String DEFAULT_ERROR_CODE = "1000";

    private final AuthControllerInterface authController;
    private final String _privateKeyString;

    public AuthenticationManager(AuthControllerInterface authController) {
        this.authController = authController;
        this._privateKeyString = authController.getPrivateKey();
    }

    /**
     * Call to authorize a username via LaunchKey
     *
     * @param username
     */
    public AuthorizeResult authorize(final String username) throws AuthenticationException {
        return authorize(username, false, false);
    }

    /**
     * Call to authorize a username via LaunchKey
     *
     * @param username
     * @param userPushId
     */
    public AuthorizeResult authorize(final String username, boolean userPushId) throws AuthenticationException {
        return authorize(username, false, userPushId);
    }

    /**
     * Call to authorize a username via LaunchKey
     * @param username
     * @param session
     * @param userPushId
     * @return
     * @throws AuthenticationException
     */
    public AuthorizeResult authorize(final String username, boolean session, boolean userPushId) throws AuthenticationException {
        JSONResponse pingResponse = this.authController.pingGet();
        if(pingResponse.isSuccess()) {
            String launchkeyTime = pingResponse.getJson().getString("launchkey_time");
            String _publicKey = pingResponse.getJson().getString("key");
            JSONResponse authsPostResponse = authController.authsPost(launchkeyTime, _publicKey, username, session, userPushId);
            if(authsPostResponse.isSuccess()) {
                AuthorizeResult result = new AuthorizeResult();
                result.setAuthRequest(authsPostResponse.getJson().getString("auth_request"));
                result.setLaunchkeyTime(launchkeyTime);
                return result;
            }
            else {
                throw new AuthenticationException(getErrorMessage(authsPostResponse.getJson()),
                        getErrorCode(authsPostResponse.getJson()));
            }
        }
        else {
            throw new AuthenticationException(getErrorMessage(pingResponse.getJson()),
                    getErrorCode(pingResponse.getJson()));
        }
    }

    /**
     * Call to determine whether the username is still authorized (i.e. has not remotely ended the session)
     * @param authRequest
     * @return
     * @throws AuthenticationException
     */
    public boolean isAuthorized(final String authRequest) throws AuthenticationException {
        JSONResponse pingResponse = this.authController.pingGet();
        if(pingResponse.isSuccess()) {
            String _publicKey = pingResponse.getJson().getString("key");
            String launchkeyTime = pingResponse.getJson().getString("launchkey_time");
            JSONResponse pollResponse = authController.pollGet(launchkeyTime, _publicKey, authRequest);
            if(pollResponse.isSuccess()) {
                return true;
            }
            else {
                if(pollResponse.getJson().has("message_code") &&
                        pollResponse.getJson().getString("message_code").equals("70404")) {
                    logsPutLogout(authRequest, true);
                }
                return false;
            }
        }
        else {
            throw new AuthenticationException(getErrorMessage(pingResponse.getJson()),
                    getErrorCode(pingResponse.getJson()));
        }
    }

    /**
     * Call to determine whether the username is still authorized (i.e. has not remotely ended the session)
     *
     * This method has been deprecated in favor of isAuthorized(String)
     *
     * @param authRequest
     * @param launchkeyTime
     * @return
     * @throws AuthenticationException
     */
    @Deprecated
    public boolean isAuthorized(final String authRequest, String launchkeyTime) throws AuthenticationException {
        return isAuthorized(authRequest);
    }

    /**
     * Call to end a session
     *
     * @param authRequest
     */
    public boolean logout(String authRequest) throws AuthenticationException {
        return logsPutLogout(authRequest, true);
    }

    /**
     * Method to poll (Poll GET) the server for an authorization
     * @param authRequest
     * @param launchkeyTime
     * @return
     * @throws AuthenticationException
     */
    public PollResult poll(String authRequest, String launchkeyTime) throws AuthenticationException {
        JSONResponse pingResponse = this.authController.pingGet();
        if (pingResponse.isSuccess()) {
            String _publicKey = pingResponse.getJson().getString("key");

            JSONResponse pollGetResponse =  authController.pollGet(launchkeyTime, _publicKey, authRequest);
            if(pollGetResponse.isSuccess()) {
                String encryptedAuth = pollGetResponse.getJson().getString("auth");
                String userHash = pollGetResponse.getJson().getString("user_hash");
                String userPushId = pollGetResponse.getJson().has("user_push_id")
                        ? pollGetResponse.getJson().getString("user_push_id")
                        : null;

                byte[] resultNot64 = null;
                String result = null;
                try {
                    resultNot64 = Crypto.decryptWithPrivateKey(Util.base64Decode(encryptedAuth.getBytes("UTF-8")),
                            _privateKeyString);
                    result = new String(resultNot64, "UTF-8");
                }
                catch(Exception e) {
                    //no op
                }

                JSONObject jsonResult = JSONObject.fromObject(result);

                if(!authRequest.equals(jsonResult.getString("auth_request"))) {
                    throw new AuthenticationException("Auth tokens do not match", DEFAULT_ERROR_CODE);
                }
                else {
                    boolean action = Boolean.valueOf(jsonResult.getString("response"));
                    String appPins = jsonResult.optString("app_pins");
                    String deviceId = jsonResult.getString("device_id");

                    return logsPutAuthenticate(userHash, authRequest, appPins, deviceId, userPushId, action);
                }

            } else {
                if(pollGetResponse.getJson().has("message_code")) {
                    if(pollGetResponse.getJson().getString("message_code").equals("70404")) {
                        throw new AuthenticationException("User denied request", DEFAULT_ERROR_CODE);
                    }
                    else if(!pollGetResponse.getJson().getString("message_code").equals("70403")) {
                        throw new AuthenticationException(
                            getErrorMessage(pollGetResponse.getJson()),
                            getErrorCode(pollGetResponse.getJson())
                        );
                    }
                }
                throw new AuthenticationException(getErrorMessage(
                    pollGetResponse.getJson()),
                    getErrorCode(pollGetResponse.getJson())
                );
            }
        } else {
            throw new AuthenticationException(
                getErrorMessage(pingResponse.getJson()),
                getErrorCode(pingResponse.getJson())
            );

        }
    }

    /**
     * Does a logs PUT when the polling is complete to notify the server of the action
     * @param userHash
     * @param authRequest
     * @param appPins
     * @param deviceId
     * @param userPushId
     * @param status
     * @return
     * @throws AuthenticationException
     */
    private PollResult logsPutAuthenticate(String userHash, String authRequest, String appPins, String deviceId, String userPushId,
                                     final boolean status) throws AuthenticationException {
        JSONResponse pingResponse = this.authController.pingGet();
        if(pingResponse.isSuccess()) {
            String launchkeyTime = pingResponse.getJson().getString("launchkey_time");
            String _publicKey = pingResponse.getJson().getString("key");
            JSONResponse logsPutResponse = authController.logsPut(authRequest, launchkeyTime, _publicKey, AUTHENTICATE, status);
            if(logsPutResponse.isSuccess()) {
                if(status) {
                    PollResult pollResult = new PollResult();
                    pollResult.setUserHash(userHash);
                    pollResult.setAuthRequest(authRequest);
                    pollResult.setAppPins(appPins);
                    pollResult.setDeviceId(deviceId);
                    pollResult.setUserPushId(userPushId);
                    return pollResult;
                }
                else {
                    throw new AuthenticationException("User denied request", DEFAULT_ERROR_CODE);
                }
            }
            else {
                throw new AuthenticationException(getErrorMessage(logsPutResponse.getJson()),
                        getErrorCode(logsPutResponse.getJson()));
            }
        }
        else {
            throw new AuthenticationException(getErrorMessage(pingResponse.getJson()),
                    getErrorCode(pingResponse.getJson()));
        }
    }

    /**
     * Does a logs PUT when the polling is complete to notify the server of the action
     * @param authRequest
     * @param status
     * @return
     * @throws AuthenticationException
     */
    private boolean logsPutLogout(String authRequest, boolean status) throws AuthenticationException {
        JSONResponse pingResponse = this.authController.pingGet();
        if(pingResponse.isSuccess()) {
            String launchkeyTime = pingResponse.getJson().getString("launchkey_time");
            String _publicKey = pingResponse.getJson().getString("key");
            JSONResponse logsPutResponse = authController.logsPut(authRequest, launchkeyTime, _publicKey, REVOKE,
                    status);
            return logsPutResponse.isSuccess();
        }
        else {
            throw new AuthenticationException(getErrorMessage(pingResponse.getJson()),
                    getErrorCode(pingResponse.getJson()));
        }
    }

    /**
     * Verify the deorbit request by signature and timestamp
     * @param deorbit  JSON string from LaunchKey with the user_hash and launchkey_time.
     * @param signature Signature signed by API to verify the authenticity of the data found in the deorbit JSON.
     * @return the user_hash needed to identify the user and log them out, null on failure
     */
    public String deorbit(String deorbit, String signature) {
        JSONResponse pingResponse = this.authController.pingGet();
        if(pingResponse.isSuccess()) {
            String _publicKey = pingResponse.getJson().getString("key");
            String launchkeyTime = pingResponse.getJson().getString("launchkey_time");
            try {
                if(Crypto.verifySignature(_publicKey, Util.base64Decode(signature.getBytes()),
                        deorbit.getBytes("UTF-8"))) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    Date pingTime = simpleDateFormat.parse(launchkeyTime);
                    JSONObject jsonObject = JSONObject.fromObject(deorbit);
                    Date requestDate = simpleDateFormat.parse(jsonObject.getString("launchkey_time"));
                    if(pingTime.getTime() - requestDate.getTime() < 5 * 1000 * 60) {
                        //only handle requests within a 5 minute time delay
                        return jsonObject.getString("user_hash");
                    }
                }
            }
            catch(Exception e) {
                //no op
            }
        }
        return null;
    }

    /**
     * This method is for creating users for a White Label application only.
     * 
     * It Create a new user for a White Label application  .If the user for the specified identifier already exists,
     * then set up a new device for that user
     *  
     * @param identifier  Unique identifier for the user in your application.  This should be a static value such as a
     *                    user's ID or UUID value rather than an email address which may be subject to change. This
     *                    identifier will be used authenticate the user as well as pair devices additional devices to
     *                    the user's account within your white label group.
     * @return
     * @throws UserCreationException
     */
    public WhiteLabelUserCreateResult createWhiteLabelUser(String identifier) throws UserCreationException {
        WhiteLabelUserCreateResult result;
        JSONResponse pingResponse = this.authController.pingGet();
        if (pingResponse.isSuccess()) {
            String publicKey = pingResponse.getJson().getString("key");
            String launchkeyTime = pingResponse.getJson().getString("launchkey_time");
            JSONResponse response = authController.usersPost(launchkeyTime, publicKey, identifier);
            if (response.isSuccess()) {
                result = new WhiteLabelUserCreateResult(
                        response.getJson().getJSONObject("response").getString("qrcode"),
                        response.getJson().getJSONObject("response").getString("code")
                );
            } else {
                throw new UserCreationException(getErrorMessage(response.getJson()), getErrorCode(response.getJson()));
            }
        } else {
            throw new UserCreationException(getErrorMessage(pingResponse.getJson()), getErrorCode(pingResponse.getJson()));
        }
        return result;
    }

    private static String getErrorMessage(JSONObject response) {
        if(response.has("message")) {
            return response.getString("message");
        }
        return "";
    }

    private static String getErrorCode(JSONObject response) {
        if(response.has("message_code")) {
            return response.getString("message_code");
        }
        return "";
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy