RM-1763: Record Contributors Group

* if configured, RECORD_CONTRIBUTOR group controls who can declare records within collaboration sites



git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@91414 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Roy Wetherall
2014-12-01 00:48:51 +00:00
parent 839686a83c
commit 9f2b174a23
18 changed files with 469 additions and 101 deletions

View File

@@ -40,6 +40,9 @@ public class BootstrapImporterModuleComponent extends ImporterModuleComponent
/** module patch executer */
private ModulePatchExecuter modulePatchExecuter;
/** record contributors group bootstrap component */
private RecordContributorsGroupBootstrapComponent recordContributorsGroupBootstrapComponent;
/**
* @param nodeService node service
@@ -57,6 +60,14 @@ public class BootstrapImporterModuleComponent extends ImporterModuleComponent
this.modulePatchExecuter = modulePatchExecuter;
}
/**
* @param recordContributorsGroupBootstrapComponent record contributors group bootstrap component
*/
public void setRecordContributorsGroupBootstrapComponent(RecordContributorsGroupBootstrapComponent recordContributorsGroupBootstrapComponent)
{
this.recordContributorsGroupBootstrapComponent = recordContributorsGroupBootstrapComponent;
}
/**
* Need to check whether this module has already been executed.
*
@@ -69,6 +80,9 @@ public class BootstrapImporterModuleComponent extends ImporterModuleComponent
if (!nodeService.exists(nodeRef))
{
super.executeInternal();
// bootstrap the record contributors group
recordContributorsGroupBootstrapComponent.createRecordContributorsGroup();
// init module schema number
modulePatchExecuter.initSchemaVersion();

View File

@@ -0,0 +1,73 @@
/*
* Copyright (C) 2005-2014 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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.
*
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.module.org_alfresco_module_rm.bootstrap;
import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
/**
* Record contributors group bootstrap component
*
* @author Roy Wetherall
* @since 2.3
*/
public class RecordContributorsGroupBootstrapComponent
{
// default record contributors group
public static final String RECORD_CONTRIBUTORS = "RECORD_CONTRIBUTORS";
public static final String GROUP_RECORD_CONTRIBUTORS = "GROUP_" + RECORD_CONTRIBUTORS;
/** authority service */
private AuthorityService authorityService;
/** authentication utils */
private AuthenticationUtil authenticationUtil;
/**
* @param authorityService authority service
*/
public void setAuthorityService(AuthorityService authorityService)
{
this.authorityService = authorityService;
}
/**
* @param authenticationUtil authentication util
*/
public void setAuthenticationUtil(AuthenticationUtil authenticationUtil)
{
this.authenticationUtil = authenticationUtil;
}
/**
* Create record contributor group
*/
public void createRecordContributorsGroup()
{
if (!authorityService.authorityExists(GROUP_RECORD_CONTRIBUTORS))
{
// create record contributors group
authorityService.createAuthority(AuthorityType.GROUP, RECORD_CONTRIBUTORS);
// add the admin user
authorityService.addAuthority(GROUP_RECORD_CONTRIBUTORS, authenticationUtil.getAdminUserName());
}
}
}

View File

