
com.adobe.cq.social.group.client.endpoints.AbstractCommunityGroupOperationService Maven / Gradle / Ivy
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2013 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/
package com.adobe.cq.social.group.client.endpoints;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.activation.DataSource;
import javax.jcr.Binary;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.ReferencePolicy;
import org.apache.jackrabbit.JcrConstants;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.request.RequestParameter;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.sling.jcr.resource.JcrResourceConstants;
import org.apache.sling.settings.SlingSettingsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.adobe.cq.social.blueprint.api.SiteActivationService;
import com.adobe.cq.social.commons.CollabUtil;
import com.adobe.cq.social.community.api.CommunityConstants;
import com.adobe.cq.social.community.api.CommunityContext;
import com.adobe.cq.social.community.api.CommunityUserGroup;
import com.adobe.cq.social.communityfunctions.api.CommunityFunction;
import com.adobe.cq.social.group.api.GroupConstants;
import com.adobe.cq.social.group.api.GroupException;
import com.adobe.cq.social.group.api.GroupService;
import com.adobe.cq.social.group.api.GroupUtil;
import com.adobe.cq.social.group.bundleactivator.impl.Activator;
import com.adobe.cq.social.group.client.api.CommunityGroup;
import com.adobe.cq.social.group.client.api.CommunityGroupConstants;
import com.adobe.cq.social.group.client.endpoints.impl.CommunityGroupOperationService;
import com.adobe.cq.social.scf.Operation;
import com.adobe.cq.social.scf.OperationException;
import com.adobe.cq.social.scf.OperationExtension;
import com.adobe.cq.social.scf.SocialComponent;
import com.adobe.cq.social.scf.SocialComponentFactory;
import com.adobe.cq.social.scf.SocialComponentFactoryManager;
import com.adobe.cq.social.scf.core.operations.AbstractOperationService;
import com.adobe.cq.social.serviceusers.internal.ServiceUserWrapper;
import com.adobe.cq.social.ugcbase.AsyncReverseReplicator;
import com.day.cq.commons.jcr.JcrUtil;
import com.day.cq.replication.ReplicationActionType;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
/**
* Provides abstract implementation of community group operations. This class can be extended to implement create
* operations for any component that extends the community group.
* @param is a {@link OperationExtension} that will be used as hooks by the extending class.
* @param is a {@link Operation} that is being provided by the extending class.
*/
@Component(metatype = false, componentAbstract = true)
public abstract class AbstractCommunityGroupOperationService
extends AbstractOperationService implements CommunityGroupOperations {
private static final String MSM_SERVICE = "msm-service";
private static final Logger LOG = LoggerFactory.getLogger(CommunityGroupOperationService.class);
private static final String PROPERTY_IMAGE_NAME = "image";
private static final int PARAM_NAME_INDEX = 0;
private static final int PARAM_CLASS_INDEX = 1;
private static final int PARAM_REQUIRED_INDEX = 2;
private static final Object requestParams[][] = {
{CommunityGroupConstants.PROP_COMMUNITY_GROUP_DESCRIPTION, String.class, Boolean.FALSE},
{CommunityGroupConstants.PROP_COMMUNITY_GROUP_NAME, String.class, Boolean.TRUE},
{CommunityGroupConstants.PROP_COMMUNITY_GROUP_TITLE, String.class, Boolean.FALSE},
{CommunityGroupConstants.PROP_COMMUNITY_GROUP_TYPE, String.class, Boolean.FALSE},
{CommunityGroupConstants.PROP_COMMUNITY_GROUP_INVITE, String.class, Boolean.FALSE},
{CommunityGroupConstants.PROP_COMMUNITY_GROUP_BLUEPRINT_ID, String.class, Boolean.TRUE}};
private static final String specialParams[] = {CommunityGroupConstants.PROP_COMMUNITY_GROUP_FILE};
// TODO: Define this value from configuration
private static final int ATTACHMENT_FILE_LIMIT = Integer.MAX_VALUE;
private static final List WHITE_LIST = new ArrayList();
private static final String[] BLACK_LIST = new String[0];
private static final String USER_ADMIN = "user-admin";
private static final String DEFAULT_GROUP_ROOTTEMPLATE_ROOT = "/etc/community/templates/groups";
private static final String DEFAULT_GROUP_TEMPLATE_ROOT = DEFAULT_GROUP_ROOTTEMPLATE_ROOT
+ CommunityConstants.REFERENCE_SUBPATH;
private static final String CUSTOM_GROUP_TEMPLATE_ROOT = DEFAULT_GROUP_ROOTTEMPLATE_ROOT
+ CommunityConstants.CUSTOM_SUBPATH;
private static final String PATH = "path";
private static final String NAME = "name";
// delimiters to split the invited id list
private final String delimiters = "[\\s,;]";
/** Social Component Factory Manager. */
@Reference
private SocialComponentFactoryManager componentFactoryManager;
@Reference
private AsyncReverseReplicator replicator;
@Reference
private GroupService groupService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY, policy = ReferencePolicy.STATIC)
private SlingRepository repository;
@Reference
private ServiceUserWrapper serviceUserWrapper;
@Reference
private ResourceResolverFactory resourceResolverFactory;
@Reference
protected SlingSettingsService settingsService;
/**
* This is needed to get a ResourceResolverFactory tied to this bundle's service user configurations. The Felix DS
* implementation will inject a ResourceResolverFactory tied to the bundle of the concrete implementation of this
* component.
*/
private ResourceResolverFactory bundleLocalResourceResolverFactory;
private void cleanupFailure(final Session session) {
try {
if (LOG.isDebugEnabled()) {
LOG.debug("Failure cleanup invoked.", new Throwable());
}
session.refresh(false);
} catch (final RepositoryException e) {
LOG.info("Failed to refresh the session", e);
}
}
private ResourceResolverFactory getBundleLocalResourceResolverFactory() {
if (bundleLocalResourceResolverFactory == null) {
bundleLocalResourceResolverFactory = Activator.getService(ResourceResolverFactory.class);
}
return bundleLocalResourceResolverFactory;
}
private ServiceUserWrapper getServiceUserWrapper() {
if (serviceUserWrapper == null) {
serviceUserWrapper = Activator.getService(ServiceUserWrapper.class);
}
return serviceUserWrapper;
}
@Override
public Resource create(final SlingHttpServletRequest request) throws OperationException {
final Resource resource = request.getResource();
final ResourceResolver resolver = resource.getResourceResolver();
final Session session = resource.getResourceResolver().adaptTo(Session.class);
if (!GroupUtil.isGroupAdmin(session, resource)) {
throw new OperationException("No permission to create a community group.",
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
// Get the other definition/configuration properties of the site
final Map props = new HashMap();
try {
getDefaultProperties(request, props, true);
getCustomProperties(request, props, session);
} catch (final RepositoryException e) {
throw new OperationException("Failed to obtain community group parameters.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
// add creator to the invite list
String invites = (String) props.get(CommunityGroupConstants.PROP_COMMUNITY_GROUP_INVITE);
if (!StringUtils.isEmpty(invites)) {
invites += "," + session.getUserID();
} else {
invites = session.getUserID();
}
props.put(CommunityGroupConstants.PROP_COMMUNITY_GROUP_INVITE, invites);
props.put(CommunityGroupConstants.PROP_COMMUNITY_GROUP_CREATOR, session.getUserID());
// Get the name of the new site
final String name = (String) props.get(CommunityGroupConstants.PROP_COMMUNITY_GROUP_NAME);
final PageManager pm = resolver.adaptTo(PageManager.class);
final Page groupPage = pm.getContainingPage(resource);
final String root = groupPage.getPath();
final Resource groupPageResource = resolver.getResource(root);
if (!GroupUtil.validateGroupName(resolver, name, root)) {
throw new OperationException("Community group name is badly formatted " + name,
HttpServletResponse.SC_BAD_REQUEST);
}
// get the attachment images
final List attachments =
getAttachmentsFromRequest(request, CommunityGroupConstants.PROP_COMMUNITY_GROUP_FILE);
// create the community group
// need to open a userAdminSession, since we allow every login user to create groups
ResourceResolver userAdminResolver = null;
try {
userAdminResolver =
getServiceUserWrapper().getServiceResourceResolver(getBundleLocalResourceResolverFactory(),
Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, (Object) USER_ADMIN));
return create(groupPageResource, name, props, attachments, userAdminResolver.adaptTo(Session.class));
} catch (final LoginException e) {
cleanupFailure(session);
throw new OperationException("Failed to join community group.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} finally {
if (userAdminResolver != null) {
userAdminResolver.close();
}
}
}
protected Resource create(final Resource root, final String name, final Map properties,
final List attachments, final Session session) throws OperationException {
try {
final Map authInfo = new HashMap();
authInfo.put(JcrResourceConstants.AUTHENTICATION_INFO_SESSION, session);
final ResourceResolver resolver = resourceResolverFactory.getResourceResolver(authInfo);
final U createOperation = getCreateOperation();
performBeforeActions(createOperation, session, root, properties);
final String groupPath = root.getPath() + "/" + name;
final CommunityContext context = root.adaptTo(CommunityContext.class);
String nuggetRoot = context != null ? context.getSitePayloadPath() : "/var/community/publish";
nuggetRoot =
StringUtils.replace(nuggetRoot, CommunityGroupConstants.ROOT_FOR_PUBLISH_COMMUNITY_NUGGETS,
CommunityGroupConstants.ROOT_FOR_CREATE_COMMUNITY_NUGGETS);
final String nuggetPath = nuggetRoot + groupPath;
final Node folder = JcrUtil.createPath(nuggetPath, "sling:Folder", session);
final Node nugget =
folder.addNode(SiteActivationService.REPLICATE_NODE_NAME, SiteActivationService.REPLICATE_NODE_TYPE);
nugget.setProperty(SiteActivationService.REPLICATE_PROPERTY_PATH, root.getPath());
nugget.setProperty(SiteActivationService.REPLICATE_PROPERTY_ACTION,
CommunityGroupConstants.ACTION_TYPE_CREATE_COMMUNITY_GROUP);
nugget.setProperty(GroupConstants.PROPERTY_FORM_PAYLOAD, nuggetPath);
for (final Entry property : properties.entrySet()) {
final String key = property.getKey();
if (!isSpecialRequestParam(key)) {
JcrUtil.setProperty(nugget, key, property.getValue());
}
}
// add image node if one has been uploaded
final boolean hasImage = !attachments.isEmpty();
if (hasImage) {
final DataSource ds = attachments.get(0);
addImage(nuggetPath, resolver, ds.getInputStream(), ds.getContentType());
}
session.save();
// reverse replicate nugget node
if (resolver.getResource(nuggetPath) != null && settingsService != null
&& settingsService.getRunModes().contains("publish")) {
final List paths = new ArrayList(2);
paths.add(nuggetPath);
if (hasImage) {
paths.add(nuggetPath + "/" + PROPERTY_IMAGE_NAME);
}
replicator.reverseReplicate(ReplicationActionType.ACTIVATE, paths);
}
performAfterActions(createOperation, session, null, properties);
/* Perform the wait with the msm-service as the user admin session we have can't read content. */
ResourceResolver msmResolver = null;
try {
msmResolver =
getServiceUserWrapper().getServiceResourceResolver(getBundleLocalResourceResolverFactory(),
Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, (Object) MSM_SERVICE));
GroupUtil.waitForPageCreation(msmResolver, groupPath, 120 * 1000, 15 * 1000);
} finally {
if (msmResolver != null) {
msmResolver.close();
}
}
return root.getResourceResolver().resolve(groupPath + "/" + CommunityGroupConstants.CONFIG_NODE_NAME);
} catch (final OperationException e) {
cleanupFailure(session);
throw e;
} catch (final Exception e) {
cleanupFailure(session);
throw new OperationException("Failed to create community group.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
@Override
public boolean approveJoin(final ResourceResolver resolver, final CommunityGroup group) throws OperationException {
// anonymous cannot join
final Session session = resolver.adaptTo(Session.class);
if (StringUtils.endsWithIgnoreCase(session.getUserID(), "anonymous")) {
return false;
}
// auto approve the request to join open community groups
if (group != null && GroupConstants.TYPE_OPEN.equals(group.getType())) {
return true;
}
// currently reject all other requests
return false;
}
@Override
public Resource join(final SlingHttpServletRequest request) throws OperationException {
final Resource resource = request.getResource();
final ResourceResolver resolver = resource.getResourceResolver();
final Session session = resource.getResourceResolver().adaptTo(Session.class);
final String groupUrl = request.getParameter(CommunityGroupConstants.PROP_COMMUNITY_GROUP_PATH);
if (StringUtils.isBlank(groupUrl)) {
return null;
}
final Resource groupPageResource = resolver.resolve(groupUrl);
final CommunityGroup group =
(CommunityGroup) this.getCommunityGroupComponentForResource(groupPageResource, request);
return join(resolver, group, session);
}
protected Resource join(final ResourceResolver resolver, final CommunityGroup group, final Session session)
throws OperationException {
if (resolver == null || group == null || session == null) {
return null;
}
if (!approveJoin(resolver, group)) {
throw new OperationException("Deny " + session.getUserID() + "'s request to join community group "
+ group.getName(), HttpServletResponse.SC_NOT_ACCEPTABLE);
}
ResourceResolver userAdminResolver = null;
try {
final String authorizableId = session.getUserID();
userAdminResolver =
getServiceUserWrapper().getServiceResourceResolver(getBundleLocalResourceResolverFactory(),
Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, (Object) USER_ADMIN));
groupService.addGroupMember(userAdminResolver, group.getMemberGroupId(), authorizableId);
resolver.adaptTo(Session.class).refresh(false);
resolver.refresh();
} catch (final LoginException e) {
cleanupFailure(session);
throw new OperationException("Failed to login as user admin.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (final GroupException e) {
cleanupFailure(session);
throw new OperationException("Failed to join community group.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (final RepositoryException e) {
cleanupFailure(session);
throw new OperationException("Failed to join community group.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} finally {
if (userAdminResolver != null) {
userAdminResolver.close();
}
}
return group.getResource();
}
@Override
public Resource leave(final SlingHttpServletRequest request) throws OperationException {
final Resource resource = request.getResource();
final ResourceResolver resolver = resource.getResourceResolver();
final Session session = resource.getResourceResolver().adaptTo(Session.class);
final String groupUrl = request.getParameter(CommunityGroupConstants.PROP_COMMUNITY_GROUP_PATH);
if (StringUtils.isBlank(groupUrl)) {
return null;
}
final Resource groupPageResource = resolver.resolve(groupUrl);
final CommunityGroup group =
(CommunityGroup) this.getCommunityGroupComponentForResource(groupPageResource, request);
return leave(resolver, group, session);
}
protected Resource leave(final ResourceResolver resolver, final CommunityGroup group, final Session session)
throws OperationException {
if (resolver == null || group == null || session == null) {
return null;
}
ResourceResolver userAdminResolver = null;
try {
final String authorizableId = session.getUserID();
userAdminResolver =
getServiceUserWrapper().getServiceResourceResolver(getBundleLocalResourceResolverFactory(),
Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, (Object) USER_ADMIN));
groupService.removeGroupMember(userAdminResolver, group.getMemberGroupId(), authorizableId);
resolver.adaptTo(Session.class).refresh(false);
resolver.refresh();
} catch (final LoginException e) {
cleanupFailure(session);
throw new OperationException("Failed to login as user admin.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (final GroupException e) {
cleanupFailure(session);
throw new OperationException("Failed to join community group.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (final RepositoryException e) {
cleanupFailure(session);
throw new OperationException("Failed to join community group.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} finally {
if (userAdminResolver != null) {
userAdminResolver.close();
}
}
return group.getResource();
}
@Override
public Resource invite(final SlingHttpServletRequest request) throws OperationException {
final Resource resource = request.getResource();
final ResourceResolver resolver = resource.getResourceResolver();
final Session session = resource.getResourceResolver().adaptTo(Session.class);
final String[] inviteList = request.getParameterValues(CommunityGroupConstants.PROP_COMMUNITY_GROUP_USERS);
final CommunityContext context = resource.adaptTo(CommunityContext.class);
final Resource groupPageResource = resolver.resolve(context.getCommunityGroupPath());
final CommunityGroup group =
(CommunityGroup) this.getCommunityGroupComponentForResource(groupPageResource, request);
invite(resolver, group, inviteList, context, session);
return resource;
}
protected void invite(final ResourceResolver resolver, final CommunityGroup group, final String[] inviteList,
final CommunityContext context, final Session session) throws OperationException {
if (resolver == null || group == null || session == null) {
return;
}
if (!GroupUtil.canInviteGroupMember(resolver, context)) {
throw new OperationException("Deny " + session.getUserID()
+ "'s request to invite users to community group " + group.getName(),
HttpServletResponse.SC_NOT_ACCEPTABLE);
}
ResourceResolver userAdminResolver = null;
try {
userAdminResolver =
getServiceUserWrapper().getServiceResourceResolver(getBundleLocalResourceResolverFactory(),
Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, (Object) USER_ADMIN));
groupService.addGroupMembers(userAdminResolver, group.getMemberGroupId(), inviteList);
session.refresh(false);
resolver.refresh();
} catch (final LoginException e) {
cleanupFailure(session);
throw new OperationException("Failed to login as user admin.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (final GroupException e) {
cleanupFailure(session);
throw new OperationException("Failed to join community group.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (final RepositoryException e) {
cleanupFailure(session);
throw new OperationException("Failed to join community group.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} finally {
if (userAdminResolver != null) {
userAdminResolver.close();
}
}
}
@Override
public Resource uninvite(final SlingHttpServletRequest request) throws OperationException {
final Resource resource = request.getResource();
final ResourceResolver resolver = resource.getResourceResolver();
final Session session = resource.getResourceResolver().adaptTo(Session.class);
final String invite = request.getParameter(CommunityGroupConstants.PROP_COMMUNITY_GROUP_USERS);
if (StringUtils.isEmpty(invite)) {
return null;
}
final String[] inviteList = invite.split(delimiters);
final CommunityContext context = resource.adaptTo(CommunityContext.class);
final Resource groupPageResource = resolver.resolve(context.getCommunityGroupPath());
final CommunityGroup group =
(CommunityGroup) this.getCommunityGroupComponentForResource(groupPageResource, request);
uninvite(resolver, group, inviteList, context, session);
return resource;
}
protected void uninvite(final ResourceResolver resolver, final CommunityGroup group, final String[] inviteList,
final CommunityContext context, final Session session) throws OperationException {
if (resolver == null || group == null || session == null) {
return;
}
if (!GroupUtil.canInviteGroupMember(resolver, context)) {
throw new OperationException("Deny " + session.getUserID()
+ "'s request to invite users to community group " + group.getName(),
HttpServletResponse.SC_NOT_ACCEPTABLE);
}
ResourceResolver userAdminResolver = null;
try {
userAdminResolver =
getServiceUserWrapper().getServiceResourceResolver(getBundleLocalResourceResolverFactory(),
Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, (Object) USER_ADMIN));
groupService.removeGroupMembers(userAdminResolver, group.getMemberGroupId(), inviteList);
session.refresh(false);
resolver.refresh();
} catch (final LoginException e) {
cleanupFailure(session);
throw new OperationException("Failed to login as user admin.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (final GroupException e) {
cleanupFailure(session);
throw new OperationException("Failed to uninvite member from community group.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (final RepositoryException e) {
cleanupFailure(session);
throw new OperationException("Failed to uninvite member from community group.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} finally {
if (userAdminResolver != null) {
userAdminResolver.close();
}
}
}
@Override
public Resource promoteMember(final SlingHttpServletRequest request) throws OperationException {
final Resource resource = request.getResource();
final ResourceResolver resolver = resource.getResourceResolver();
final Session session = resource.getResourceResolver().adaptTo(Session.class);
final String[] inviteList = request.getParameterValues(CommunityGroupConstants.PROP_COMMUNITY_GROUP_USERS);
final CommunityContext context = resource.adaptTo(CommunityContext.class);
final Resource groupPageResource = resolver.resolve(context.getCommunityGroupPath());
final CommunityGroup group =
(CommunityGroup) this.getCommunityGroupComponentForResource(groupPageResource, request);
LOG.debug("promoteMember: resource {} groupPageResource {}", resource, groupPageResource);
LOG.debug("promoteMember: communityGroupPath {}", context.getCommunityGroupPath());
promoteMember(resolver, group, context, inviteList, session);
return resource;
}
protected void promoteMember(final ResourceResolver resolver, final CommunityGroup group,
final CommunityContext context, final String[] inviteList, final Session session) throws OperationException {
final String groupAdminID = context.getSiteUserGroupName(CommunityUserGroup.GROUP_ADMIN);
if (LOG.isDebugEnabled()) {
LOG.debug("promoteMember: {} to {}", Arrays.asList(inviteList), groupAdminID);
}
if (resolver == null) {
throw new IllegalArgumentException("resolver not allowed to be null");
}
if (group == null) {
throw new IllegalArgumentException("group not allowed to be null");
}
if (session == null) {
throw new IllegalArgumentException("session not allowed to be null");
}
if (!GroupUtil.canPromoteGroupMember(resolver, context)) {
throw new OperationException("Deny " + session.getUserID()
+ "'s request to invite users to community group " + group.getName(),
HttpServletResponse.SC_NOT_ACCEPTABLE);
}
LOG.debug("promoteMember: {} is authorized.", resolver.getUserID());
ResourceResolver userAdminResolver = null;
try {
userAdminResolver =
getServiceUserWrapper().getServiceResourceResolver(getBundleLocalResourceResolverFactory(),
Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, (Object) USER_ADMIN));
LOG.debug("promoteMember: calling addGroupMembers adding {} to {}.", Arrays.asList(inviteList),
groupAdminID);
groupService.addGroupMembers(userAdminResolver, groupAdminID, inviteList);
session.refresh(false);
resolver.refresh();
} catch (final LoginException e) {
cleanupFailure(session);
throw new OperationException("Failed to login as user admin.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (final GroupException e) {
cleanupFailure(session);
throw new OperationException("Failed to join community group.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (final RepositoryException e) {
cleanupFailure(session);
throw new OperationException("Failed to join community group.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} finally {
if (userAdminResolver != null) {
userAdminResolver.close();
}
}
}
@Override
public Resource demoteMember(final SlingHttpServletRequest request) throws OperationException {
final Resource resource = request.getResource();
final ResourceResolver resolver = resource.getResourceResolver();
final Session session = resource.getResourceResolver().adaptTo(Session.class);
final String[] inviteList = request.getParameterValues(CommunityGroupConstants.PROP_COMMUNITY_GROUP_USERS);
final CommunityContext context = resource.adaptTo(CommunityContext.class);
final Resource groupPageResource = resolver.resolve(context.getCommunityGroupPath());
final CommunityGroup group =
(CommunityGroup) this.getCommunityGroupComponentForResource(groupPageResource, request);
demoteMember(resolver, group, context, inviteList, session);
return resource;
}
protected void demoteMember(final ResourceResolver resolver, final CommunityGroup group,
final CommunityContext context, final String[] inviteList, final Session session) throws OperationException {
if (resolver == null || group == null || session == null) {
return;
}
final String groupAdminID = context.getSiteUserGroupName(CommunityUserGroup.GROUP_ADMIN);
if (!GroupUtil.canPromoteGroupMember(resolver, context)) {
throw new OperationException("Deny " + session.getUserID()
+ "'s request to invite users to community group " + group.getName(),
HttpServletResponse.SC_NOT_ACCEPTABLE);
}
ResourceResolver userAdminResolver = null;
try {
userAdminResolver =
getServiceUserWrapper().getServiceResourceResolver(getBundleLocalResourceResolverFactory(),
Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, (Object) USER_ADMIN));
groupService.removeGroupMembers(userAdminResolver, groupAdminID, inviteList);
groupService.addGroupMembers(userAdminResolver, group.getMemberGroupId(), inviteList);
session.refresh(false);
resolver.refresh();
} catch (final LoginException e) {
cleanupFailure(session);
throw new OperationException("Failed to login as user admin.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (final GroupException e) {
cleanupFailure(session);
throw new OperationException("Failed to join community group.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (final RepositoryException e) {
cleanupFailure(session);
throw new OperationException("Failed to join community group.", e,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} finally {
if (userAdminResolver != null) {
userAdminResolver.close();
}
}
}
private boolean isSpecialRequestParam(final String paramName) {
for (int i = 0; i < specialParams.length; i++) {
if (paramName.equals(specialParams[i])) {
return true;
}
}
return false;
}
protected void addImage(final String path, final ResourceResolver resolver, final InputStream imageStream,
final String contentType) throws OperationException, RepositoryException {
try {
if (imageStream != null && imageStream.available() > 0) {
final Resource folder =
ResourceUtil.getOrCreateResource(resolver, path, CommunityGroupConstants.FOLDER_NODETYPE, null,
true);
final Node folderNode = folder.adaptTo(Node.class);
final Node imageNode = folderNode.addNode(PROPERTY_IMAGE_NAME, JcrConstants.NT_FILE);
final Node imageContentNode = imageNode.addNode(JcrConstants.JCR_CONTENT, JcrConstants.NT_RESOURCE);
final Binary data = resolver.adaptTo(Session.class).getValueFactory().createBinary(imageStream);
imageContentNode.setProperty(JcrConstants.JCR_MIMETYPE, contentType);
imageContentNode.setProperty(JcrConstants.JCR_DATA, data);
imageContentNode.setProperty(JcrConstants.JCR_LASTMODIFIED, Calendar.getInstance());
}
} catch (final IOException e) {
throw new OperationException("IO failure", e, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
// NOTE: caller should save the new image node
}
protected List getAttachmentsFromRequest(final SlingHttpServletRequest request,
final String requestParameterName) {
final RequestParameter[] fileRequestParameters = request.getRequestParameters(requestParameterName);
if (fileRequestParameters != null) {
// Didn't find equivalent in SocialUitl
return CollabUtil.getAttachmentsFromRequest(fileRequestParameters, ATTACHMENT_FILE_LIMIT, WHITE_LIST,
BLACK_LIST);
}
return Collections.emptyList();
}
/**
* Extract the default site properties from the specified {@link SlingHttpServletRequest} into the specified.
* {@link Map}
* @param request
* @param props
* @param session
* @throws RepositoryException
* @throws OperationException
*/
protected void getDefaultProperties(final SlingHttpServletRequest request, final Map props,
final boolean validateRequired) throws RepositoryException, OperationException {
for (int i = 0; i < requestParams.length; i++) {
final Object params[] = requestParams[i];
final Class clazz = (Class) params[PARAM_CLASS_INDEX];
final String name = (String) params[PARAM_NAME_INDEX];
if (clazz.isArray()) {
final String values[] = request.getParameterValues(name);
if (validateRequired && values == null && ((Boolean) params[PARAM_REQUIRED_INDEX])) {
throw new OperationException("Community group value '" + name + "' is empty",
HttpServletResponse.SC_BAD_REQUEST);
}
if (clazz == String[].class) {
if (values != null) {
props.put(name, values);
}
}
// TODO: Handle other array types
} else {
final String value = request.getParameter(name);
if (validateRequired && value == null && ((Boolean) params[PARAM_REQUIRED_INDEX])) {
throw new OperationException("Community group value '" + name + "' is empty",
HttpServletResponse.SC_BAD_REQUEST);
}
if (value != null) {
props.put(name, GroupUtil.toObject(value, clazz));
}
}
}
}
/**
* Extract the custom site properties from the specified {@link SlingHttpServletRequest} into the specified.
* {@link Map}
* @param request
* @param props
* @param session
* @throws RepositoryException
* @throws OperationException
*/
protected void getCustomProperties(final SlingHttpServletRequest request, final Map props,
final Session session) throws RepositoryException, OperationException {
// TODO
}
private void addAllowedTemplate(final String path, final List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy