Question

I'm trying to create a new role (permissions group) for Share sites in a existing installation. Before asking I did my 'homework' and found useful resources such as:

Among others.

I have no problem in configuring my new role, it works like a charm in a clean installation or in new sites, the issue that I have is that I need to have the role available for existing sites.

To do so, I have created a sub-group in the system group that represents the site. For instance say GROUP_site_{siteId} is the site, I created a sub-group called GROUP_site_{siteId}_MyCustomRole. The problem is that the sub-group is created in the APP.DEFAULT zone and to make it work properly it MUST be in the APP.SHARE zone (please anybody correct me if I'm wrong).

Basically that's the problem I'm having... I need to 'upgrade' existing sites but I'm not sure of how I could create sub-groups in the APP.SHARE zone.

I have read the JavaScript API and the REST services documentation and it seems that zones management is not supported. The only way I see it can be achieved is through the Java API, specifically with the Authority service: http://dev.alfresco.com/resource/docs/java/repository/org/alfresco/service/cmr/security/AuthorityService.html

Now, assuming that the Java Authority service is my only option, which would be the right approach to implement the upgrade functionality that creates the child authorities in the appropriate zone? Perhaps by creating a custom patch (http://dev.alfresco.com/resource/docs/java/repository/org/alfresco/repo/admin/patch/impl/package-summary.html)?

Unless I'm taking the wrong approach, I'd like to hear from people who had the same issue, otherwise some advice would be really appreciated. I'd be really surprised if I'm the only one that need to create a new role for existing sites...

EDIT:

This problem is tracked here: https://issues.alfresco.com/jira/browse/MNT-2456

Était-ce utile?

La solution 2

The solution I came up with in order to configure and enable a new role in previously existing sites is as follows.

  1. Configure the new role, e.g. as it's explained here: https://wiki.alfresco.com/wiki/Custom_Permissions_in_Share
  2. Create a new sub-group authority under the desired site group. You can do it from the 'Groups' utility in the administration console, using REST API or the JavaScript API .
  3. Add the new sub-group authority to the APP.SHARE and remove it from APP.DEFAULT.
  4. Configure appropriate permissions on site's root folder. In other words, the new role must be granted to the new sub-group.

Note: I haven't confirmed it, but the third step might be optional. I think the only benefit of this would be to have new sub-groups properly arrange exactly the same way that Alfresco does internally.

I have created the following JavaScript snippet that can be easily run and modified on the go by using the JavaScript console admin tool (https://addons.alfresco.com/addons/javascript-console). This could be useful if you need to enable a new role in multiple existing sites.

var siteName = "my-site-id";

var newRoleName = "CustomConsumer";

var newRoleSubGroupName = "site_" + siteName + "_" + newRoleName;
var newRoleSubGroupFullName = "GROUP_" + newRoleSubGroupName;

/************************************************************/
/** Creation of the sub-group that represents the new role **/
/************************************************************/

logger.log("Starting sub-group creation");

// Get the site group object
var siteGroup = groups.getGroup("site_" + siteName);

// Create the sub-group
var newRoleSubGroup = siteGroup.createGroup(newRoleSubGroupName, newRoleSubGroupName);

logger.log("Sub-group creation done");

/**************************************************/
/** Setup the appropriate zones to the sub-group **/
/**************************************************/

logger.log("Setting up appropriate zones to the sub-group");

var shareZonesAdd = Packages.java.lang.Class.forName("java.util.HashSet").newInstance();
shareZonesAdd.add(Packages.org.alfresco.service.cmr.security.AuthorityService.ZONE_APP_SHARE);

var shareZonesRemove = Packages.java.lang.Class.forName("java.util.HashSet").newInstance();
shareZonesRemove.add(Packages.org.alfresco.service.cmr.security.AuthorityService.ZONE_APP_DEFAULT);

var ctx = Packages.org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext();
var authorityService = ctx.getBean("authorityService");

var permissionGroup = authorityService.addAuthorityToZones(newRoleSubGroupFullName, shareZonesAdd);
var permissionGroup = authorityService.removeAuthorityFromZones(newRoleSubGroupFullName, shareZonesRemove);

logger.log("Zones setup done");

/*******************************************************/
/** Setup the appropriate permissions fo the new role **/
/*******************************************************/

var nodes = search.xpathSearch('/app:company_home/st:sites/cm:' + siteName);

for (var i = 0; i < nodes.length; i++)
{
    logger.log("Setting new 'Content Expert' role permissions...");

    nodes[i].setPermission(newRoleName, newRoleSubGroupFullName);

    logger.log("Permissions folder successfully set");
}

IMPORTANT: bear in mind that as Andreas Steffan is pointing out, you also might have to deal with group life-cycle, invitation process, workflows etc. so beware by using this solution!

EDIT:

The solution explained here might work too, but I haven't tried: http://blog.abstractive.ca/2012/12/custom-share-role-breaks-existing-sites-solution/

Autres conseils

It's ugly, but you can create groups of this type from JavaScript. Before you do this, get really aware of all the consequences you might have to deal with. Messing up with group based security in alfresco share is dead simple - even if you only stick with ootb functionality. It's in german, but you might still wan't to have a look at the extension I came up with at http://www.contentreich.de/contentreich-alfresco-add-on-site-gruppen .

That said, you can create the groups with Javascript like so:

var groupName = "YourGroup";
var shareZones = Packages.java.lang.Class.forName("java.util.HashSet").newInstance();
shareZones.add(Packages.org.alfresco.service.cmr.security.AuthorityService.ZONE_APP_SHARE);
shareZones.add(Packages.org.alfresco.service.cmr.security.AuthorityService.ZONE_AUTH_ALFRESCO;
var ctx = Packages.org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext();
var authorityService = ctx.getBean("authorityService");
var siteRoleGroup = "site_" + site.shortName + "_Site" + groupName;
var permissionGroup = authorityService.createAuthority(Packages.org.alfresco.service.cmr.security.AuthorityType.GROUP, siteRoleGroup, site.shortName, shareZones);

For people who are getting error as : org.springframework.beans.factory.BeanDefinitionStoreException: Can only specify arguments for the getBean method when referring to a prototype bean definition.

Please use following to get authorityService bean. var authorityService = ctx.getBean("authorityService",Packages.org.alfresco.service.cmr.security.AuthorityService);

Additionally i have created following script which will fix the custom role for all existing sites. You do not have to fix for each site individually.

main();

function main(){
	var message = 'Test';
	var successCount = 0;
	var failedCount = 0;
	var successNodes = [];
	var failNodes = [];
	var allSites = siteService.listSites(null, null, 0);

	for (var siteIndex = 0; siteIndex < allSites.length; siteIndex++) {
		var siteShortName = allSites[siteIndex].shortName;
		logger.log("SiteShortName: "+siteShortName);
		var siteNode = allSites[siteIndex].getNode();
		var response = createAuthorities(siteShortName, [ "SiteViewer" ], siteNode);
		if (response == 'success') {
			successCount = successCount + 1;
			successNodes[siteNode.nodeRef] = 'Success - '+ siteNode.properties.name + ' and SiteShortName - '  + siteShortName;
		} else {
			failedCount = failedCount + 1;
			failNodes[siteNode.nodeRef] = 'Failed - '+ siteNode.properties.name +' and SiteShortName - ' + siteShortName;
		}
	}
  
	model.message = 'Success count = '+successCount+' Fail count = '+failedCount+' Total = '+allSites.length;
	model.successNodes = successNodes;
	model.failNodes = failNodes;
	logger.log(successNodes);
	logger.log(model.message);
}

function createAuthorities(siteName, rolesList, siteNode) {
	var msg = "";
	try {
		var siteExp = "site_" + siteName;
		var prefix = siteExp + "_";
		var rootGroup = groups.getGroup(siteExp);
		for (var roleIndex = 0; roleIndex < rolesList.length; roleIndex++) {
			var roleName = rolesList[roleIndex];
			var groupName = prefix + roleName;
			var groupFullName = "GROUP_"+ groupName;
			logger.log("GroupName: "+groupName+" and roleName: "+roleName);
			if (groups.getGroup(groupName) == null) {
				rootGroup.createGroup(groupName, groupName);
			}

			if (siteNode != null) {
				siteNode.setPermission(roleName, groupFullName);
			}
			
			logger.log("Sub-group creation done");

			/**************************************************/
			/** Setup the appropriate zones to the sub-group **/
			/**************************************************/

			logger.log("Setting up appropriate zones to the sub-group");

			var shareZonesAdd = Packages.java.lang.Class.forName("java.util.HashSet").newInstance();
			shareZonesAdd.add(Packages.org.alfresco.service.cmr.security.AuthorityService.ZONE_APP_SHARE);

			var shareZonesRemove = Packages.java.lang.Class.forName("java.util.HashSet").newInstance();
			shareZonesRemove.add(Packages.org.alfresco.service.cmr.security.AuthorityService.ZONE_APP_DEFAULT);

			var ctx = Packages.org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext();
			var authorityService = ctx.getBean("authorityService",Packages.org.alfresco.service.cmr.security.AuthorityService);

			authorityService.addAuthorityToZones(groupFullName, shareZonesAdd);
			authorityService.removeAuthorityFromZones(groupFullName, shareZonesRemove);

			logger.log("Zones setup done");
		}
		msg = "success";
	} catch (e) {
		msg = e.message;
		logger.log("Error while creating authority for "+ siteNode.nodeRef);
	}
	return msg;
}

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top