diff --git a/kudos-services/src/main/java/io/meeds/kudos/listener/KudosSentActivityGeneratorListener.java b/kudos-services/src/main/java/io/meeds/kudos/listener/KudosSentActivityGeneratorListener.java index 12e786fdc..9b3a80503 100644 --- a/kudos-services/src/main/java/io/meeds/kudos/listener/KudosSentActivityGeneratorListener.java +++ b/kudos-services/src/main/java/io/meeds/kudos/listener/KudosSentActivityGeneratorListener.java @@ -72,8 +72,7 @@ public void onEvent(Event event) throws Exception { // NOSO Kudos kudos = event.getData(); KudosService kudosService = event.getSource(); - if (KudosEntityType.valueOf(kudos.getEntityType()) == KudosEntityType.ACTIVITY - || KudosEntityType.valueOf(kudos.getEntityType()) == KudosEntityType.COMMENT) { + if (kudosService.isActivityComment(kudos)) { String activityId = kudos.getEntityId(); try { String parentCommentId = null; diff --git a/kudos-services/src/main/java/io/meeds/kudos/service/KudosService.java b/kudos-services/src/main/java/io/meeds/kudos/service/KudosService.java index 05c9560ad..11aee5889 100644 --- a/kudos-services/src/main/java/io/meeds/kudos/service/KudosService.java +++ b/kudos-services/src/main/java/io/meeds/kudos/service/KudosService.java @@ -60,6 +60,7 @@ import org.exoplatform.social.core.manager.ActivityManager; import org.exoplatform.social.core.manager.IdentityManager; import org.exoplatform.social.core.space.model.Space; +import org.exoplatform.social.core.space.spi.SpaceService; import io.meeds.kudos.model.AccountSettings; import io.meeds.kudos.model.GlobalSettings; @@ -97,6 +98,9 @@ public class KudosService { @Autowired private KudosStorage kudosStorage; + @Autowired + private SpaceService spaceService; + @Autowired private SettingService settingService; @@ -179,6 +183,14 @@ public Kudos createKudos(Kudos kudos, String currentUser) throws IllegalAccessEx if (StringUtils.equals(currentUser, kudos.getReceiverId())) { throw new IllegalAccessException("User with username '" + currentUser + "' is not authorized to send kudos to himseld!"); } + if (StringUtils.isNotBlank(kudos.getSpacePrettyName())) { + Space space = getSpace(kudos.getSpacePrettyName()); + if (space == null) { + throw new ObjectNotFoundException("Space not found"); + } else if (!canSendKudosInSpace(kudos, space, currentUser)) { + throw new IllegalAccessException("User cannot redact on space"); + } + } KudosPeriod currentPeriod = getCurrentKudosPeriod(); Identity senderIdentity = (Identity) checkStatusAndGetReceiver(OrganizationIdentityProvider.NAME, currentUser); @@ -196,7 +208,11 @@ public Kudos createKudos(Kudos kudos, String currentUser) throws IllegalAccessEx if (receiverObject instanceof Identity identity) { kudos.setReceiverIdentityId(identity.getId()); } else if (receiverObject instanceof Space space) { - kudos.setReceiverIdentityId(space.getId()); + if (canSendKudosInSpace(kudos, space, currentUser)) { + kudos.setReceiverIdentityId(space.getId()); + } else { + throw new IllegalAccessException("User cannot redact on space"); + } } } @@ -209,6 +225,17 @@ public Kudos createKudos(Kudos kudos, String currentUser) throws IllegalAccessEx return kudosStorage.getKudoById(createdKudos.getTechnicalId()); } + /** + * @param kudos {@link Kudos} to create + * @param space target {@link Space} + * @param username user making the action + * @return true if can redact on space or if is a comment/reply on an existing activity + */ + public boolean canSendKudosInSpace(Kudos kudos, Space space, String username) { + return (isActivityComment(kudos) && spaceService.canViewSpace(space, username)) + || spaceService.canRedactOnSpace(space, username); + } + /** * Deletes a sent kudos * @@ -259,15 +286,23 @@ public void deleteKudosById(long kudosId) throws ObjectNotFoundException { kudosStorage.deleteKudosById(kudosId); } + /** + * @param kudos {@link Kudos} + * @return true if the associated Activity to generate is a comment or a reply + * to a comment, else false + */ + public boolean isActivityComment(Kudos kudos) { + return KudosEntityType.valueOf(kudos.getEntityType()) == KudosEntityType.ACTIVITY + || KudosEntityType.valueOf(kudos.getEntityType()) == KudosEntityType.COMMENT; + } + /** * Stores generated activity for created {@link Kudos} * * @param kudosId {@link Kudos} technical identifier * @param activityId {@link ExoSocialActivity} technical identifier - * @throws Exception when an error happens when broadcasting event or saving - * activityId of Kudos */ - public void updateKudosGeneratedActivityId(long kudosId, long activityId) throws Exception { + public void updateKudosGeneratedActivityId(long kudosId, long activityId) { kudosStorage.saveKudosActivityId(kudosId, activityId); Kudos kudos = kudosStorage.getKudoById(kudosId); listenerService.broadcast(KUDOS_ACTIVITY_EVENT, this, kudos); diff --git a/kudos-services/src/test/java/io/meeds/kudos/service/KudosServiceTest.java b/kudos-services/src/test/java/io/meeds/kudos/service/KudosServiceTest.java index ce83998e2..0e21d4d80 100644 --- a/kudos-services/src/test/java/io/meeds/kudos/service/KudosServiceTest.java +++ b/kudos-services/src/test/java/io/meeds/kudos/service/KudosServiceTest.java @@ -48,6 +48,7 @@ import org.exoplatform.social.core.identity.provider.SpaceIdentityProvider; import org.exoplatform.social.core.manager.ActivityManager; import org.exoplatform.social.core.manager.IdentityManager; +import org.exoplatform.social.core.space.spi.SpaceService; import io.meeds.kudos.BaseKudosTest; import io.meeds.kudos.dao.KudosDAO; @@ -60,6 +61,7 @@ import io.meeds.kudos.model.KudosPeriodType; import io.meeds.kudos.service.utils.Utils; import io.meeds.kudos.storage.KudosStorage; +import io.meeds.test.kudos.mock.SpaceServiceMock; import lombok.SneakyThrows; @@ -88,6 +90,9 @@ public class KudosServiceTest extends BaseKudosTest { @Autowired KudosService kudosService; + @Autowired + SpaceService spaceService; + @Autowired ActivityManager activityManager; @@ -358,28 +363,69 @@ public void testSendKudos() { public void testSendKudosToSpace() { String spaceRemoteId = "space3"; - Kudos kudos = newKudosDTO(); - kudos.setReceiverType(SpaceIdentityProvider.NAME); - kudos.setReceiverId(spaceRemoteId); - kudos.setReceiverIdentityId(null); + Identity spaceIdentity = identityManager.getOrCreateSpaceIdentity(spaceRemoteId); + KudosPeriod currentKudosPeriod = kudosService.getCurrentKudosPeriod(); + + Kudos kudosToSend = newKudosDTO(); + kudosToSend.setReceiverType(SpaceIdentityProvider.NAME); + kudosToSend.setReceiverId(spaceRemoteId); + kudosToSend.setReceiverIdentityId(null); restartTransaction(); - kudos = kudosService.createKudos(kudos, SENDER_REMOTE_ID); + assertThrows(IllegalAccessException.class, () -> kudosService.createKudos(kudosToSend, SENDER_REMOTE_ID)); - KudosPeriod currentKudosPeriod = kudosService.getCurrentKudosPeriod(); - Identity identity = identityManager.getOrCreateIdentity(SpaceIdentityProvider.NAME, spaceRemoteId); - List list = kudosService.getKudosByPeriodAndReceiver(Long.parseLong(identity.getId()), + List list = kudosService.getKudosByPeriodAndReceiver(Long.parseLong(spaceIdentity.getId()), currentKudosPeriod.getStartDateInSeconds(), currentKudosPeriod.getEndDateInSeconds(), 10); assertNotNull(list); + assertEquals(0, list.size()); + + SpaceServiceMock.setRedactor(SENDER_REMOTE_ID); + Kudos kudos; + try { + kudos = kudosService.createKudos(kudosToSend, SENDER_REMOTE_ID); + } finally { + SpaceServiceMock.setRedactor(null); + } + list = kudosService.getKudosByPeriodAndReceiver(Long.parseLong(spaceIdentity.getId()), + currentKudosPeriod.getStartDateInSeconds(), + currentKudosPeriod.getEndDateInSeconds(), + 10); + assertNotNull(list); assertEquals(1, list.size()); Kudos retrievedKudos = list.get(0); assertEquals(kudos, retrievedKudos); assertEquals(kudos.getTechnicalId(), retrievedKudos.getTechnicalId()); assertEquals(kudos.getTimeInSeconds(), retrievedKudos.getTimeInSeconds()); assertEquals(kudos.hashCode(), retrievedKudos.hashCode()); + + Kudos kudosToSendOnActivity = newKudosDTO(); + kudosToSendOnActivity.setReceiverType(SpaceIdentityProvider.NAME); + kudosToSendOnActivity.setReceiverId(spaceRemoteId); + kudosToSendOnActivity.setReceiverIdentityId(null); + kudosToSendOnActivity.setReceiverIdentityId(null); + kudosToSendOnActivity.setEntityType(KudosEntityType.ACTIVITY.name()); + kudosToSendOnActivity.setEntityId(String.valueOf(retrievedKudos.getActivityId())); + + SpaceServiceMock.setMember(SENDER_REMOTE_ID); + try { + kudosService.createKudos(kudosToSendOnActivity, SENDER_REMOTE_ID); + } finally { + SpaceServiceMock.setMember(null); + } + + list = kudosService.getKudosByPeriodAndReceiver(Long.parseLong(spaceIdentity.getId()), + currentKudosPeriod.getStartDateInSeconds(), + currentKudosPeriod.getEndDateInSeconds(), + 10); + assertNotNull(list); + assertEquals(2, list.size()); + + retrievedKudos = list.get(0); + assertEquals(kudosToSendOnActivity.getEntityType(), retrievedKudos.getEntityType()); + assertEquals(kudosToSendOnActivity.getEntityId(), retrievedKudos.getEntityId()); } @Test diff --git a/kudos-services/src/test/java/io/meeds/test/kudos/mock/SpaceServiceMock.java b/kudos-services/src/test/java/io/meeds/test/kudos/mock/SpaceServiceMock.java index 450d08487..80d9fec82 100644 --- a/kudos-services/src/test/java/io/meeds/test/kudos/mock/SpaceServiceMock.java +++ b/kudos-services/src/test/java/io/meeds/test/kudos/mock/SpaceServiceMock.java @@ -21,6 +21,9 @@ import java.util.List; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; + import org.exoplatform.commons.utils.ListAccess; import org.exoplatform.social.core.application.PortletPreferenceRequiredPlugin; import org.exoplatform.social.core.identity.model.Identity; @@ -33,9 +36,20 @@ import org.exoplatform.social.core.space.spi.SpaceLifeCycleListener; import org.exoplatform.social.core.space.spi.SpaceService; +import lombok.Getter; +import lombok.Setter; + @SuppressWarnings("all") public class SpaceServiceMock implements SpaceService { + @Getter + @Setter + private static String redactor; + + @Getter + @Setter + private static String member; + public Space getSpaceByDisplayName(String spaceDisplayName) { throw new UnsupportedOperationException(); } @@ -129,11 +143,11 @@ public Space updateSpace(Space existingSpace) { throw new UnsupportedOperationException(); } - public Space updateSpaceAvatar(Space existingSpace) { + public Space updateSpaceAvatar(Space existingSpace, String username) { throw new UnsupportedOperationException(); } - public Space updateSpaceBanner(Space existingSpace) { + public Space updateSpaceBanner(Space existingSpace, String username) { throw new UnsupportedOperationException(); } @@ -299,7 +313,7 @@ public void renameSpace(Space space, String newDisplayName) throws SpaceExceptio } - public void renameSpace(String remoteId, Space space, String newDisplayName) throws SpaceException { + public void renameSpace(Space space, String newDisplayName, String remoteId) throws SpaceException { throw new UnsupportedOperationException(); } @@ -373,6 +387,16 @@ public boolean isOnlyLeader(String spaceId, String userId) throws SpaceException throw new UnsupportedOperationException(); } + @Override + public boolean canRedactOnSpace(Space space, String username) { + return space != null && redactor != null && StringUtils.equals(username, redactor); + } + + @Override + public boolean canViewSpace(Space space, String username) { + return space != null && member != null && StringUtils.equals(username, member); + } + public boolean isMember(String spaceId, String userId) throws SpaceException { throw new UnsupportedOperationException(); @@ -554,14 +578,6 @@ public void unregisterSpaceLifeCycleListener(SpaceLifeCycleListener listener) { } - public void setPortletsPrefsRequired(PortletPreferenceRequiredPlugin portletPrefsRequiredPlugin) { - // Nothing to do - } - - public String[] getPortletsPrefsRequired() { - throw new UnsupportedOperationException(); - } - public ListAccess getVisitedSpaces(String remoteId, String appId) { throw new UnsupportedOperationException(); }