package edu.harvard.iq.dataverse.passwordreset;
import edu.harvard.iq.dataverse.authorization.providers.builtin.BuiltinUser;
import edu.harvard.iq.dataverse.util.SystemConfig;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;
import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Table(indexes = {@Index(columnList="token")
, @Index(columnList="builtinuser_id")})
@NamedQueries({
@NamedQuery(name="PasswordResetData.findAll",
query="SELECT prd FROM PasswordResetData prd"),
@NamedQuery(name="PasswordResetData.findByUser",
query="SELECT prd FROM PasswordResetData prd WHERE prd.builtinUser = :user"),
@NamedQuery(name="PasswordResetData.findByToken",
query="SELECT prd FROM PasswordResetData prd WHERE prd.token = :token")
})
@Entity
public class PasswordResetData implements Serializable {
public enum Reason {
FORGOT_PASSWORD,
UPGRADE_REQUIRED
}
// TODO cleaup: can remove the (unused) id field, and use the token field as an id instead.
// This will prevent duplicate tokens (ok, not a likely poroblem) and would
// make the token lookup much faster.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = true)
private String token;
/**
* @todo Is there an annotation to help enforce that a given DataverseUser
* can only have one token at a time?
*/
@OneToOne
@JoinColumn(nullable = false)
private BuiltinUser builtinUser;
@Column(nullable = false)
private Timestamp created;
@Column(nullable = false)
private Timestamp expires;
@Enumerated(EnumType.STRING)
private Reason reason;
/**
* This is only here because it has to be: "The class should have a no-arg,
* public or protected constructor." Please use the constructor that takes
* arguments.
*/
@Deprecated
public PasswordResetData() {
}
public PasswordResetData(BuiltinUser aBuiltinUser) {
builtinUser = aBuiltinUser;
token = UUID.randomUUID().toString();
long nowInMilliseconds = new Date().getTime();
created = new Timestamp(nowInMilliseconds);
long ONE_MINUTE_IN_MILLISECONDS = 60000;
long futureInMilliseconds = nowInMilliseconds + (SystemConfig.getMinutesUntilPasswordResetTokenExpires() * ONE_MINUTE_IN_MILLISECONDS);
expires = new Timestamp(new Date(futureInMilliseconds).getTime());
reason = Reason.FORGOT_PASSWORD;
}
public boolean isExpired() {
if (this.expires == null) {
return true;
}
long expiresInMilliseconds = this.expires.getTime();
long nowInMilliseconds = new Date().getTime();
return nowInMilliseconds > expiresInMilliseconds;
}
public String getToken() {
return token;
}
public BuiltinUser getBuiltinUser() {
return builtinUser;
}
public Timestamp getCreated() {
return created;
}
public Timestamp getExpires() {
return expires;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Reason getReason() {
return reason;
}
public void setReason(Reason reason) {
this.reason = reason;
}
}