/** * ============================================================================= * * ORCID (R) Open Source * http://orcid.org * * Copyright (c) 2012-2014 ORCID, Inc. * Licensed under an MIT-Style License (MIT) * http://orcid.org/open-source-license * * This copyright and license information (including a link to the full license) * shall be included in its entirety in all copies or substantial portion of * the software. * * ============================================================================= */ package org.orcid.api.notifications.server.delegator.impl; import static org.orcid.core.api.OrcidApiConstants.MAX_NOTIFICATIONS_AVAILABLE; import static org.orcid.core.api.OrcidApiConstants.STATUS_OK_MESSAGE; import java.net.URI; import java.net.URISyntaxException; import java.security.AccessControlException; import java.util.HashMap; import java.util.Map; import javax.annotation.Resource; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import javax.xml.datatype.XMLGregorianCalendar; import org.orcid.api.notifications.server.delegator.NotificationsApiServiceDelegator; import org.orcid.core.exception.OrcidDeprecatedException; import org.orcid.core.exception.OrcidNotFoundException; import org.orcid.core.exception.OrcidNotificationAlreadyReadException; import org.orcid.core.exception.OrcidNotificationException; import org.orcid.core.exception.OrcidNotificationNotFoundException; import org.orcid.core.locale.LocaleManager; import org.orcid.core.manager.NotificationManager; import org.orcid.core.manager.NotificationValidationManager; import org.orcid.core.manager.ProfileEntityCacheManager; import org.orcid.core.manager.ProfileEntityManager; import org.orcid.core.manager.SourceManager; import org.orcid.core.security.visibility.aop.AccessControl; import org.orcid.jaxb.model.message.ScopePathType; import org.orcid.jaxb.model.notification.permission_v2.NotificationPermissions; import org.orcid.jaxb.model.notification.permission_v2.NotificationPermission; import org.orcid.jaxb.model.notification_v2.Notification; import org.orcid.persistence.jpa.entities.ProfileEntity; import org.orcid.utils.DateUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.OAuth2Request; import org.springframework.stereotype.Component; /** * * @author Will Simpson * */ @Component public class NotificationsApiServiceDelegatorImpl implements NotificationsApiServiceDelegator<NotificationPermission> { @Resource private NotificationManager notificationManager; @Resource private ProfileEntityManager profileEntityManager; @Resource private NotificationValidationManager notificationValidationManager; @Resource private SourceManager sourceManager; @Resource private LocaleManager localeManager; @Resource private ProfileEntityCacheManager profileEntityCacheManager; @Value("${org.orcid.core.baseUri}") private String baseUrl; @Override public Response viewStatusText() { return Response.ok(STATUS_OK_MESSAGE).build(); } @Override @AccessControl(requiredScope = ScopePathType.PREMIUM_NOTIFICATION) public Response findPermissionNotifications(String orcid) { // Get the client profile information Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String clientId = null; if (OAuth2Authentication.class.isAssignableFrom(authentication.getClass())) { OAuth2Request authorizationRequest = ((OAuth2Authentication) authentication).getOAuth2Request(); clientId = authorizationRequest.getClientId(); } NotificationPermissions notifications = notificationManager.findPermissionsByOrcidAndClient(orcid, clientId, 0, MAX_NOTIFICATIONS_AVAILABLE); return Response.ok(notifications).build(); } @Override @AccessControl(requiredScope = ScopePathType.PREMIUM_NOTIFICATION) public Response findPermissionNotification(String orcid, Long id) { checkIfProfileDeprecated(orcid); Notification notification = notificationManager.findByOrcidAndId(orcid, id); if (notification != null) { checkSource(notification); return Response.ok(notification).build(); } else { Map<String, String> params = new HashMap<String, String>(); params.put("orcid", orcid); params.put("id", String.valueOf(id)); throw new OrcidNotificationNotFoundException(params); } } private void checkSource(Notification notification) { String notificationSourceId = notification.getSource().retrieveSourcePath(); String currentSourceId = sourceManager.retrieveSourceOrcid(); if (!notificationSourceId.equals(currentSourceId)) { Object params[] = { currentSourceId }; throw new AccessControlException(localeManager.resolveMessage("apiError.notification_accesscontrol.exception", params)); } } @Override @AccessControl(requiredScope = ScopePathType.PREMIUM_NOTIFICATION) public Response flagNotificationAsArchived(String orcid, Long id) throws OrcidNotificationAlreadyReadException { checkIfProfileDeprecated(orcid); Notification notification = notificationManager.flagAsArchived(orcid, id); if (notification == null) { Map<String, String> params = new HashMap<String, String>(); params.put("orcid", orcid); params.put("id", String.valueOf(id)); throw new OrcidNotificationNotFoundException(params); } return Response.ok(notification).build(); } @Override @AccessControl(requiredScope = ScopePathType.PREMIUM_NOTIFICATION) public Response addPermissionNotification(UriInfo uriInfo, String orcid, NotificationPermission notification) { checkIfProfileDeprecated(orcid); notificationValidationManager.validateNotificationPermission(notification); ProfileEntity profile = profileEntityCacheManager.retrieve(orcid); if (profile == null) { throw OrcidNotFoundException.newInstance(orcid); } if (profile.getSendMemberUpdateRequests() != null && !profile.getSendMemberUpdateRequests()) { Map<String, String> params = new HashMap<String, String>(); params.put("orcid", orcid); throw new OrcidNotificationException(params); } Notification createdNotification = notificationManager.createNotification(orcid, notification); try { return Response.created(new URI(uriInfo.getAbsolutePath() + "/" + createdNotification.getPutCode())).build(); } catch (URISyntaxException e) { throw new RuntimeException(localeManager.resolveMessage("apiError.notification_uri.exception"), e); } } private void checkIfProfileDeprecated(String orcid) { ProfileEntity entity = profileEntityManager.findByOrcid(orcid); if (entity != null && profileEntityManager.isProfileDeprecated(orcid)) { StringBuffer primary = new StringBuffer(baseUrl).append("/").append(entity.getPrimaryRecord().getId()); Map<String, String> params = new HashMap<String, String>(); params.put(OrcidDeprecatedException.ORCID, primary.toString()); if (entity.getDeprecatedDate() != null) { XMLGregorianCalendar calendar = DateUtils.convertToXMLGregorianCalendar(entity.getDeprecatedDate()); params.put(OrcidDeprecatedException.DEPRECATED_DATE, calendar.toString()); } throw new OrcidDeprecatedException(params); } } }