package com.rapidftr.model;
import android.content.SharedPreferences;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rapidftr.RapidFtrApplication;
import com.rapidftr.utils.EncryptionUtil;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.UUID;
@JsonIgnoreProperties(ignoreUnknown = true)
@EqualsAndHashCode(of = {"userName", "verified"})
@AllArgsConstructor(suppressConstructorProperties = true)
public class User {
public static final ObjectMapper JSON_MAPPER = new ObjectMapper();
public static final String UNAUTHENTICATED_DB_KEY = "UNAUTHENTICATED_DB_KEY";
public static final String UNAUTHENTICATED_DB_NAME = "DB-" + UNAUTHENTICATED_DB_KEY.hashCode();
@Getter @JsonProperty("user_name")
protected String userName;
@Getter @Setter @JsonIgnore
protected String password;
@Getter @Setter @JsonProperty("verified")
protected boolean verified;
@Getter @Setter @JsonProperty("server_url")
protected String serverUrl;
@Getter @Setter @JsonProperty("db_key")
protected String dbKey;
@Getter @Setter @JsonProperty("organisation")
protected String organisation;
@Getter @Setter @JsonProperty("full_name")
protected String fullName;
@Getter @Setter @JsonProperty("unauthenticated_password")
protected String unauthenticatedPassword;
@Getter @Setter @JsonProperty("language")
protected String language;
protected User() {
}
public User(String userName) {
this(userName, null, false, null, null, null, null, null, null);
}
public User(String userName, String password) {
this(userName, password, false, null, null, null, null, null, null);
}
public User(String userName, String password, boolean authenticated) {
this(userName, password, authenticated, null, null, null, null, null, null);
}
public User(String userName, String password, boolean authenticated, String serverUrl) {
this(userName, password, authenticated, serverUrl, null, null, null, null, null);
}
public String getDbName() {
return getDbKey() == null ? null : ("DB-" + getDbKey().hashCode());
}
public String asJSON() throws IOException {
return getJsonMapper().writeValueAsString(this);
}
public String asEncryptedJSON() throws IOException, GeneralSecurityException {
if (this.password == null)
throw new GeneralSecurityException("User password not available to encrypt");
else
return EncryptionUtil.encrypt(this.password, this.userName, this.asJSON());
}
public User read(String json) throws IOException {
getJsonMapper().readerForUpdating(this).readValue(json);
return this;
}
public User load() throws GeneralSecurityException, IOException {
String encryptedJson = getSharedPreferences().getString(prefKey(userName), null);
String json = EncryptionUtil.decrypt(password, this.userName, encryptedJson);
return read(json);
}
public void save() throws IOException, GeneralSecurityException {
if (!this.isVerified()) {
this.setUnauthenticatedPassword(this.getPassword());
this.setDbKey(getUnauthenticatedDbKey());
}
getSharedPreferences().edit().putString(prefKey(userName), asEncryptedJSON()).commit();
}
public boolean exists() {
return getSharedPreferences().contains(prefKey(userName));
}
protected ObjectMapper getJsonMapper() {
return JSON_MAPPER;
}
public static User readFromJSON(String json) throws IOException {
return new User().read(json);
}
protected static SharedPreferences getSharedPreferences() {
return RapidFtrApplication.getApplicationInstance().getSharedPreferences();
}
protected static String getUnauthenticatedDbKey() {
String dbKey = getSharedPreferences().getString(UNAUTHENTICATED_DB_KEY, null);
return dbKey != null ? dbKey : createUnauthenticatedDbKey();
}
protected static String createUnauthenticatedDbKey() {
String dbKey = UUID.randomUUID().toString();
getSharedPreferences().edit().putString(UNAUTHENTICATED_DB_KEY, dbKey).commit();
return dbKey;
}
protected static String prefKey(String userName) {
return "user_" + userName;
}
}