InvitationToken.java
/*
* The coLAB project
* Copyright (C) 2021-2024 AlbaSim, MEI, HEIG-VD, HES-SO
*
* Licensed under the MIT License
*/
package ch.colabproject.colab.api.model.token;
import ch.colabproject.colab.api.controller.token.TokenManager;
import ch.colabproject.colab.api.model.project.Project;
import ch.colabproject.colab.api.model.team.TeamMember;
import ch.colabproject.colab.api.model.token.tools.InvitationMessageBuilder;
import ch.colabproject.colab.api.security.permissions.Conditions;
import javax.json.bind.annotation.JsonbTransient;
import javax.persistence.Entity;
import javax.persistence.Index;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
/**
* A token to invite someone to be a team member of a project.
* <p>
* As soon as the token is generated, a team member is linked to it. It allows to specify rights,
* roles and tasks even before the aimed user consumes the token.
*
* @author maxence
*/
@Entity
@Table(
indexes = {
@Index(columnList = "teammember_id"),
}
)
@NamedQuery(
name = "InvitationToken.findByProjectAndRecipient",
query = "SELECT t from InvitationToken t "
+ "WHERE t.teamMember.project.id = :projectId AND t.recipient = :recipient")
@NamedQuery(
name = "InvitationToken.findByTeamMember",
query = "SELECT t from InvitationToken t "
+ "WHERE t.teamMember.id = :teamMemberId")
public class InvitationToken extends Token implements EmailableToken {
private static final long serialVersionUID = 1L;
/**
* Email subject
*/
private static final String EMAIL_SUBJECT = "Invitation to collaborate on a co.LAB project";
// ---------------------------------------------------------------------------------------------
// fields
// ---------------------------------------------------------------------------------------------
/**
* The member of the project
*/
@OneToOne // FetchType.EAGER is fine
@NotNull
@JsonbTransient
private TeamMember teamMember;
/**
* Invitation sender
*/
@Size(max = 255)
@JsonbTransient
private String sender;
/**
* email address to send the invitation to
*/
@Size(max = 255)
@JsonbTransient
private String recipient;
// ---------------------------------------------------------------------------------------------
// getters and setters
// ---------------------------------------------------------------------------------------------
/**
* Get the teamMember for which the invitation is pending.
*
* @return team member
*/
public TeamMember getTeamMember() {
return teamMember;
}
/**
* set the team member this invitation is for
*
* @param teamMember the team member for which this invitation is pending
*/
public void setTeamMember(TeamMember teamMember) {
this.teamMember = teamMember;
}
/**
* Get sender name
*
* @return name of sender
*/
public String getSender() {
return sender;
}
/**
* Set the sender name
*
* @param sender name of the sender
*/
public void setSender(String sender) {
this.sender = sender;
}
/**
* Email address to send the invitation to
*
* @return email address
*/
public String getRecipient() {
return recipient;
}
/**
* Set the email address to send this invitation to
*
* @param recipient recipient email address
*/
public void setRecipient(String recipient) {
this.recipient = recipient;
}
// ---------------------------------------------------------------------------------------------
// helpers
// ---------------------------------------------------------------------------------------------
@Override
public String getRedirectTo() {
if (this.teamMember != null && this.teamMember.getUser() != null) {
// if link from user to project is not set, do not even try to read the project
// as it will lead to access denied exception
Project project = getProject();
if (project != null && project.getId() != null) {
return "/new-project-access/" + project.getId();
}
}
return "";
}
@Override
public boolean consume(TokenManager tokenManager) {
return tokenManager.consumeInvitationToken(teamMember);
}
@Override
public ExpirationPolicy getExpirationPolicy() {
return ExpirationPolicy.ONE_SHOT;
}
// ---------------------------------------------------------------------------------------------
// to build a message
// ---------------------------------------------------------------------------------------------
@JsonbTransient
@Override
public String getSubject() {
return EMAIL_SUBJECT;
}
@Override
public String getEmailBody(String link) {
return InvitationMessageBuilder.build(this, link);
}
// ---------------------------------------------------------------------------------------------
// concerning the whole class
// ---------------------------------------------------------------------------------------------
/**
* If team member is set, return the associated project.
*
* @return the project
*/
@JsonbTransient
public Project getProject() {
if (teamMember != null) {
return teamMember.getProject();
}
return null;
}
@Override
@JsonbTransient
public Conditions.Condition getCreateCondition() {
return new Conditions.IsCurrentUserMemberOfProject(getProject());
}
@Override
public String toString() {
return "InvitationToken{" + "id=" + getId() + ", deletion=" + getDeletionStatus() + '}';
}
}