@@ -63,124 +63,65 @@ public interface RMPermissionModel
String ROLE_ADMINISTRATOR = SimplePermissionReference.getPermissionReference(RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT, FilePlanRoleService.ROLE_ADMIN).toString();
// Capability permissions
String DECLARE_RECORDS = "DeclareRecords";
String VIEW_RECORDS = "ViewRecords";
String VIEW_RECORDS = "ViewRecords";
String CREATE_MODIFY_DESTROY_FOLDERS = "CreateModifyDestroyFolders";
String EDIT_RECORD_METADATA = "EditRecordMetadata";
String EDIT_NON_RECORD_METADATA = "EditNonRecordMetadata";
String ADD_MODIFY_EVENT_DATES = "AddModifyEventDates";
String CLOSE_FOLDERS = "CloseFolders";
String DECLARE_RECORDS_IN_CLOSED_FOLDERS = "DeclareRecordsInClosedFolders";
String RE_OPEN_FOLDERS = "ReOpenFolders";
String CYCLE_VITAL_RECORDS = "CycleVitalRecords";
String PLANNING_REVIEW_CYCLES = "PlanningReviewCycles";
String UPDATE_TRIGGER_DATES = "UpdateTriggerDates";
String CREATE_MODIFY_DESTROY_EVENTS = "CreateModifyDestroyEvents";
String MANAGE_ACCESS_RIGHTS = "ManageAccessRights";
String MOVE_RECORDS = "MoveRecords";
String CHANGE_OR_DELETE_REFERENCES = "ChangeOrDeleteReferences";
String DELETE_LINKS = "DeleteLinks";
String EDIT_DECLARED_RECORD_METADATA = "EditDeclaredRecordMetadata";
String MANUALLY_CHANGE_DISPOSITION_DATES = "ManuallyChangeDispositionDates";
String APPROVE_RECORDS_SCHEDULED_FOR_CUTOFF = "ApproveRecordsScheduledForCutoff";
String CREATE_MODIFY_RECORDS_IN_CUTOFF_FOLDERS = "CreateModifyRecordsInCutoffFolders";
String EXTEND_RETENTION_PERIOD_OR_FREEZE = "ExtendRetentionPeriodOrFreeze";
String UNFREEZE = "Unfreeze";
String VIEW_UPDATE_REASONS_FOR_FREEZE = "ViewUpdateReasonsForFreeze";
String DESTROY_RECORDS_SCHEDULED_FOR_DESTRUCTION = "DestroyRecordsScheduledForDestruction";
String DESTROY_RECORDS = "DestroyRecords";
String UPDATE_VITAL_RECORD_CYCLE_INFORMATION = "UpdateVitalRecordCycleInformation";
String UNDECLARE_RECORDS = "UndeclareRecords";
String DECLARE_AUDIT_AS_RECORD = "DeclareAuditAsRecord";
String DELETE_AUDIT = "DeleteAudit";
String CREATE_MODIFY_DESTROY_TIMEFRAMES = "CreateModifyDestroyTimeframes";
String AUTHORIZE_NOMINATED_TRANSFERS = "AuthorizeNominatedTransfers";
String EDIT_SELECTION_LISTS = "EditSelectionLists";
String AUTHORIZE_ALL_TRANSFERS = "AuthorizeAllTransfers";
String CREATE_MODIFY_DESTROY_FILEPLAN_METADATA = "CreateModifyDestroyFileplanMetadata";
String CREATE_AND_ASSOCIATE_SELECTION_LISTS = "CreateAndAssociateSelectionLists";
String ATTACH_RULES_TO_METADATA_PROPERTIES = "AttachRulesToMetadataProperties";
String CREATE_MODIFY_DESTROY_FILEPLAN_TYPES = "CreateModifyDestroyFileplanTypes";
String CREATE_MODIFY_DESTROY_RECORD_TYPES = "CreateModifyDestroyRecordTypes";
String MAKE_OPTIONAL_PARAMETERS_MANDATORY = "MakeOptionalParametersMandatory";
String MAP_EMAIL_METADATA = "MapEmailMetadata";
String DELETE_RECORDS = "DeleteRecords";
String TRIGGER_AN_EVENT = "TriggerAnEvent";
String CREATE_MODIFY_DESTROY_ROLES = "CreateModifyDestroyRoles";
String CREATE_MODIFY_DESTROY_USERS_AND_GROUPS = "CreateModifyDestroyUsersAndGroups";
String PASSWORD_CONTROL = "PasswordControl";
String ENABLE_DISABLE_AUDIT_BY_TYPES = "EnableDisableAuditByTypes";
String SELECT_AUDIT_METADATA = "SelectAuditMetadata";
String DISPLAY_RIGHTS_REPORT = "DisplayRightsReport";
String ACCESS_AUDIT = "AccessAudit";
String EXPORT_AUDIT = "ExportAudit";
String CREATE_MODIFY_DESTROY_REFERENCE_TYPES = "CreateModifyDestroyReferenceTypes";
String UPDATE_CLASSIFICATION_DATES = "UpdateClassificationDates";
String CREATE_MODIFY_DESTROY_CLASSIFICATION_GUIDES = "CreateModifyDestroyClassificationGuides";
String UPGRADE_DOWNGRADE_AND_DECLASSIFY_RECORDS = "UpgradeDowngradeAndDeclassifyRecords";
String UPDATE_EXEMPTION_CATEGORIES = "UpdateExemptionCategories";
String MAP_CLASSIFICATION_GUIDE_METADATA = "MapClassificationGuideMetadata";
String MANAGE_ACCESS_CONTROLS = "ManageAccessControls";
String CREATE_HOLD = "CreateHold";
String ADD_TO_HOLD = "AddToHold";
String REMOVE_FROM_HOLD = "RemoveFromHold";
}
}

