-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #18 from samply/feature/email-context
Feature/email context
- Loading branch information
Showing
27 changed files
with
465 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -223,21 +223,54 @@ public class ProjectManagerConst { | |
public final static String REDIRECT_EXPLORER_URL = "explorer-url"; | ||
public final static String QUERY_CONTEXT = "query-context"; | ||
|
||
// Email context properties | ||
// Variables for Email Templates: | ||
public final static String EMAIL_CONTEXT_BRIDGEHEAD = "bridgehead"; | ||
public final static String EMAIL_CONTEXT_PROJECT_CODE = "projectCode"; | ||
public final static String EMAIL_CONTEXT_PROJECT_BRIDGEHEAD_USER_EMAIL = "projectBridgeheadUserEmail"; | ||
public final static String EMAIL_CONTEXT_PROJECT_BRIDGEHEAD_USER_FIRST_NAME = "projectBridgeheadUserFirstName"; | ||
public final static String EMAIL_CONTEXT_PROJECT_BRIDGEHEAD_USER_LAST_NAME = "projectBridgeheadUserLastName"; | ||
public final static String EMAIL_CONTEXT_PROJECT_ROLE = "projectRole"; | ||
public final static String EMAIL_CONTEXT_PROJECT_TYPE = "projectType"; | ||
public final static String EMAIL_CONTEXT_PROJECT_CREATOR_EMAIL = "projectCreatorEmail"; | ||
public final static String EMAIL_CONTEXT_PROJECT_CREATOR_FIRST_NAME = "projectCreatorFirstName"; | ||
public final static String EMAIL_CONTEXT_PROJECT_CREATOR_LAST_NAME = "projectCreatorLastName"; | ||
public final static String EMAIL_CONTEXT_QUERY = "query"; | ||
public final static String EMAIL_CONTEXT_QUERY_LABEL = "queryLabel"; | ||
public final static String EMAIL_CONTEXT_QUERY_DESCRIPTION = "queryDescription"; | ||
public final static String EMAIL_CONTEXT_PROJECT_VIEW_URL = "projectViewUrl"; | ||
public final static String EMAIL_CONTEXT_MESSAGE = "message"; | ||
|
||
public final static String EMAIL_CONTEXT_EMAIL_TO = "emailTo"; | ||
public final static String EMAIL_CONTEXT_EMAIL_TO_FIRST_NAME = "emailToFirstName"; | ||
public final static String EMAIL_CONTEXT_EMAIL_TO_LAST_NAME = "emailToLastName"; | ||
|
||
public final static String[] EMAIL_CONTEXT_VARIABLES = { | ||
EMAIL_CONTEXT_BRIDGEHEAD, | ||
EMAIL_CONTEXT_PROJECT_CODE, | ||
EMAIL_CONTEXT_PROJECT_BRIDGEHEAD_USER_EMAIL, | ||
EMAIL_CONTEXT_PROJECT_BRIDGEHEAD_USER_FIRST_NAME, | ||
EMAIL_CONTEXT_PROJECT_BRIDGEHEAD_USER_LAST_NAME, | ||
EMAIL_CONTEXT_PROJECT_ROLE, | ||
EMAIL_CONTEXT_PROJECT_TYPE, | ||
EMAIL_CONTEXT_PROJECT_CREATOR_EMAIL, | ||
EMAIL_CONTEXT_PROJECT_CREATOR_FIRST_NAME, | ||
EMAIL_CONTEXT_PROJECT_CREATOR_LAST_NAME, | ||
EMAIL_CONTEXT_QUERY, | ||
EMAIL_CONTEXT_QUERY_LABEL, | ||
EMAIL_CONTEXT_QUERY_DESCRIPTION, | ||
EMAIL_CONTEXT_PROJECT_VIEW_URL, | ||
EMAIL_CONTEXT_MESSAGE, | ||
EMAIL_CONTEXT_EMAIL_TO, | ||
EMAIL_CONTEXT_EMAIL_TO_FIRST_NAME, | ||
EMAIL_CONTEXT_EMAIL_TO_LAST_NAME | ||
}; | ||
|
||
// Application Properties | ||
public final static String JWT_GROUPS_CLAIM_PROPERTY = "jwt.groups.claim"; | ||
public final static String JWKS_URI_PROPERTY = "spring.security.oauth2.client.provider.oidc.jwk-set-uri"; | ||
public final static String REGISTERED_BRIDGEHEADS = "bridgeheads"; | ||
public final static String FRONTEND_CONFIG = "frontend"; | ||
public final static String HTTP_PROXY_PREFIX = "http.proxy"; | ||
public final static String HTTPS_PROXY_PREFIX = "https.proxy"; | ||
public final static String EMAIL_CONTEXT = "email"; | ||
public final static String EMAIL_CONTEXT_PREFIX = "email"; | ||
|
||
// Exporter | ||
public final static String SECURITY_ENABLED = "SECURITY_ENABLED"; | ||
|
@@ -350,6 +383,11 @@ public class ProjectManagerConst { | |
public final static String MAX_TIME_TO_WAIT_FOCUS_TASK_IN_MINUTES = "MAX_TIME_TO_WAIT_FOCUS_TASK_IN_MINUTES"; | ||
public final static String DEFAULT_LANGUAGE = "DEFAULT_LANGUAGE"; | ||
|
||
public final static String JWT_GROUPS_CLAIM = "JWT_GROUPS_CLAIM"; | ||
public final static String JWT_EMAIL_CLAIM = "JWT_EMAIL_CLAIM"; | ||
public final static String JWT_FIRST_NAME_CLAIM = "JWT_FIRST_NAME_CLAIM"; | ||
public final static String JWT_LAST_NAME_CLAIM = "JWT_LAST_NAME_CLAIM"; | ||
|
||
public final static String CODER_BASE_URL = "CODER_BASE_URL"; | ||
public final static String CODER_ORGANISATION_ID = "CODER_ORGANISATION_ID"; | ||
public final static String CODER_MEMBER_ID = "CODER_MEMBER_ID"; | ||
|
@@ -385,7 +423,10 @@ public class ProjectManagerConst { | |
public final static String HEAD_SV = "${"; | ||
public final static String BOTTOM_SV = "}"; | ||
public final static String PM_ADMIN_GROUPS_SV = HEAD_SV + PM_ADMIN_GROUPS + BOTTOM_SV; | ||
public final static String JWT_GROUPS_CLAIM_PROPERTY_SV = HEAD_SV + JWT_GROUPS_CLAIM_PROPERTY + BOTTOM_SV; | ||
public final static String JWT_GROUPS_CLAIM_SV = HEAD_SV + JWT_GROUPS_CLAIM + ":groups" + BOTTOM_SV; | ||
public final static String JWT_EMAIL_CLAIM_SV = HEAD_SV + JWT_EMAIL_CLAIM + ":email" + BOTTOM_SV; | ||
public final static String JWT_FIRST_NAME_CLAIM_SV = HEAD_SV + JWT_FIRST_NAME_CLAIM + ":given_name" + BOTTOM_SV; | ||
public final static String JWT_LAST_NAME_CLAIM_SV = HEAD_SV + JWT_LAST_NAME_CLAIM + ":family_name" + BOTTOM_SV; | ||
public final static String JWKS_URI_PROPERTY_SV = HEAD_SV + JWKS_URI_PROPERTY + BOTTOM_SV; | ||
public final static String BK_USER_GROUP_PREFIX_SV = HEAD_SV + BK_USER_GROUP_PREFIX + BOTTOM_SV; | ||
public final static String BK_USER_GROUP_SUFFIX_SV = HEAD_SV + BK_USER_GROUP_SUFFIX + BOTTOM_SV; | ||
|
@@ -487,6 +528,13 @@ public class ProjectManagerConst { | |
public final static String ASYNC_NOTIFICATION_EXECUTOR = "notification"; | ||
public final static String ASYNC_EXPORTER_EXECUTOR = "exporter"; | ||
|
||
// Thymeleaf | ||
public final static int THYMELEAF_PROCESSOR_PRECEDENCE = 1000; | ||
public final static int THYMELEAF_DIALECT_PRECEDENCE = 1000; | ||
public final static String THYMELEAF_DIALECT_NAME = "Project Manager"; | ||
public final static String THYMELEAF_DIALECT_PREFIX = "pm"; | ||
|
||
|
||
// Others | ||
public final static String TEST_EMAIL = "[email protected]"; | ||
public final static String TEST_BRIDGEHEAD = "bridgehead-test"; | ||
|
@@ -495,12 +543,12 @@ public class ProjectManagerConst { | |
public final static int QUERY_CODE_SIZE = 20; | ||
public final static String NO_BRIDGEHEAD = "NONE"; | ||
public final static String THIS_IS_A_TEST = "This is a test"; | ||
public final static String OIDC_EMAIL_CLAIM = "email"; | ||
public final static String CUSTOM_PROJECT_CONFIGURATION = "CUSTOM"; | ||
public final static String EMAIL_SERVICE = "EMAIL_SERVICE"; | ||
public final static String HYPHEN = "minus"; | ||
public final static String HTTP_PROTOCOL_SCHEMA = "http"; | ||
public final static String HTTPS_PROTOCOL_SCHEMA = "https"; | ||
|
||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package de.samply.db.model; | ||
|
||
import jakarta.persistence.*; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Data; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Entity | ||
@Table(name = "user", schema = "samply") | ||
@Data | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
public class User { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Column(name = "id", nullable = false) | ||
private Long id; | ||
|
||
@Column(name = "email", nullable = false, unique = true) | ||
private String email; | ||
|
||
@Column(name = "first_name", nullable = false) | ||
private String firstName; | ||
|
||
@Column(name = "last_name", nullable = false) | ||
private String lastName; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package de.samply.db.repository; | ||
|
||
import de.samply.db.model.User; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.stereotype.Repository; | ||
|
||
import java.util.Optional; | ||
|
||
@Repository | ||
public interface UserRepository extends JpaRepository<User, Long> | ||
{ | ||
Optional<User> findByEmail(String email); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
package de.samply.email; | ||
|
||
import de.samply.app.ProjectManagerConst; | ||
import de.samply.db.model.Project; | ||
import de.samply.db.model.ProjectBridgehead; | ||
import de.samply.db.model.ProjectBridgeheadUser; | ||
import de.samply.db.model.Query; | ||
import de.samply.db.repository.ProjectBridgeheadRepository; | ||
import de.samply.db.repository.ProjectRepository; | ||
import de.samply.db.repository.UserRepository; | ||
import de.samply.frontend.FrontendService; | ||
import de.samply.user.roles.ProjectRole; | ||
import jakarta.validation.constraints.NotNull; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
import java.util.concurrent.atomic.AtomicReference; | ||
import java.util.function.Supplier; | ||
|
||
public class EmailKeyValues { | ||
|
||
private Map<String, String> keyValues = new HashMap<>(); | ||
private final FrontendService frontendService; | ||
private final ProjectBridgeheadRepository projectBridgeheadRepository; | ||
private final ProjectRepository projectRepository; | ||
private final UserRepository userRepository; | ||
|
||
|
||
public EmailKeyValues(FrontendService frontendService, | ||
EmailContext emailContext, | ||
ProjectBridgeheadRepository projectBridgeheadRepository, | ||
ProjectRepository projectRepository, | ||
UserRepository userRepository) { | ||
this.frontendService = frontendService; | ||
this.projectBridgeheadRepository = projectBridgeheadRepository; | ||
this.projectRepository = projectRepository; | ||
this.userRepository = userRepository; | ||
keyValues.putAll(emailContext.getContext()); | ||
} | ||
|
||
public EmailKeyValues add(EmailRecipient emailRecipient) { | ||
if (emailRecipient != null) { | ||
addEmailData(emailRecipient.getEmail(), ProjectManagerConst.EMAIL_CONTEXT_EMAIL_TO, | ||
ProjectManagerConst.EMAIL_CONTEXT_EMAIL_TO_FIRST_NAME, ProjectManagerConst.EMAIL_CONTEXT_EMAIL_TO_LAST_NAME); | ||
emailRecipient.getMessage().ifPresent(this::addMessage); | ||
add(emailRecipient.getRole()); | ||
addProjectBridgeheadOrProject(emailRecipient); | ||
} | ||
return this; | ||
} | ||
|
||
private void addProjectBridgeheadOrProject(EmailRecipient emailRecipient) { | ||
AtomicReference<Optional<ProjectBridgehead>> projectBridgeheadOptional = new AtomicReference<>(Optional.empty()); | ||
AtomicReference<Optional<Project>> projectOptional = new AtomicReference<>(Optional.empty()); | ||
emailRecipient.getProjectCode().ifPresent(projectCode -> | ||
projectRepository.findByCode(projectCode).ifPresent(project -> | ||
emailRecipient.getBridgehead().ifPresent(bridgehead -> | ||
projectBridgeheadRepository.findFirstByBridgeheadAndProject(bridgehead, project).ifPresentOrElse(projectBridgehead -> | ||
projectBridgeheadOptional.set(Optional.of(projectBridgehead)), | ||
() -> projectOptional.set(Optional.of(project)))))); | ||
if (projectBridgeheadOptional.get().isPresent()) { | ||
add(projectBridgeheadOptional.get().get()); | ||
} else if (projectOptional.get().isPresent()) { | ||
add(projectOptional.get().get()); | ||
} else { | ||
emailRecipient.getProjectCode().ifPresent(this::addProjectCode); | ||
emailRecipient.getBridgehead().ifPresent(this::addBridgehead); | ||
} | ||
} | ||
|
||
public EmailKeyValues add(ProjectBridgeheadUser projectBridgeheadUser) { | ||
if (projectBridgeheadUser != null) { | ||
addEmailData(projectBridgeheadUser.getEmail(), ProjectManagerConst.EMAIL_CONTEXT_PROJECT_BRIDGEHEAD_USER_EMAIL, | ||
ProjectManagerConst.EMAIL_CONTEXT_PROJECT_BRIDGEHEAD_USER_FIRST_NAME, ProjectManagerConst.EMAIL_CONTEXT_PROJECT_BRIDGEHEAD_USER_LAST_NAME); | ||
add(projectBridgeheadUser.getProjectRole()); | ||
add(projectBridgeheadUser.getProjectBridgehead()); | ||
} | ||
return this; | ||
} | ||
|
||
public EmailKeyValues add(ProjectRole projectRole) { | ||
addKeyValue(ProjectManagerConst.EMAIL_CONTEXT_PROJECT_ROLE, projectRole.toString()); | ||
return this; | ||
} | ||
|
||
public EmailKeyValues addMessage(String message) { | ||
addKeyValue(ProjectManagerConst.EMAIL_CONTEXT_MESSAGE, message); | ||
return this; | ||
} | ||
|
||
public EmailKeyValues addProjectCode(String projectCode) { | ||
addKeyValue(ProjectManagerConst.EMAIL_CONTEXT_PROJECT_CODE, projectCode); | ||
addKeyValue(ProjectManagerConst.EMAIL_CONTEXT_PROJECT_VIEW_URL, | ||
this.frontendService.fetchUrl(ProjectManagerConst.PROJECT_VIEW_SITE, | ||
Map.of(ProjectManagerConst.PROJECT_CODE, projectCode))); | ||
return this; | ||
} | ||
|
||
public EmailKeyValues add(ProjectBridgehead projectBridgehead) { | ||
if (projectBridgehead != null) { | ||
addBridgehead(projectBridgehead.getBridgehead()); | ||
add(projectBridgehead.getProject()); | ||
} | ||
return this; | ||
} | ||
|
||
public EmailKeyValues addBridgehead(String bridgehead) { | ||
addKeyValue(ProjectManagerConst.EMAIL_CONTEXT_BRIDGEHEAD, bridgehead); | ||
return this; | ||
} | ||
|
||
|
||
public EmailKeyValues add(Project project) { | ||
if (project != null) { | ||
addProjectCode(project.getCode()); | ||
addEmailData(project.getCreatorEmail(), ProjectManagerConst.EMAIL_CONTEXT_PROJECT_CREATOR_EMAIL, | ||
ProjectManagerConst.EMAIL_CONTEXT_PROJECT_CREATOR_FIRST_NAME, ProjectManagerConst.EMAIL_CONTEXT_PROJECT_CREATOR_LAST_NAME); | ||
addKeyValue(ProjectManagerConst.EMAIL_CONTEXT_QUERY, | ||
(project.getQuery().getHumanReadable()) != null ? | ||
project.getQuery().getHumanReadable() : project.getQuery().getQuery()); | ||
addKeyValue(ProjectManagerConst.EMAIL_CONTEXT_PROJECT_TYPE, () -> project.getType().toString()); | ||
add(project.getQuery()); | ||
} | ||
return this; | ||
} | ||
|
||
public EmailKeyValues add(Query query) { | ||
if (query != null) { | ||
addKeyValue(ProjectManagerConst.EMAIL_CONTEXT_QUERY, | ||
(query.getHumanReadable()) != null ? query.getHumanReadable() : query.getQuery()); | ||
addKeyValue(ProjectManagerConst.EMAIL_CONTEXT_QUERY_LABEL, query::getLabel); | ||
addKeyValue(ProjectManagerConst.EMAIL_CONTEXT_QUERY_DESCRIPTION, query::getDescription); | ||
} | ||
return this; | ||
} | ||
|
||
private void addKeyValue(@NotNull String key, Supplier<String> valueGetter) { | ||
String value = valueGetter.get(); | ||
if (value != null) { | ||
keyValues.put(key, value); | ||
} | ||
} | ||
|
||
public void addKeyValue(@NotNull String key, @NotNull String value) { | ||
keyValues.put(key, value); | ||
} | ||
|
||
public Map<String, String> getKeyValues() { | ||
return keyValues; | ||
} | ||
|
||
private void addEmailData(String email, @NotNull String emailKey, @NotNull String emailFirstNameKey, @NotNull String emailLastNameKey) { | ||
if (email != null) { | ||
addKeyValue(emailKey, email); | ||
userRepository.findByEmail(email).ifPresent(user -> { | ||
addKeyValue(emailFirstNameKey, user::getFirstName); | ||
addKeyValue(emailLastNameKey, user::getLastName); | ||
}); | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.