Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2012 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.api;
import java.util.ArrayList;
import java.util.List;
import javax.jcr.LoginException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.security.Privilege;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Reference;
import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.jcr.api.SlingRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import aQute.bnd.annotation.ProviderType;
import com.adobe.cq.social.community.api.CommunityConstants;
import com.adobe.cq.social.community.api.CommunityContext;
import com.adobe.cq.social.console.utils.api.UserUtils;
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.scf.ClientUtilities;
import com.adobe.cq.social.scf.OperationException;
import com.adobe.cq.social.serviceusers.internal.ServiceUserWrapper;
import com.adobe.cq.social.site.api.CommunitySiteConstants;
import com.adobe.cq.social.site.api.SiteConfiguration;
import com.adobe.granite.security.user.UserProperties;
import com.adobe.granite.security.user.UserPropertiesManager;
import com.adobe.granite.security.user.UserPropertiesService;
import com.adobe.granite.socialgraph.Direction;
import com.adobe.granite.socialgraph.GraphNode;
import com.adobe.granite.socialgraph.Relationship;
import com.adobe.granite.socialgraph.SocialGraph;
import com.adobe.granite.xss.XSSAPI;
import com.day.cq.commons.jcr.JcrConstants;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
@ProviderType
/**
* GroupUtil provides various methods managing community groups.
*/
public class GroupUtil {
public static final int DEFAULT_MAX_WAIT_TIME = 2000;
public static final int DEFAULT_WAIT_BETWEEN_RETRIES = 100;
public static final int WARN_WAIT_TIME = 120000;
public static final int WARN_RETRY_DELAY = 1000;
private static final String ANONYMOUS_USER = "anonymous";
private static final String USER_ADMIN = "communities-user-admin";
private static final String ADMIN = "admin";
private static final String ADMINISTRATORS_GROUP = "administrators";
private static final Logger log = LoggerFactory.getLogger(GroupUtil.class);
@Reference
private static XSSAPI xssAPI;
protected ClientUtilities clientUtils;
public static boolean canEveryoneCreateGroup(final Resource resource) {
// check the group configure first
final CommunityContext context = resource.adaptTo(CommunityContext.class);
final ResourceResolver resolver = resource.getResourceResolver();
final Resource configure = resolver.getResource(context.getSitePath());
if (configure == null) {
return false;
}
final ValueMap values = configure.adaptTo(ValueMap.class);
final String groupCreationType =
values.get(CommunitySiteConstants.PROP_CONFIG_GROUP_CREATION_PERMISSION_TYPE, String.class);
return StringUtils.equalsIgnoreCase(groupCreationType,
SiteConfiguration.GroupManagementConfiguration.CreatePermission.EVERYONE.name());
}
/**
* Validate if a community group name is unique.
* @param resolver resource resolver.
* @param name community group name.
* @param groupRoot community group site path.
* @return true if a community group name is unique.
*/
public static boolean validateGroupName(final ResourceResolver resolver, final String name, final String groupRoot) {
// group name cannot start with _
if (name.startsWith("_")) {
log.info("Group name {} begins with invalid charactor", name);
return false;
}
// check if a child page with the given name already exists
final PageManager pm = resolver.adaptTo(PageManager.class);
final Page childPage = pm.getPage(groupRoot + "/" + name);
if (childPage != null) {
log.info("Page {} already exists in {}", name, groupRoot);
return false;
}
// check if site has given language node to create group under it
if(resolver.getResource(groupRoot) == null){
log.error("Group root {} doesnot exists", groupRoot);
return true;
}
// check if a member group with the given name already exists
final CommunityContext site = resolver.getResource(groupRoot).adaptTo(CommunityContext.class);
String memberGroup = name + GroupConstants.GROUP_MEMBERGROUP_SUFFIX;
if (site != null) {
memberGroup = site.getTenantUserGroupName(site.getSiteId() + CommunityConstants.DASH_CHAR + memberGroup);
}
try {
final Session session = resolver.adaptTo(Session.class);
final UserManager um = ((JackrabbitSession) session).getUserManager();
final Authorizable group = um.getAuthorizable(memberGroup);
if (group != null) {
log.info("Authorizable {} already exists", memberGroup);
return false;
}
} catch (final RepositoryException e) {
log.error("Failed to validate user group " + memberGroup, e);
return false;
}
return true;
}
/**
* Returns the number of the group members.
* @param userPropertiesService user properties service.
* @param resourceResolver resource resolver.
* @param groupId group id.
* @return Number of the members of this Group. This includes both declared members and all authorizables that are
* indirect group members.
*/
public static int getNumberOfMembers(final UserPropertiesService userPropertiesService,
final ResourceResolver resourceResolver, final String groupId) {
final List relations =
establishMemberRelation(userPropertiesService, resourceResolver, groupId);
if (relations != null) {
return relations.size();
} else {
return 0;
}
}
/**
* Returns true if an authorizable is a group member.
* @param userPropertiesService user properties service.
* @param resourceResolver resource resolver.
* @param authId authorizable id.
* @param groupId group id.
* @return true if an authorizable is a group member.
*/
public static boolean isMember(final UserPropertiesService userPropertiesService,
final ResourceResolver resourceResolver, final String authId, final String groupId) {
if (StringUtils.isEmpty(authId) || StringUtils.isEmpty(groupId)) {
return false;
}
boolean isMember = false;
final SocialGraph socialGraph = resourceResolver.adaptTo(SocialGraph.class);
final GraphNode group = socialGraph.getNode(groupId);
final GraphNode user = socialGraph.getNode(authId);
if (group == null || user == null) {
isMember = false;
} else {
final String relation = "member";
final Direction direction = Direction.INCOMING;
isMember = (group.getRelationship(direction, user, relation) != null);
}
if (isMember) {
return true;
}
if (ADMIN.equals(authId)) {
return true;
}
final ServiceUserWrapper serviceUserWrapper = Activator.getService(ServiceUserWrapper.class);
final SlingRepository repository = Activator.getService(SlingRepository.class);
Session session = null;
try {
session = serviceUserWrapper.loginService(repository, USER_ADMIN);
final UserManager um = ((JackrabbitSession) session).getUserManager();
final Authorizable administrators = um.getAuthorizable(ADMINISTRATORS_GROUP);
final Authorizable userAuthorizable = um.getAuthorizable(authId);
return ((Group) administrators).isMember(userAuthorizable);
} catch (final LoginException e) {
throw new IllegalStateException("Unable to confirm user membership in administrators group.", e);
} catch (final RepositoryException e) {
throw new IllegalStateException("Unable to confirm user membership in administrators group.", e);
} finally {
if (session != null) {
session.logout();
}
}
}
/**
* Establish Social Graph relations of the group members.
* @param userPropertiesService user properties service.
* @param resourceResolver resource resolver.
* @param groupId group id.
* @return List of UserProperties which are members of this Group. This includes both declared members and all
* authorizables that are indirect group members.
*/
private static List establishMemberRelation(final UserPropertiesService userPropertiesService,
final ResourceResolver resourceResolver, final String groupId) {
final List results = new ArrayList();
if (StringUtils.isEmpty(groupId)) {
return results;
}
try {
final UserPropertiesManager upm = userPropertiesService.createUserPropertiesManager(resourceResolver);
final SocialGraph socialGraph = resourceResolver.adaptTo(SocialGraph.class);
final GraphNode group = socialGraph.getNode(groupId);
if (group == null) {
return results;
}
final String relation = "member";
final Direction direction = Direction.INCOMING;
for (final Relationship r : group.getRelationships(direction, relation)) {
final String authId = r.getOtherNode(group).getId();
// skip groups and other non authorizable relations
final UserProperties memberProperties = upm.getUserProperties(authId, "profile");
if (memberProperties == null || memberProperties.getNode().getPath().contains("groups")) {
continue;
}
results.add(memberProperties);
}
} catch (final RepositoryException e) {
log.error("establishMemberRelation: error while establish relation for [{}]", groupId);
log.error("", e);
}
return results;
}
/**
* wait for page content creation to complete. wait no more than 1 second.
* @param resolver resource resolver.
* @param pagePath page path
* @param maxWaitTime time out in millisecond
* @param waitInterval wait interval in millisecond
* @throws RepositoryException - thrown if unable to wait for page creation.
*/
public static void waitForPageCreation(final ResourceResolver resolver, final String pagePath, long maxWaitTime,
long waitInterval) throws RepositoryException {
log.debug("Wait for page creation at {}", pagePath);
if (resolver == null || StringUtils.isEmpty(pagePath)) {
return;
}
if (maxWaitTime <= 0) {
log.warn("Invalid maxWaitTime [{}]. Resetting.", maxWaitTime);
maxWaitTime = GroupUtil.DEFAULT_MAX_WAIT_TIME;
}
if (maxWaitTime > GroupUtil.WARN_WAIT_TIME) {
log.warn("Very large number of retries configured [{}]. This may cause thread contention.", maxWaitTime);
}
if (waitInterval <= 0) {
log.warn("Invalid wait interval [{}]. Resetting.", waitInterval);
waitInterval = GroupUtil.DEFAULT_WAIT_BETWEEN_RETRIES;
}
if (waitInterval > GroupUtil.WARN_RETRY_DELAY) {
log.warn("Very large wait interval configured [{}]. This may cause thread contention.", waitInterval);
}
final long start = System.currentTimeMillis();
boolean wait = false;
do {
final Resource res = resolver.resolve(pagePath + "/" + JcrConstants.JCR_CONTENT);
if (res != null && !ResourceUtil.isNonExistingResource(res)) {
if (wait) {
log.debug("Page content successfully created at {} after waiting for {} milliseconds", pagePath,
(System.currentTimeMillis() - start));
} else {
log.debug("Page content successfully created at {} already", pagePath);
}
return;
}
wait = true;
try {
Thread.sleep(waitInterval);
} catch (final InterruptedException ignore) {
}
resolver.adaptTo(Session.class).refresh(true);
resolver.refresh();
} while (System.currentTimeMillis() - start < maxWaitTime);
log.debug("Page content failed to be created at {} ", pagePath);
}
public static Object toObject(final String value, final Class clazz) {
if (Boolean.class == clazz || Boolean.TYPE == clazz) {
return Boolean.valueOf(value);
}
if (Byte.class == clazz || Byte.TYPE == clazz) {
try {
return Long.valueOf(value).byteValue();
} catch (final NumberFormatException e) {
return Double.valueOf(value).byteValue();
}
}
if (Short.class == clazz || Short.TYPE == clazz) {
try {
return Long.valueOf(value).shortValue();
} catch (final NumberFormatException e) {
return Double.valueOf(value).shortValue();
}
}
if (Integer.class == clazz || Integer.TYPE == clazz) {
try {
return Long.valueOf(value).intValue();
} catch (final NumberFormatException e) {
return Double.valueOf(value).intValue();
}
}
if (Long.class == clazz || Long.TYPE == clazz) {
try {
return Long.valueOf(value).longValue();
} catch (final NumberFormatException e) {
return Double.valueOf(value).longValue();
}
}
if (Float.class == clazz || Float.TYPE == clazz) {
try {
return Double.valueOf(value).floatValue();
} catch (final NumberFormatException e) {
return Long.valueOf(value).floatValue();
}
}
if (Double.class == clazz || Double.TYPE == clazz) {
try {
return Double.valueOf(value).doubleValue();
} catch (final NumberFormatException e) {
return Long.valueOf(value).doubleValue();
}
}
return value;
}
/**
* Check if the specified user id belong to the group admin or not.
* @param um user manager
* @param groupId Id of the group
* @param userId Id of the user
* @return the status
* @throws RepositoryException - thrown if get member status.
*/
public static boolean isMember(final UserManager um, final String groupId, final String userId)
throws RepositoryException {
if (StringUtils.isNotEmpty(groupId) && StringUtils.isNotEmpty(userId)) {
final Authorizable user = um.getAuthorizable(userId);
final Authorizable group = um.getAuthorizable(groupId);
if (group instanceof Group && user != null) {
return ((Group) group).isMember(user);
}
}
return false;
}
public static boolean isMember(final String groupId, final String userId,
final ServiceUserWrapper serviceUserWrapper, final SlingRepository repository) throws RepositoryException {
final Session session = serviceUserWrapper.loginService(repository, USER_ADMIN);
final UserManager um = ((JackrabbitSession) session).getUserManager();
if (StringUtils.isNotEmpty(groupId) && StringUtils.isNotEmpty(userId)) {
final Authorizable user = um.getAuthorizable(userId);
final Authorizable group = um.getAuthorizable(groupId);
if (group instanceof Group && user != null) {
return ((Group) group).isMember(user);
}
}
return false;
}
@Deprecated
public static boolean isGroupAdmin(final Session session, final Resource resource) throws OperationException {
if (resource == null || session == null) {
return false;
}
// check the group configure first
final ResourceResolver resolver = resource.getResourceResolver();
final CommunityContext context = resource.adaptTo(CommunityContext.class);
final Resource configure = resolver.getResource(context.getSitePath());
if (configure == null) {
return false;
}
final ValueMap values = configure.adaptTo(ValueMap.class);
final String groupCreationType =
values.get(CommunitySiteConstants.PROP_CONFIG_GROUP_CREATION_PERMISSION_TYPE, String.class);
if (StringUtils.equalsIgnoreCase(groupCreationType,
SiteConfiguration.GroupManagementConfiguration.CreatePermission.EVERYONE.name())) {
if (ANONYMOUS_USER.equals(session.getUserID())) {
return false;
} else {
return true;
}
}
return hasAdminPermissions(session, resource);
}
private static ValueMap getGroupConfiguration(final Session session, final Resource resource) {
try {
// get the community manager group
// check if the login user is part of community manager grp
final ResourceResolver resolver = resource.getResourceResolver();
final CommunityContext context = resource.adaptTo(CommunityContext.class);
final String groupPath = context.getCommunityGroupPath();
final Resource groupRes = resolver.resolve(groupPath);
final Resource groupConfig = groupRes.getChild(CommunityGroupConstants.CONFIG_NODE_NAME);
if (groupConfig == null) {
log.warn("Failed to get groupConfig resource");
return null;
}
return groupConfig.adaptTo(ValueMap.class);
} catch (final Exception e) {
log.error("Error obtaining group configuration", e);
return null;
}
}
private static boolean hasAdminPermissions(final Session session, final Resource resource) {
try {
final Privilege[] userPrivs = session.getAccessControlManager().getPrivileges(resource.getPath());
if (userPrivs.length == 1 && UserUtils.JCR_ALL_PRIVELEGE.equalsIgnoreCase(userPrivs[0].getName())) {
return true;
}
} catch (final RepositoryException e) {
log.error("Error Check If User Is Group Admin or Community Manager " + session.getUserID(), e);
}
return false;
}
// this is called when checking current user can promote/demote/invite/leave
// return true if the current user has admin permissions
// or the current user is part of the group's community managers
private static boolean isGroupCommunityMananger(final Session session, final Resource resource,
final ServiceUserWrapper serviceUserWrapper, final SlingRepository repository, final UserManager um) {
try {
// check permissions first
if (hasAdminPermissions(session, resource)) {
return true;
}
final ValueMap values = getGroupConfiguration(session, resource);
if (values == null) {
return false;
}
// check if session user is part of the group's community managers
final String grpCommunityManager =
values.get(CommunityGroupConstants.GROUP_COMMUNITY_MANAGERGROUP, String.class);
final String sessionUserId = session.getUserID();
final boolean isManager = isMember(um, grpCommunityManager, sessionUserId);
return isManager;
} catch (final RepositoryException e) {
log.error("Error Check If User Is Group Admin or Community Manager " + session.getUserID(), e);
return false;
}
}
/**
* Check if logged in user can invite group members. when group creation permission type is everyone, only group
* owner and real admins can invite/promote/demote members
* @param resolver a resource resolver.
* @param context CommunityContext.
* @param serviceUserWrapper ServiceUserWrapper.
* @param repository sling repository.
* @param um user manager.
* @return true if logged in user can invite group members
*/
public static boolean canInviteGroupMember(final ResourceResolver resolver, final CommunityContext context,
final ServiceUserWrapper serviceUserWrapper, final SlingRepository repository, final UserManager um) {
final Session session = resolver.adaptTo(Session.class);
if (context == null) {
return false;
}
final String groupPath = context.getCommunityGroupPath();
if (StringUtils.isEmpty(groupPath)) {
return false;
}
final Resource groupRes = resolver.resolve(groupPath);
final Resource groupConfig = groupRes.getChild(CommunityGroupConstants.CONFIG_NODE_NAME);
if (groupConfig == null) {
return false;
}
final ValueMap values = groupConfig.adaptTo(ValueMap.class);
if (values == null) {
return false;
}
final String type = values.get(CommunityGroupConstants.PROP_COMMUNITY_GROUP_TYPE, String.class);
final String owner = values.get(CommunityGroupConstants.PROP_COMMUNITY_GROUP_CREATOR, String.class);
if (!GroupConstants.TYPE_SECRET.equals(type)) {
return false;
}
// check the group configure first
final Resource siteConfigure = resolver.getResource(context.getSitePath());
if (siteConfigure == null) {
return false;
}
final ValueMap siteValues = siteConfigure.adaptTo(ValueMap.class);
final String groupCreationType =
siteValues.get(CommunitySiteConstants.PROP_CONFIG_GROUP_CREATION_PERMISSION_TYPE, String.class);
if (StringUtils.equalsIgnoreCase(groupCreationType,
SiteConfiguration.GroupManagementConfiguration.CreatePermission.EVERYONE.name())) {
if (session.getUserID().equals(owner)) {
return true;
}
}
return isGroupCommunityMananger(session, groupRes, serviceUserWrapper, repository, um);
}
/**
* Check if logged in user can invite group members. when group creation permission type is everyone, only group
* owner and real admins can invite/promote/demote members
* @param resolver a resource resolver.
* @param context CommunityContext.
* @param serviceUserWrapper ServiceUserWrapper.
* @param repository sling repository.
* @param um user manager.
* @return true if logged in user can invite group members
*/
public static boolean canLeaveGroup(final ResourceResolver resolver, final CommunityContext context,
final ServiceUserWrapper serviceUserWrapper, final SlingRepository repository, final UserManager um) {
final Session session = resolver.adaptTo(Session.class);
if (context == null) {
return false;
}
final String groupPath = context.getCommunityGroupPath();
if (StringUtils.isEmpty(groupPath)) {
return false;
}
final Resource groupRes = resolver.resolve(groupPath);
final Resource groupConfig = groupRes.getChild(CommunityGroupConstants.CONFIG_NODE_NAME);
if (groupConfig == null) {
return false;
}
final ValueMap values = groupConfig.adaptTo(ValueMap.class);
if (values == null) {
return false;
}
final String owner = values.get(CommunityGroupConstants.PROP_COMMUNITY_GROUP_CREATOR, String.class);
// check the group configure first
final Resource siteConfigure = resolver.getResource(context.getSitePath());
if (siteConfigure == null) {
return false;
}
final ValueMap siteValues = siteConfigure.adaptTo(ValueMap.class);
final String groupCreationType =
siteValues.get(CommunitySiteConstants.PROP_CONFIG_GROUP_CREATION_PERMISSION_TYPE, String.class);
if (StringUtils.equalsIgnoreCase(groupCreationType,
SiteConfiguration.GroupManagementConfiguration.CreatePermission.EVERYONE.name())) {
if (session.getUserID().equals(owner)) {
return true;
}
}
return isGroupCommunityMananger(session, groupRes, serviceUserWrapper, repository, um);
}
/**
* Check if logged in user can promote group members. this is disabled when group creation permission type is
* everyone.
* @param resolver a resource resolver.
* @param context CommunityContext.
* @param serviceUserWrapper ServiceUserWrapper.
* @param repository sling repository.
* @param um user manager.
* @return true if logged in user can promote group members
*/
public static boolean canPromoteGroupMember(final ResourceResolver resolver, final CommunityContext context,
final ServiceUserWrapper serviceUserWrapper, final SlingRepository repository, final UserManager um) {
final Session session = resolver.adaptTo(Session.class);
if (context == null) {
return false;
}
final String groupPath = context.getCommunityGroupPath();
if (StringUtils.isEmpty(groupPath)) {
return false;
}
final Resource groupRes = resolver.resolve(groupPath);
final Resource groupConfig = groupRes.getChild(CommunityGroupConstants.CONFIG_NODE_NAME);
if (groupConfig == null) {
return false;
}
final ValueMap values = groupConfig.adaptTo(ValueMap.class);
if (values == null) {
return false;
}
final String type = values.get(CommunityGroupConstants.PROP_COMMUNITY_GROUP_TYPE, String.class);
if (!GroupConstants.TYPE_SECRET.equals(type)) {
return false;
}
// check the group configure first
final Resource siteConfigure = resolver.getResource(context.getSitePath());
if (siteConfigure == null) {
return false;
}
final ValueMap siteValues = siteConfigure.adaptTo(ValueMap.class);
final String groupCreationType =
siteValues.get(CommunitySiteConstants.PROP_CONFIG_GROUP_CREATION_PERMISSION_TYPE, String.class);
if (StringUtils.equalsIgnoreCase(groupCreationType,
SiteConfiguration.GroupManagementConfiguration.CreatePermission.EVERYONE.name())) {
return false;
}
return isGroupCommunityMananger(session, groupRes, serviceUserWrapper, repository, um);
}
public static boolean canAccessCommunityGroup(final ResourceResolver resolver, final CommunityGroup group) {
if (GroupConstants.TYPE_OPEN.equalsIgnoreCase(group.getType())) {
return true;
} else {
// check if the session has access right
final String membergroup = group.getMemberGroupId();
final String currentUser = resolver.adaptTo(Session.class).getUserID();
return isMember(null, resolver, currentUser, membergroup);
}
}
public static boolean isPublicGroup(final ResourceResolver resourceResolver, String groupPath){
if ( resourceResolver != null && StringUtils.isNotBlank(groupPath)) {
String groupSitesConfigPath = groupPath + "/configuration";
Resource configNode = resourceResolver.getResource(groupSitesConfigPath);
if (configNode != null && configNode.getValueMap().containsKey("type") && !GroupConstants.TYPE_PUBLIC.equalsIgnoreCase(configNode.getValueMap().get("type", String.class))){
return false;
}
}
return true;
}
public static String getMemberGroupName(final ResourceResolver resourceResolver, String groupPath){
if ( resourceResolver != null && StringUtils.isNotBlank(groupPath)) {
String groupSitesConfigPath = groupPath + "/configuration";
Resource configNode = resourceResolver.getResource(groupSitesConfigPath);
if (configNode != null && configNode.getValueMap().containsKey("membergroup")){
return configNode.getValueMap().get("membergroup", String.class);
}
}
return null;
}
}