View File

@@ -22,6 +22,7 @@ import java.util.Map;
import net.sf.acegisecurity.vote.AccessDecisionVoter;
import org.alfresco.module.org_alfresco_module_rm.capability.impl.ViewRecordsCapability;
import org.alfresco.module.org_alfresco_module_rm.caveat.RMCaveatConfigComponent;
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
@@ -276,7 +277,7 @@ public class RMSecurityCommon implements ApplicationContextAware
}
else
{
AccessStatus result = permissionService.hasPermission(filePlan, RMPermissionModel.VIEW_RECORDS);
AccessStatus result = permissionService.hasPermission(filePlan, ViewRecordsCapability.NAME);
transactionCache.put(key, result);
return result;
}

View File

@@ -18,7 +18,7 @@
*/
package org.alfresco.module.org_alfresco_module_rm.capability.policy;
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
import org.alfresco.module.org_alfresco_module_rm.capability.impl.ViewRecordsCapability;
import org.alfresco.service.cmr.repository.NodeRef;
import org.aopalliance.intercept.MethodInvocation;
@@ -32,7 +32,7 @@ public class AssocPolicy extends AbstractBasePolicy
ConfigAttributeDefinition cad)
{
NodeRef testNodeRef = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent());
return getCapabilityService().getCapability(RMPermissionModel.VIEW_RECORDS).evaluate(testNodeRef);
return getCapabilityService().getCapability(ViewRecordsCapability.NAME).evaluate(testNodeRef);
}
}

View File

@@ -18,7 +18,7 @@
*/
package org.alfresco.module.org_alfresco_module_rm.capability.policy;
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
import org.alfresco.module.org_alfresco_module_rm.capability.impl.ViewRecordsCapability;
import org.alfresco.service.cmr.repository.NodeRef;
import org.aopalliance.intercept.MethodInvocation;
@@ -38,6 +38,6 @@ public class ReadPolicy extends AbstractBasePolicy
ConfigAttributeDefinition cad)
{
NodeRef testNodeRef = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent());
return getCapabilityService().getCapability(RMPermissionModel.VIEW_RECORDS).evaluate(testNodeRef);
return getCapabilityService().getCapability(ViewRecordsCapability.NAME).evaluate(testNodeRef);
}
}

View File

