package fr.xephi.authme.data.auth; import fr.xephi.authme.security.crypts.HashedPassword; import org.bukkit.Location; import java.util.Locale; import java.util.Objects; import java.util.Optional; import java.util.UUID; import static com.google.common.base.Preconditions.checkNotNull; /** * AuthMe player data. */ @SuppressWarnings("checkstyle:FinalClass") // Justification: class is mocked in multiple tests public class PlayerAuth { /** Default email used in the database if the email column is defined to be NOT NULL. */ public static final String DB_EMAIL_DEFAULT = "your@email.com"; /** Default last login value used in the database if the last login column is NOT NULL. */ public static final long DB_LAST_LOGIN_DEFAULT = 0; /** Default last ip value used in the database if the last IP column is NOT NULL. */ public static final String DB_LAST_IP_DEFAULT = "127.0.0.1"; /** The player's name in lowercase, e.g. "xephi". */ private String nickname; /** The player's name in the correct casing, e.g. "Xephi". */ private String realName; private HashedPassword password; private String totpKey; private String email; private String lastIp; private int groupId; private Long lastLogin; private String registrationIp; private long registrationDate; // Fields storing the player's quit location private double x; private double y; private double z; private String world; private float yaw; private float pitch; private UUID uuid; private boolean emailVerified; /** * Hidden constructor. * * @see #builder() */ private PlayerAuth() { } public void setNickname(String nickname) { this.nickname = nickname.toLowerCase(Locale.ROOT); } public String getNickname() { return nickname; } public String getRealName() { return realName; } public void setRealName(String realName) { this.realName = realName; } public int getGroupId() { return groupId; } public void setQuitLocation(Location location) { x = location.getBlockX(); y = location.getBlockY(); z = location.getBlockZ(); world = location.getWorld().getName(); } public double getQuitLocX() { return x; } public void setQuitLocX(double d) { this.x = d; } public double getQuitLocY() { return y; } public void setQuitLocY(double d) { this.y = d; } public double getQuitLocZ() { return z; } public void setQuitLocZ(double d) { this.z = d; } public String getWorld() { return world; } public void setWorld(String world) { this.world = world; } public float getYaw() { return yaw; } public float getPitch() { return pitch; } public String getLastIp() { return lastIp; } public void setLastIp(String lastIp) { this.lastIp = lastIp; } public Long getLastLogin() { return lastLogin; } public void setLastLogin(long lastLogin) { this.lastLogin = lastLogin; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public HashedPassword getPassword() { return password; } public void setPassword(HashedPassword password) { this.password = password; } public String getRegistrationIp() { return registrationIp; } public long getRegistrationDate() { return registrationDate; } public void setRegistrationDate(long registrationDate) { this.registrationDate = registrationDate; } public String getTotpKey() { return totpKey; } public void setTotpKey(String totpKey) { this.totpKey = totpKey; } public UUID getUuid() { return uuid; } public void setUuid(UUID uuid) { this.uuid = uuid; } public boolean isEmailVerified() { return emailVerified; } public void setEmailVerified(boolean emailVerified) { this.emailVerified = emailVerified; } @Override public boolean equals(Object obj) { if (!(obj instanceof PlayerAuth)) { return false; } PlayerAuth other = (PlayerAuth) obj; return Objects.equals(other.lastIp, this.lastIp) && Objects.equals(other.nickname, this.nickname); } @Override public int hashCode() { int hashCode = 7; hashCode = 71 * hashCode + (this.nickname != null ? this.nickname.hashCode() : 0); hashCode = 71 * hashCode + (this.lastIp != null ? this.lastIp.hashCode() : 0); return hashCode; } @Override public String toString() { return "Player : " + nickname + " | " + realName + " ! IP : " + lastIp + " ! LastLogin : " + lastLogin + " ! LastPosition : " + x + "," + y + "," + z + "," + world + " ! Email : " + email + " ! EmailVerified : " + emailVerified + " ! Password : {" + password.getHash() + ", " + password.getSalt() + "}" + " ! UUID : " + uuid; } public static Builder builder() { return new Builder(); } public static final class Builder { private String name; private String realName; private HashedPassword password; private String totpKey; private String lastIp; private String email; private int groupId = -1; private Long lastLogin; private String registrationIp; private Long registrationDate; private boolean emailVerified; private double x; private double y; private double z; private String world; private float yaw; private float pitch; private UUID uuid; /** * Creates a PlayerAuth object. * * @return the generated PlayerAuth */ public PlayerAuth build() { PlayerAuth auth = new PlayerAuth(); auth.nickname = checkNotNull(name).toLowerCase(Locale.ROOT); auth.realName = Optional.ofNullable(realName).orElse("Player"); auth.password = Optional.ofNullable(password).orElse(new HashedPassword("")); auth.totpKey = totpKey; auth.email = DB_EMAIL_DEFAULT.equals(email) ? null : email; auth.lastIp = lastIp; // Don't check against default value 127.0.0.1 as it may be a legit value auth.groupId = groupId; auth.lastLogin = isEqualTo(lastLogin, DB_LAST_LOGIN_DEFAULT) ? null : lastLogin; auth.registrationIp = registrationIp; auth.registrationDate = registrationDate == null ? System.currentTimeMillis() : registrationDate; auth.x = x; auth.y = y; auth.z = z; auth.world = Optional.ofNullable(world).orElse("world"); auth.yaw = yaw; auth.pitch = pitch; auth.uuid = uuid; auth.emailVerified = emailVerified; return auth; } private static boolean isEqualTo(Long value, long defaultValue) { return value != null && defaultValue == value; } public Builder name(String name) { this.name = name; return this; } public Builder realName(String realName) { this.realName = realName; return this; } public Builder password(HashedPassword password) { this.password = password; return this; } public Builder password(String hash, String salt) { return password(new HashedPassword(hash, salt)); } public Builder totpKey(String totpKey) { this.totpKey = totpKey; return this; } public Builder lastIp(String lastIp) { this.lastIp = lastIp; return this; } /** * Sets the location info based on the argument. * * @param location the location info to set * @return this builder instance */ public Builder location(Location location) { this.x = location.getX(); this.y = location.getY(); this.z = location.getZ(); this.world = location.getWorld().getName(); this.yaw = location.getYaw(); this.pitch = location.getPitch(); return this; } public Builder locX(double x) { this.x = x; return this; } public Builder locY(double y) { this.y = y; return this; } public Builder locZ(double z) { this.z = z; return this; } public Builder locWorld(String world) { this.world = world; return this; } public Builder locYaw(float yaw) { this.yaw = yaw; return this; } public Builder locPitch(float pitch) { this.pitch = pitch; return this; } public Builder lastLogin(Long lastLogin) { this.lastLogin = lastLogin; return this; } public Builder groupId(int groupId) { this.groupId = groupId; return this; } public Builder email(String email) { this.email = email; return this; } public Builder emailVerified(boolean emailVerified) { this.emailVerified = emailVerified; return this; } public Builder registrationIp(String ip) { this.registrationIp = ip; return this; } public Builder registrationDate(long date) { this.registrationDate = date; return this; } public Builder uuid(UUID uuid) { this.uuid = uuid; return this; } } }