package io.lumify.termsOfUse;
import com.google.inject.Inject;
import io.lumify.core.config.Configuration;
import io.lumify.core.exception.LumifyException;
import io.lumify.core.model.user.UserRepository;
import io.lumify.core.model.workspace.WorkspaceRepository;
import io.lumify.core.user.User;
import io.lumify.core.util.LumifyLogger;
import io.lumify.core.util.LumifyLoggerFactory;
import io.lumify.miniweb.HandlerChain;
import io.lumify.web.BaseRequestHandler;
import org.apache.commons.codec.binary.Hex;
import org.json.JSONObject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TermsOfUse extends BaseRequestHandler {
private static final LumifyLogger LOGGER = LumifyLoggerFactory.getLogger(TermsOfUse.class);
private JSONObject termsJson;
private String termsHash;
public static final String TITLE_PROPERTY = "termsOfUse.title";
public static final String DEFAULT_TITLE = "Terms of Use";
public static final String HTML_PROPERTY = "termsOfUse.html";
public static final String DEFAULT_HTML = "<p>These are the terms to which you must agree before using Lumify:</p><p>With great power comes great responsibility. Please use Lumify responsibly.</p>";
public static final String DATE_PROPERTY = "termsOfUse.date";
public static final String DATE_PROPERTY_FORMAT = "yyyy-MM-dd";
private static final String UI_PREFERENCE_KEY = "termsOfUse";
private static final String UI_PREFERENCE_HASH_SUBKEY = "hash";
private static final String UI_PREFERENCE_DATE_SUBKEY = "date";
@Inject
protected TermsOfUse(UserRepository userRepository, WorkspaceRepository workspaceRepository, Configuration configuration) {
super(userRepository, workspaceRepository, configuration);
String title = configuration.get(TITLE_PROPERTY, DEFAULT_TITLE);
String html = configuration.get(HTML_PROPERTY, DEFAULT_HTML);
termsHash = hash(html);
Date date = null;
String dateString = configuration.get(DATE_PROPERTY, null);
if (dateString != null) {
SimpleDateFormat sdf = new SimpleDateFormat(DATE_PROPERTY_FORMAT);
try {
date = sdf.parse(dateString);
} catch (ParseException e) {
throw new LumifyException("unable to parse " + DATE_PROPERTY + " property with format " + DATE_PROPERTY_FORMAT, e);
}
}
termsJson = new JSONObject();
termsJson.put("title", title);
termsJson.put("html", html);
termsJson.put("hash", termsHash);
if (date != null) {
termsJson.put("date", date);
}
}
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, HandlerChain chain) throws Exception {
User user = getUser(request);
if (request.getMethod().equals("POST")) {
recordAcceptance(user, getRequiredParameter(request, "hash"));
JSONObject successJson = new JSONObject();
successJson.put("success", true);
successJson.put("message", "Terms of Use accepted.");
respondWithJson(response, successJson);
} else {
JSONObject termsAndStatus = new JSONObject();
termsAndStatus.put("terms", termsJson);
termsAndStatus.put("status", getStatus(user));
respondWithJson(response, termsAndStatus);
}
}
private String hash(String s) {
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] md5 = digest.digest(s.getBytes());
return Hex.encodeHexString(md5);
} catch (NoSuchAlgorithmException e) {
throw new LumifyException("Could not find MD5", e);
}
}
private JSONObject getUiPreferences(User user) {
JSONObject uiPreferences = user.getUiPreferences();
return uiPreferences != null ? uiPreferences : new JSONObject();
}
private void recordAcceptance(User user, String hash) {
JSONObject uiPreferences = getUiPreferences(user);
JSONObject touJson = new JSONObject();
touJson.put(UI_PREFERENCE_HASH_SUBKEY, hash);
touJson.put(UI_PREFERENCE_DATE_SUBKEY, new Date());
uiPreferences.put(UI_PREFERENCE_KEY, touJson);
getUserRepository().setUiPreferences(user, uiPreferences);
}
private JSONObject getStatus(User user) {
JSONObject uiPreferences = getUiPreferences(user);
JSONObject touJson = uiPreferences.optJSONObject(UI_PREFERENCE_KEY);
JSONObject statusJson = new JSONObject();
statusJson.put("current", false);
if (touJson != null) {
if (touJson.getString(UI_PREFERENCE_HASH_SUBKEY).equals(termsHash)) {
statusJson.put("current", true);
statusJson.put("accepted", touJson.getString(UI_PREFERENCE_DATE_SUBKEY));
}
}
return statusJson;
}
}