@@ -19,11 +19,13 @@
package org.alfresco.module.org_alfresco_module_rm.jscript.app;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService;
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
import org.alfresco.module.org_alfresco_module_rm.capability.impl.ViewRecordsCapability;
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind;
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
@@ -53,9 +55,23 @@ import org.json.simple.JSONObject;
*
* @author Roy Wetherall
*/
public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONConversionComponent implements NodeServicePolicies.OnDeleteNodePolicy,
NodeServicePolicies.OnCreateNodePolicy
public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONConversionComponent
implements NodeServicePolicies.OnDeleteNodePolicy,
NodeServicePolicies.OnCreateNodePolicy
{
/** JSON values */
private static final String IS_RM_NODE = "isRmNode";
private static final String RM_NODE = "rmNode";
private static final String IS_RM_SITE_CREATED = "isRmSiteCreated";
private static final String IS_RECORD_CONTRIBUTOR_GROUP_ENABLED = "isRecordContributorGroupEnabled";
private static final String RECORD_CONTRIBUTOR_GROUP_NAME = "recordContributorGroupName";
/** true if record contributor group is enabled, false otherwise */
private boolean isRecordContributorsGroupEnabled = false;
/** record contributors group */
private String recordContributorsGroupName = "RECORD_CONTRIBUTORS";
/** Record service */
private RecordService recordService;
@@ -86,6 +102,22 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC
/** Constant for checking the cache */
private static final String RM_SITE_EXISTS = "rmSiteExists";
/**
* @param enabled true if enabled, false otherwise
*/
public void setRecordContributorsGroupEnabled(boolean enabled)
{
isRecordContributorsGroupEnabled = enabled;
}
/**
* @param recordContributorsGroupName record contributors group name
*/
public void setRecordContributorsGroupName(String recordContributorsGroupName)
{
this.recordContributorsGroupName = recordContributorsGroupName;
}
/**
* @param recordService record service
*/
@@ -199,21 +231,25 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC
// Set the base root values
super.setRootValues(nodeInfo, rootJSONObject, useShortQNames);
// check the exisitance of the RM site
checkRmSiteExistence(rootJSONObject);
// get the record contributor information
rootJSONObject.put(IS_RECORD_CONTRIBUTOR_GROUP_ENABLED, isRecordContributorsGroupEnabled);
rootJSONObject.put(RECORD_CONTRIBUTOR_GROUP_NAME, recordContributorsGroupName);
// Get the node reference for convenience
NodeRef nodeRef = nodeInfo.getNodeRef();
if (AccessStatus.ALLOWED.equals(capabilityService.getCapabilityAccessState(nodeRef,
RMPermissionModel.VIEW_RECORDS)))
if (AccessStatus.ALLOWED.equals(capabilityService.getCapabilityAccessState(nodeRef, ViewRecordsCapability.NAME)))
{
// Indicate whether the node is a RM object or not
boolean isFilePlanComponent = filePlanService.isFilePlanComponent(nodeInfo.getNodeRef());
rootJSONObject.put("isRmNode", isFilePlanComponent);
rootJSONObject.put(IS_RM_NODE, isFilePlanComponent);
if (isFilePlanComponent)
{
rootJSONObject.put("rmNode", setRmNodeValues(nodeRef, useShortQNames));
rootJSONObject.put(RM_NODE, setRmNodeValues(nodeRef, useShortQNames));
// FIXME: Is this the right place to add the information?
addInfo(nodeInfo, rootJSONObject);
@@ -222,6 +258,11 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC
}
}
/**
* Checks for the existance of the RM site
*
* @param rootJSONObject the root JSON object
*/
@SuppressWarnings("unchecked")
private void checkRmSiteExistence(JSONObject rootJSONObject)
{
@@ -231,17 +272,17 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC
if (site != null)
{
getJsonConversionComponentCache().put(RM_SITE_EXISTS, true);
rootJSONObject.put("isRmSiteCreated", true);
rootJSONObject.put(IS_RM_SITE_CREATED, true);
}
else
{
getJsonConversionComponentCache().put(RM_SITE_EXISTS, false);
rootJSONObject.put("isRmSiteCreated", false);
rootJSONObject.put(IS_RM_SITE_CREATED, false);
}
}
else
{
rootJSONObject.put("isRmSiteCreated", getJsonConversionComponentCache().get(RM_SITE_EXISTS));
rootJSONObject.put(IS_RM_SITE_CREATED, getJsonConversionComponentCache().get(RM_SITE_EXISTS));
}
}
@@ -293,6 +334,7 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC
if (originatingLocation != null)
{
// add the originating location (if there is one)
String pathSeparator = "/";
String displayPath = getDisplayPath(originatingLocation);
String[] displayPathElements = displayPath.split(pathSeparator);
@@ -324,12 +366,14 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC
}
/**
* @param nodeRef
* @param useShortQName
* @return
* Helper method to set the RM node values
*
* @param nodeRef node reference
* @param useShortQName indicates whether the short QName are used or not
* @return {@link JSONObject} JSON object containing values
*/
@SuppressWarnings("unchecked")
private JSONObject setRmNodeValues(NodeRef nodeRef, boolean useShortQName)
private JSONObject setRmNodeValues(final NodeRef nodeRef, final boolean useShortQName)
{
JSONObject rmNodeValues = new JSONObject();
@@ -339,20 +383,32 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC
// Get the 'kind' of the file plan component
FilePlanComponentKind kind = filePlanService.getFilePlanComponentKind(nodeRef);
rmNodeValues.put("kind", kind.toString());
// File plan node reference
NodeRef filePlan = filePlanService.getFilePlan(nodeRef);
rmNodeValues.put("filePlan", filePlan.toString());
// Unfiled container node reference
NodeRef unfiledRecordContainer = filePlanService.getUnfiledContainer(filePlan);
if (unfiledRecordContainer != null)
Map<String, Object> values = AuthenticationUtil.runAsSystem(new RunAsWork<Map<String, Object>>()
{
rmNodeValues.put("unfiledRecordContainer", unfiledRecordContainer.toString());
rmNodeValues.put("properties", propertiesToJSON(unfiledRecordContainer, nodeService.getProperties(unfiledRecordContainer), useShortQName));
QName type = fileFolderService.getFileInfo(unfiledRecordContainer).getType();
rmNodeValues.put("type", useShortQName ? type.toPrefixString(namespaceService) : type.toString());
}
public Map<String, Object> doWork() throws Exception
{
Map<String, Object> result = new HashMap<String, Object>();
// File plan node reference
NodeRef filePlan = filePlanService.getFilePlan(nodeRef);
result.put("filePlan", filePlan.toString());
// Unfiled container node reference
NodeRef unfiledRecordContainer = filePlanService.getUnfiledContainer(filePlan);
if (unfiledRecordContainer != null)
{
result.put("unfiledRecordContainer", unfiledRecordContainer.toString());
result.put("properties", propertiesToJSON(unfiledRecordContainer, nodeService.getProperties(unfiledRecordContainer), useShortQName));
QName type = fileFolderService.getFileInfo(unfiledRecordContainer).getType();
result.put("type", useShortQName ? type.toPrefixString(namespaceService) : type.toString());
}
return result;
}
});
rmNodeValues.putAll(values);
// Set the indicators array
setIndicators(rmNodeValues, nodeRef);

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2005-2014 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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.
*
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.module.org_alfresco_module_rm.patch.v23;
import org.alfresco.module.org_alfresco_module_rm.bootstrap.RecordContributorsGroupBootstrapComponent;
import org.alfresco.module.org_alfresco_module_rm.patch.AbstractModulePatch;
/**
* RM v2.3 patch that creates the record contributors group.
*
* @author Roy Wetherall
* @since 2.3
*/
public class RMv23RecordContributorsGroupPatch extends AbstractModulePatch
{
/** record contributors group bootstrap component */
private RecordContributorsGroupBootstrapComponent recordContributorsGroupBootstrapComponent;
/**
* @param recordContributorsGroupBootstrapComponent record contributors group bootstrap component
*/
public void setRecordContributorsGroupBootstrapComponent(RecordContributorsGroupBootstrapComponent recordContributorsGroupBootstrapComponent)
{
this.recordContributorsGroupBootstrapComponent = recordContributorsGroupBootstrapComponent;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.patch.AbstractModulePatch#applyInternal()
*/
@Override
public void applyInternal()
{
// create record contributors group
recordContributorsGroupBootstrapComponent.createRecordContributorsGroup();
}
}

View File

@@ -29,8 +29,9 @@ import org.alfresco.service.cmr.repository.NodeRef;
public interface FilePlanPermissionService
{
/**
* Setup permissions for a record category
*
* @param nodeRef
* @param nodeRef record category node reference
*/
void setupRecordCategoryPermissions(NodeRef recordCategory);

View File

@@ -69,7 +69,7 @@ public class AuthenticationUtil
/**
* Helper method that gets the admin user name.
* <p>
* Usefule when testing using mocks.
* Useful when testing using mocks.
*
* @see org.alfresco.repo.security.authentication.AuthenticationUtil#getAdminUserName()
*/
@@ -77,5 +77,14 @@ public class AuthenticationUtil
{
return org.alfresco.repo.security.authentication.AuthenticationUtil.getAdminUserName();
}
/**
* Helper method that gets the system user name.
*
* @see org.alfresco.repo.security.authentication.AuthenticationUtil#getSystemUserName()
*/
public String getSystemUserName()
{
return org.alfresco.repo.security.authentication.AuthenticationUtil.getSystemUserName();
}
}