Commit 7b7ec2f4 authored by Matija Obreza's avatar Matija Obreza

Merge branch '459-email-notification-on-publish-unpublish' into 'master'

Resolve "Email notification on publish/unpublish"

Closes #459

See merge request genesys-pgr/genesys-server!440
parents a0e2126a e6f2e22f
......@@ -67,6 +67,8 @@ import org.genesys.filerepository.InvalidRepositoryPathException;
import org.genesys.filerepository.NoSuchRepositoryFileException;
import org.genesys.filerepository.model.RepositoryFile;
import org.genesys.filerepository.service.RepositoryService;
import org.genesys2.server.component.aspect.NotifyOnPublished;
import org.genesys2.server.component.aspect.NotifyForReview;
import org.genesys2.server.component.security.AsAdminInvoker;
import org.genesys2.server.component.security.SecurityUtils;
import org.genesys2.server.exception.InvalidApiUsageException;
......@@ -802,6 +804,7 @@ public class DatasetServiceImpl implements DatasetService {
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR')")
@NotifyOnPublished
public Dataset approveDataset(final Dataset dataset) {
Dataset loaded = getUnpublishedDataset(dataset);
......@@ -876,6 +879,7 @@ public class DatasetServiceImpl implements DatasetService {
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#dataset, 'write')")
@NotifyForReview
public Dataset reviewDataset(final Dataset dataset) {
final Dataset loaded = getUnpublishedDataset(dataset);
......
......@@ -41,6 +41,8 @@ import org.genesys.catalog.model.traits.DescriptorList;
import org.genesys.catalog.persistence.traits.DescriptorListRepository;
import org.genesys.catalog.service.DescriptorListService;
import org.genesys.catalog.service.DescriptorService;
import org.genesys2.server.component.aspect.NotifyOnPublished;
import org.genesys2.server.component.aspect.NotifyForReview;
import org.genesys2.server.component.security.SecurityUtils;
import org.genesys2.server.exception.InvalidApiUsageException;
import org.genesys2.server.exception.NotFoundElement;
......@@ -401,6 +403,7 @@ public class DescriptorListServiceImpl implements DescriptorListService {
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR')")
@NotifyOnPublished
public DescriptorList approveDescriptorList(final DescriptorList descriptorList) {
final DescriptorList loaded = getUnpublishedDescriptorList(descriptorList);
......@@ -429,6 +432,7 @@ public class DescriptorListServiceImpl implements DescriptorListService {
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#descriptorList, 'WRITE')")
@NotifyForReview
public DescriptorList reviewDescriptorList(final DescriptorList descriptorList) {
final DescriptorList loaded = getUnpublishedDescriptorList(descriptorList);
......
/*
* Copyright 2019 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.genesys2.server.component.aspect;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.genesys.blocks.model.AuditedVersionedModel;
import org.genesys.blocks.model.UuidModel;
import org.genesys.catalog.model.dataset.Dataset;
import org.genesys.catalog.model.traits.DescriptorList;
import org.genesys2.server.model.impl.Article;
import org.genesys2.server.model.impl.Subset;
import org.genesys2.server.model.impl.User;
import org.genesys2.server.service.ContentService;
import org.genesys2.server.service.EMailService;
import org.genesys2.server.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
/**
* @author Maxym Borodenko
*/
@Aspect
@Component
public class EmailNotificationAspect {
private final static Logger LOG = LoggerFactory.getLogger(EmailNotificationAspect.class);
@Value("${mail.helpdesk}")
private String helpdeskEmail;
@Value("${frontend.url}")
private String frontendUrl;
@Autowired
private EMailService emailService;
@Autowired
private ContentService contentService;
@Autowired
private UserService userService;
@AfterReturning(value = "execution(public * *(..)) && @annotation(NotifyForReview)", returning = "result")
public void afterSentToReview(final Object result) {
if (result == null) {
LOG.warn("@NotifyOnReview received null object");
return;
}
// Create the root hash
final Map<String, Object> root = new HashMap<>();
if (result instanceof Dataset) {
root.put("publicationType", "dataset");
root.put("title", ((Dataset) result).getTitle());
} else if (result instanceof Subset) {
root.put("publicationType", "subset");
root.put("title", ((Subset) result).getTitle());
} else if (result instanceof DescriptorList) {
root.put("publicationType", "descriptor list");
root.put("title", ((DescriptorList) result).getTitle());
} else {
LOG.warn("@NotifyOnReview not supported for {}", result.getClass());
return;
}
root.put("uuid", ((UuidModel) result).getUuid().toString());
root.put("baseUrl", frontendUrl);
try {
Article article = contentService.getGlobalArticle(ContentService.REVIEW_PUBLICATION, Locale.ENGLISH);
final String mailBody = contentService.processTemplate(article.getBody(), root);
final String mailSubject = article.getTitle();
LOG.debug(">>>{}", mailBody);
emailService.sendMail(mailSubject, mailBody, helpdeskEmail);
} catch (Throwable e) {
LOG.warn("Error processing @NotifyForReview: {}", e.getMessage(), e);
}
}
@AfterReturning(value = "execution(public * *(..)) && @annotation(NotifyOnPublished)", returning = "result")
public void afterPublishing(final Object result) {
if (result == null) {
LOG.warn("@NotifyOnPublished received null object");
return;
}
Long creatorId = ((AuditedVersionedModel) result).getCreatedBy();
if (creatorId == null) {
LOG.warn("Skipping @NotifyOnPublished, no createdBy for {}", result);
return;
}
// Create the root hash
final Map<String, Object> root = new HashMap<>();
if (result instanceof Dataset) {
root.put("publicationType", "dataset");
root.put("title", ((Dataset) result).getTitle());
} else if (result instanceof Subset) {
root.put("publicationType", "subset");
root.put("title", ((Subset) result).getTitle());
} else if (result instanceof DescriptorList) {
root.put("publicationType", "descriptor list");
root.put("title", ((DescriptorList) result).getTitle());
} else {
LOG.warn("@NotifyOnPublished not supported for {}", result.getClass());
return;
}
root.put("uuid", ((UuidModel) result).getUuid().toString());
root.put("baseUrl", frontendUrl);
try {
Article article = contentService.getGlobalArticle(ContentService.PUBLISH_PUBLICATION, LocaleContextHolder.getLocale());
final String mailBody = contentService.processTemplate(article.getBody(), root);
final String mailSubject = article.getTitle();
LOG.debug(">>>{}", mailBody);
User user = userService.getUser(creatorId);
emailService.sendMail(mailSubject, mailBody, user.getEmail());
} catch (Throwable e) {
LOG.warn("Error processing @NotifyForReview: {}", e.getMessage(), e);
}
}
}
/*
* Copyright 2019 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.genesys2.server.component.aspect;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Maxym Borodenko
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotifyForReview {
// marker annotation
}
/*
* Copyright 2019 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.genesys2.server.component.aspect;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Maxym Borodenko
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotifyOnPublished {
// marker annotation
}
......@@ -69,7 +69,9 @@ public interface ContentService {
public final String DELETE_ACCOUNT_SENT = "account-delete-requested";
public final String DELETE_ACCOUNT_CONFIRMED = "account-delete-confirmed";
public final String SMTP_DELETE_ACCOUNT_INPROGRESS = "smtp-delete-account-inprogress";
public final String PUBLISH_PUBLICATION = "publish-published";
public final String REVIEW_PUBLICATION = "publish-for-review";
List<ActivityPost> lastNews();
Page<ActivityPost> allNews(Pageable page);
......
......@@ -39,6 +39,8 @@ import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;
import org.genesys.blocks.security.service.CustomAclService;
import org.genesys.catalog.model.Partner;
import org.genesys2.server.component.aspect.NotifyOnPublished;
import org.genesys2.server.component.aspect.NotifyForReview;
import org.genesys2.server.component.security.SecurityUtils;
import org.genesys2.server.exception.InvalidApiUsageException;
import org.genesys2.server.exception.NotFoundElement;
......@@ -457,6 +459,7 @@ public class SubsetServiceImpl implements SubsetService {
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR')")
@NotifyOnPublished
public Subset approveSubset(final Subset subset) {
final Subset loadedSubset = getUnpublishedSubset(subset);
......@@ -487,6 +490,7 @@ public class SubsetServiceImpl implements SubsetService {
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#subset, 'write')")
@NotifyForReview
public Subset reviewSubset(final Subset subset) {
final Subset loadedSubset = getUnpublishedSubset(subset);
......
......@@ -100,6 +100,7 @@ mail.port=25
mail.user.from=test@localhost
mail.requests.to=test@localhost
mail.helpdesk=helpdesk@genesys-pgr.org
mail.user.password=
mail.user.name=
......
{
"template": true,
"en": {
"title": "New publication submitted",
"body": "## VELOCITY\n<h2><small><a href=\"${baseUrl}\">${baseUrl}</a></small><br />New ${publicationType} submitted</h2>\n\n<p>The ${publicationType} titled \"<b>${title}</b>\" is ready for your review.</p>\n\n<p>Review it at \n\n#if ($publicationType == \"dataset\")\n ${baseUrl}/datasets/${uuid}\n#elseif ($publicationType == \"subset\")\n ${baseUrl}/subsets/${uuid}\n#elseif ($publicationType == \"descriptor list\")\n ${baseUrl}/descriptorlists/${uuid}\n#end\n\n</p>\n\n<p>Thanks,<br />Genesys team</p>\n"
}
}
{
"template": true,
"en": {
"title": "Publication approved",
"body": "## VELOCITY\n<h2><small><a href=\"${baseUrl}\">${baseUrl}</a></small><br />Publication approved</h2>\n\n<p>The ${publicationType} titled \"<b>${title}</b>\" is now published on Genesys.</p>\n\n<p>It is publicly accessible at \n\n#if ($publicationType == \"dataset\")\n${baseUrl}/datasets/${uuid}\n#elseif ($publicationType == \"subset\")\n${baseUrl}/subsets/${uuid}\n#elseif ($publicationType == \"descriptor list\")\n${baseUrl}/descriptorlists/${uuid}\n#end\n\n</p>\n\n<p>Thanks,<br />Genesys team</p>"
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment