The Q&A Friday is back and today we have a question from Mr Fred Vadon, one of our mighty presales engineers. He asks how he can have a dashboard that cannot be modified by users. This is a very logical need. This way you can make sure that every user sees their current task, pending requests or their agenda. But let me explain the default behavior.

The dashboard configuration is stored in a document. The first time a user goes to his dashboard, it's automatically copied from the default dashboard defined by the Administrator. Since we don't want users to have a personal dashboard, let's use the admin's dashboard directly by changing the userDashboardSpaceProvider. This way we avoid creating unnecessary documents. Then we'll have another issue to address - we need to give read permission to all users on the admin's dashboard document.

So about this userDashboardSpaceProvider. It's a simple contribution to an extension point:

<require>org.nuxeo.ecm.user.center.dashboard.opensocial.spaceprovider</require>
<extension target="org.nuxeo.ecm.spaces.core.spacemanager.service"
point="spaceProviders">
<spaceProvider name="userDashboardSpaceProvider">
<class>
org.nuxeo.ecm.user.center.dashboard.DefaultDashboardSpaceProvider
</class>
</spaceProvider>
</extension>

You can contribute it directly through Nuxeo Studio in AdvancedSettings > XML Extension or directly in your dev bundle (don't forget to add the file to your Manifest).

Now every user's dashboard will use the admin's document. But they still haven't got the right to read this document. If you're application is already running, you have to set up the permissions on the document. There are several ways to do this. On Nuxeo Answers, Fred explains how to do this using Nuxeo Shell. It's quite simple:

connect -u Administrator (or whatever user is an Admin, it should prompt the pwd)
cd management/dashboard-management/ (if you do a ls in there you'll see the defaultdashboardSpace)
perms defaultDashboardSpace/ (it will show you the permissions)
perms -grant "Everyone:Read" defaultDashboardSpace/ (it will update the property)

Or you can cheat and use the WebEngine administration site through this URL: http://yourserver/nuxeo/site/admin/repository/management/dashboard-management/defaultDashboardSpace.
Or even better, go directly to the document's Access Right tab through this URL: http://demo.nuxeo.com/nuxeo/nxpath/default/management/dashboard-management/[email protected]_documents?tabIds=%3ATAB_MANAGE%3ATAB_RIGHTS
It's quite easy to figure it out once you have the path of the document. You just have to use the nxpath codec and the right tabIds parameter. I find this easier than using Nuxeo Shell :)

But as Fred also wrote in his answer:

The problem with the solution above is that if you redeploy a new database, you will have to redo the permission granting, which is not something you want.

Again there are two ways to handle this problem. If you want to do this with Nuxeo Studio, read Fred's answer. If you want to do it the old fashioned way, launch Nuxeo IDE and start coding :)

Instead of adding another listener on the documentCreated event, we can directly change the way the default Dashboard is created. Here's how I would do it:

First I would define a custom spaceProvider for users and Administrators:

<require>org.nuxeo.ecm.user.center.dashboard.opensocial.spaceprovider</require>
<extension target="org.nuxeo.ecm.spaces.core.spacemanager.service"
point="spaceProviders">
<spaceProvider name="defaultDashboardSpaceProvider">
<class>
org.nuxeo.sample.CustomDefaultDashboardSpaceProvider
</class>
</spaceProvider>
<spaceProvider name="userDashboardSpaceProvider">
<class>
org.nuxeo.sample.CustomDefaultDashboardSpaceProvider
</class>
</spaceProvider>
</extension>

CustomDefaultDashboardSpaceProvider should extend DefaultDashboardSpaceProvider and override the getOrCreateDefaultDashboardSpace method. This method usually uses the DefaultDashboardSpaceCreator unrestricted runner to create the document. We're going to use our own:

public class CustomDefaultDashboardSpaceProvider extends
DefaultDashboardSpaceProvider {

@Override
protected DocumentRef getOrCreateDefaultDashboardSpace(CoreSession session,
Map<String, String> parameters) throws ClientException {
CustomDefaultDashboardSpaceCreator customDefaultDashboardSpaceCreator = new CustomDefaultDashboardSpaceCreator(
session, parameters);
customDefaultDashboardSpaceCreator.runUnrestricted();
return customDefaultDashboardSpaceCreator.defaultDashboardSpaceRef;
}

}

CustomDefaultDashboardSpaceCreator will do exactly the same thing as DefaultDashboardSpaceCreator, plus adding the read permission to everyone.

public class CustomDefaultDashboardSpaceCreator extends DefaultDashboardSpaceCreator {

public CustomDefaultDashboardSpaceCreator(CoreSession session,
Map<String, String> parameters) {
super(session, parameters);
}

@Override
protected void addDefaultACP(DocumentModel defaultDashboardSpace)
throws ClientException {
ACP acp = defaultDashboardSpace.getACP();
ACL acl = acp.getOrCreateACL();
for (String group : getUserManager().getAdministratorsGroups()) {
acl.add(new ACE(group, SecurityConstants.EVERYTHING, true));
}
acl.add(new ACE(POWER_USERS_GROUP, SecurityConstants.EVERYTHING, true));
acl.add(new ACE(SecurityConstants.EVERYONE, SecurityConstants.READ, true));
defaultDashboardSpace.setACP(acp, true);
}

}

This way you don't add an intrusive listener. The defaultDashboardSpace will always have read permission for everyone at creation.

That's it for today. As you might have read on Nuxeo Answers or on a previous post, I won't be posting Dev Heavens as regularly as I used to. I'm saving some time for other community projects right now :)