Skip to content

Commit

Permalink
feat: Implement Space news target auto creation listener in order to …
Browse files Browse the repository at this point in the history
…create space news target when a space is created - EXO-73039 - Meeds-io/MIPs#129
  • Loading branch information
azayati committed Sep 27, 2024
1 parent dfb2c1a commit 2660b0a
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* This file is part of the Meeds project (https://meeds.io/).
*
* Copyright (C) 2020 - 2024 Meeds Association [email protected]
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package io.meeds.news.listener;

import java.util.Map;

import org.exoplatform.commons.api.settings.ExoFeatureService;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.security.ConversationState;
import org.exoplatform.services.security.Identity;
import org.exoplatform.social.core.space.SpaceListenerPlugin;
import org.exoplatform.social.core.space.model.Space;
import org.exoplatform.social.core.space.spi.SpaceLifeCycleEvent;

import io.meeds.news.rest.NewsTargetingEntity;
import io.meeds.news.service.NewsTargetingService;

public class SpaceNewsTargetAutoCreationListener extends SpaceListenerPlugin {

private static final Log LOG =
ExoLogger.getLogger(SpaceNewsTargetAutoCreationListener.class);

private NewsTargetingService newsTargetingService;

private ExoFeatureService featureService;

private static final String SPACE_NEWS_TARGET_AUTO_CREATION_FEATURE = "spaceNewsTargetAutoCreation";

public SpaceNewsTargetAutoCreationListener(NewsTargetingService newsTargetingService, ExoFeatureService featureService) {
this.newsTargetingService = newsTargetingService;
this.featureService = featureService;
}

@Override
public void spaceCreated(SpaceLifeCycleEvent event) {
if (featureService.isActiveFeature(SPACE_NEWS_TARGET_AUTO_CREATION_FEATURE)) {
Identity currentIdentity = ConversationState.getCurrent().getIdentity();
Space space = event.getSpace();
NewsTargetingEntity spaceNewsTargetEntity = new NewsTargetingEntity();
spaceNewsTargetEntity.setName(space.getDisplayName());
spaceNewsTargetEntity.setProperties(Map.of("label", space.getDisplayName(), "permissions", "space:" + space.getId()));
try {
newsTargetingService.createNewsTarget(spaceNewsTargetEntity, currentIdentity, false);
} catch (Exception e) {
LOG.warn("Can't create space {} news target", space.getPrettyName());
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ void deleteTargetByName(String targetName,
* Gets the {@link List} of {@link News} targets linked to a given
* {@link News}
*
* @param news {@link News} for which targets to be
* retrieved
* @param news {@link News} for which targets to be retrieved
* @return {@link List} of {@link News} targets by {@link News} news object
*/
List<String> getTargetsByNews(News news);
Expand Down Expand Up @@ -127,6 +126,23 @@ Metadata createNewsTarget(NewsTargetingEntity newsTargetingEntity,
org.exoplatform.services.security.Identity currentIdentity) throws IllegalArgumentException,
IllegalAccessException;

/**
* Create news target
*
* @param newsTargetingEntity {@link News} TargetingEntity
* @param currentIdentity current {@link Identity} attempting to create
* {@link News} target
* @param checkPermissions true if permissions are checked
* @return created {@link News} target {@link Metadata}
* @throws IllegalArgumentException when user creates a {@link News} target
* that already exists
* @throws IllegalAccessException when user doesn't have access to create
* {@link News} target
*/
Metadata createNewsTarget(NewsTargetingEntity newsTargetingEntity,
org.exoplatform.services.security.Identity currentIdentity,
boolean checkPermissions) throws IllegalArgumentException, IllegalAccessException;

/**
* Update news target
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
Expand All @@ -48,9 +51,6 @@
import io.meeds.news.rest.NewsTargetingPermissionsEntity;
import io.meeds.news.service.NewsTargetingService;
import io.meeds.news.utils.NewsUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

/**
* Service managing News Targeting
Expand Down Expand Up @@ -118,7 +118,7 @@ public List<NewsTargetingEntity> getAllowedTargets(org.exoplatform.services.secu
@Override
public void deleteTargetByName(String targetName,
org.exoplatform.services.security.Identity currentIdentity) throws IllegalAccessException {
if (currentIdentity != null && !NewsUtils.canManageNewsPublishTargets(currentIdentity)) {
if (!NewsUtils.canManageNewsPublishTargets(currentIdentity)) {
throw new IllegalArgumentException("User " + currentIdentity.getUserId()
+ " not authorized to delete news target with name " + targetName);
}
Expand All @@ -129,7 +129,10 @@ public void deleteTargetByName(String targetName,

@Override
public List<String> getTargetsByNews(News news) {
NewsTargetObject newsTargetObject = new NewsTargetObject(NewsUtils.NEWS_METADATA_OBJECT_TYPE, news.getId(), null, Long.parseLong(news.getSpaceId()));
NewsTargetObject newsTargetObject = new NewsTargetObject(NewsUtils.NEWS_METADATA_OBJECT_TYPE,
news.getId(),
null,
Long.parseLong(news.getSpaceId()));
List<MetadataItem> newsTargets = metadataService.getMetadataItemsByMetadataTypeAndObject(METADATA_TYPE.getName(),
newsTargetObject);
return newsTargets.stream().map(MetadataItem::getMetadata).map(Metadata::getName).toList();
Expand All @@ -144,14 +147,21 @@ public void saveNewsTarget(News news,
if (!NewsUtils.canPublishNews(news.getSpaceId(), currentIdentity)) {
throw new IllegalAccessException("User " + currentUserId + " not authorized to save news targets");
}
NewsTargetObject newsTargetObject = new NewsTargetObject(NewsUtils.NEWS_METADATA_OBJECT_TYPE, news.getId(), null, Long.parseLong(news.getSpaceId()));
NewsTargetObject newsTargetObject = new NewsTargetObject(NewsUtils.NEWS_METADATA_OBJECT_TYPE,
news.getId(),
null,
Long.parseLong(news.getSpaceId()));
Identity currentSocIdentity = identityManager.getOrCreateIdentity(OrganizationIdentityProvider.NAME, currentUserId);
Map<String, String> properties = new LinkedHashMap<>();
properties.put(NewsUtils.DISPLAYED_STATUS, String.valueOf(displayed));
targets.stream().forEach(targetName -> {
try {
MetadataKey metadataKey = new MetadataKey(NewsTargetingService.METADATA_TYPE.getName(), targetName, 0);
metadataService.createMetadataItem(newsTargetObject, metadataKey, properties, Long.parseLong(currentSocIdentity.getId()), false);
metadataService.createMetadataItem(newsTargetObject,
metadataKey,
properties,
Long.parseLong(currentSocIdentity.getId()),
false);
} catch (ObjectAlreadyExistsException e) {
LOG.warn("Targets with name {} is already associated to object {}. Ignore error since it will not affect result.",
targetName,
Expand All @@ -174,7 +184,10 @@ public List<MetadataItem> getNewsTargetItemsByTargetName(String targetName, long

@Override
public void deleteNewsTargets(News news) {
NewsTargetObject newsTargetObject = new NewsTargetObject(NewsUtils.NEWS_METADATA_OBJECT_TYPE, news.getId(), null, Long.parseLong(news.getSpaceId()));
NewsTargetObject newsTargetObject = new NewsTargetObject(NewsUtils.NEWS_METADATA_OBJECT_TYPE,
news.getId(),
null,
Long.parseLong(news.getSpaceId()));
metadataService.deleteMetadataItemsByMetadataTypeAndObject(METADATA_TYPE.getName(), newsTargetObject);
}

Expand All @@ -191,13 +204,21 @@ public void deleteNewsTargets(News news, String currentUserId) throws IllegalAcc
public Metadata createNewsTarget(NewsTargetingEntity newsTargetingEntity,
org.exoplatform.services.security.Identity currentIdentity) throws IllegalArgumentException,
IllegalAccessException {
return createNewsTarget(newsTargetingEntity, currentIdentity, true);
}

@Override
public Metadata createNewsTarget(NewsTargetingEntity newsTargetingEntity,
org.exoplatform.services.security.Identity currentIdentity,
boolean withPermissions) throws IllegalArgumentException, IllegalAccessException {
if (withPermissions && !NewsUtils.canManageNewsPublishTargets(currentIdentity)) {
throw new IllegalAccessException("User " + currentIdentity.getUserId() + " not authorized to create news targets");
}
Identity identity = identityManager.getOrCreateIdentity(OrganizationIdentityProvider.NAME, currentIdentity.getUserId());
long userIdentityId = identity == null ? 0 : Long.parseLong(identity.getId());
Metadata metadata = fromEntity(newsTargetingEntity);
metadata.setCreatorId(userIdentityId);
if (!NewsUtils.canManageNewsPublishTargets(currentIdentity)) {
throw new IllegalAccessException("User " + currentIdentity.getUserId() + " not authorized to create news targets");
}

MetadataKey targetMetadataKey = new MetadataKey(METADATA_TYPE.getName(), metadata.getName(), 0);
Metadata storedMetadata = metadataService.getMetadataByKey(targetMetadataKey);
if (storedMetadata != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@
<import>war:/conf/news/metadata-plugins-configuration.xml</import>
<import>war:/conf/news/gamification-configuration.xml</import>
<import>war:/conf/news/ckeditor-configuration.xml</import>
<import>war:/conf/news/feature-flags-configuration.xml</import>

</configuration>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
* This file is part of the Meeds project (https://meeds.io/).
*
* Copyright (C) 2024 Meeds Association [email protected]
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-->
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.exoplatform.org/xml/ns/kernel_1_3.xsd http://www.exoplatform.org/xml/ns/kernel_1_3.xsd"
xmlns="http://www.exoplatform.org/xml/ns/kernel_1_3.xsd">
<component>
<key>ContentFeatureProperties</key>
<type>org.exoplatform.container.ExtendedPropertyConfigurator</type>
<init-params>
<properties-param>
<name>ContentFeatureProperties</name>
<description>Content Feature enablement flag</description>
<property name="exo.feature.spaceNewsTargetAutoCreation.enabled" value="${exo.feature.spaceNewsTargetAutoCreation.enabled:false}"/>
</properties-param>
</init-params>
</component>
</configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,14 @@
</init-params>
</component-plugin>
</external-component-plugins>

<external-component-plugins>
<target-component>org.exoplatform.social.core.space.spi.SpaceService</target-component>
<component-plugin>
<name>content.listeners.social.space</name>
<set-method>addSpaceListener</set-method>
<type>io.meeds.news.listener.SpaceNewsTargetAutoCreationListener</type>
<description>Create a space news when a new space is created</description>
</component-plugin>
</external-component-plugins>
</configuration>

0 comments on commit 2660b0a

Please sign in to comment.