/*
* (C) Copyright 2006-2007 Nuxeo SA (http://nuxeo.com/) and others.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
* Nuxeo - initial API and implementation
*
* $Id$
*/
package org.nuxeo.ecm.webapp.security;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuxeo.common.utils.i18n.Labeler;
import org.nuxeo.ecm.core.api.security.SecurityConstants;
/**
* Holds the formatted security data, ready to be displayed. Holds the data on each map on the following structure: <br>
* <p>
* current doc grants: <br>
* user 1 - perm1, perm2 <br>
* user 2 - perm1, perm2 <br>
* user 3 - perm2 <br>
* current doc denies:<br>
* ... <br>
* parent doc grants:<br>
* ... <br>
* parent doc denies:<br>
* ...<br>
* <p>
* Also has methods that allow manipulation of the contained data, such as add/remove security privileges. The end
* result after add/remove has been called will be converted to a backend security DTO and then submitted on backend.
*
* @author Razvan Caraghin
*/
public class SecurityData implements Serializable {
protected static final Labeler labeler = new Labeler("label.security.permission");
private static final long serialVersionUID = -7958330304227141087L;
private static final Log log = LogFactory.getLog(SecurityData.class);
protected Map<String, List<String>> currentDocGrant = new HashMap<String, List<String>>();
protected Map<String, List<String>> currentDocDeny = new HashMap<String, List<String>>();
protected Map<String, List<String>> parentDocsGrant = new HashMap<String, List<String>>();
protected Map<String, List<String>> parentDocsDeny = new HashMap<String, List<String>>();
protected final List<String> currentDocumentUsers = new ArrayList<String>();
protected final List<String> parentDocumentsUsers = new ArrayList<String>();
protected String documentType = "";
protected boolean needSave = false;
public void setNeedSave(boolean needSave) {
this.needSave = needSave;
}
public boolean getNeedSave() {
return needSave;
}
public Map<String, List<String>> getCurrentDocDeny() {
return currentDocDeny;
}
public void setCurrentDocDeny(Map<String, List<String>> deny) {
currentDocDeny = deny;
}
public Map<String, List<String>> getCurrentDocGrant() {
return currentDocGrant;
}
public void setCurrentDocGrant(Map<String, List<String>> grant) {
currentDocGrant = grant;
}
public Map<String, List<String>> getParentDocsDenyLabels() {
return buildLabelMap(parentDocsDeny);
}
/**
* @since 6.0
*/
public Map<String, List<String>> getCurrentDocDenyLabels() {
return buildLabelMap(currentDocDeny);
}
public Map<String, List<String>> getParentDocsDeny() {
return parentDocsDeny;
}
public void setParentDocsDeny(Map<String, List<String>> parentDocsDeny) {
this.parentDocsDeny = parentDocsDeny;
}
public Map<String, List<String>> getParentDocsGrant() {
return parentDocsGrant;
}
public Map<String, List<String>> getParentDocsGrantLabels() {
return buildLabelMap(parentDocsGrant);
}
/**
* @since 6.0
*/
public Map<String, List<String>> getCurrentDocGrantLabels() {
return buildLabelMap(currentDocGrant);
}
public void setParentDocsGrant(Map<String, List<String>> parentDocsGrant) {
this.parentDocsGrant = parentDocsGrant;
}
public List<String> getCurrentDocumentUsers() {
return currentDocumentUsers;
}
public List<String> getParentDocumentsUsers() {
return parentDocumentsUsers;
}
protected Map<String, List<String>> buildLabelMap(Map<String, List<String>> permissions) {
Map<String, List<String>> labelMap = new HashMap<String, List<String>>();
for (String user : permissions.keySet()) {
List<String> labels = new ArrayList<String>();
for (String perm : permissions.get(user)) {
labels.add(labeler.makeLabel(perm));
}
labelMap.put(user, labels);
}
return labelMap;
}
public void rebuildUserLists() {
List<String> users = new ArrayList<String>();
users.addAll(currentDocGrant.keySet());
for (String user : currentDocDeny.keySet()) {
if (!users.contains(user)) {
users.add(user);
}
}
currentDocumentUsers.clear();
currentDocumentUsers.addAll(users);
users.clear();
users.addAll(parentDocsGrant.keySet());
for (String user : parentDocsDeny.keySet()) {
if (!users.contains(user)) {
users.add(user);
}
}
parentDocumentsUsers.clear();
parentDocumentsUsers.addAll(users);
}
/**
* Adds a privilege to the displayed list. This does not submit anything to the backend.
*/
public void addModifiablePrivilege(String principalName, String permissionName, boolean grant) {
if (null == principalName || null == permissionName) {
log.error("Null params received, returning...");
return;
}
needSave = true;
if (grant) {
// if we already have the user stored with rights we dont add the
// user again, just update the list if needed
if (null != currentDocGrant.get(principalName)) {
// we already have the user - add the right to him
boolean shouldAddPermission = true;
for (String permission : currentDocGrant.get(principalName)) {
// only add the right to list if the right is not already
// there
if (permission.equals(permissionName)) {
shouldAddPermission = false;
break;
}
}
if (shouldAddPermission) {
currentDocGrant.get(principalName).add(permissionName);
}
} else {
// add the user and create a new list of rights for him
List<String> permissions = new ArrayList<String>();
permissions.add(permissionName);
currentDocGrant.put(principalName, permissions);
}
} else {
// if we already have the user stored with rights we dont add the
// user again, just update the list if needed
if (null != currentDocDeny.get(principalName)) {
// we already have the user - add the right to him
boolean shouldAddPermission = true;
for (String permission : currentDocDeny.get(principalName)) {
// only add the right to list if the right is not already
// there
if (permission.equals(permissionName)) {
shouldAddPermission = false;
break;
}
}
if (shouldAddPermission) {
currentDocDeny.get(principalName).add(permissionName);
}
} else {
// add the user and create a new list of rights for him
List<String> permissions = new ArrayList<String>();
permissions.add(permissionName);
currentDocDeny.put(principalName, permissions);
}
}
rebuildUserLists();
}
/**
* Removes a privilege from the displayed list. This does not submit anything to backend.
*
* @return true if a privilege was indeed removed
*/
public boolean removeModifiablePrivilege(String principalName, String permissionName, boolean grant) {
if (null == principalName || null == permissionName) {
log.error("Null params received, returning...");
return false;
}
needSave = true;
boolean removed = false;
if (grant) {
if (null != currentDocGrant.get(principalName)) {
// we have the specified user, check if we have the right
Iterator<String> permissionIterator = currentDocGrant.get(principalName).iterator();
while (permissionIterator.hasNext()) {
if (permissionIterator.next().equals(permissionName)) {
permissionIterator.remove();
removed = true;
break;
}
}
}
} else {
if (null != currentDocDeny.get(principalName)) {
// we have the specified user, check if we have the right
Iterator<String> permissionIterator = currentDocDeny.get(principalName).iterator();
while (permissionIterator.hasNext()) {
if (permissionIterator.next().equals(permissionName)) {
permissionIterator.remove();
removed = true;
break;
}
}
}
}
rebuildUserLists();
return removed;
}
/**
* Removes all privileges for a given user. This does not edit the backend.
*/
public void removeModifiablePrivilege(String principalName) {
if (null == principalName) {
log.error("Null principal received, returning...");
return;
}
currentDocGrant.remove(principalName);
// if user everyone had deny everything perm, then we have to
// keep this perm
if (principalName.equals(SecurityConstants.EVERYONE)) {
final List<String> deniedPerms = currentDocDeny.get(principalName);
boolean keepDenyAll = deniedPerms != null ? deniedPerms.contains(SecurityConstants.EVERYTHING) : false;
currentDocDeny.remove(principalName);
if (keepDenyAll) {
addModifiablePrivilege(SecurityConstants.EVERYONE, SecurityConstants.EVERYTHING, false);
}
} else {
currentDocDeny.remove(principalName);
}
needSave = true;
rebuildUserLists();
}
/**
* Adds an unmodifiable privilege to the displayed list (these are related to the parent documents).
*/
public void addUnModifiablePrivilege(String principalName, String permissionName, boolean grant) {
if (null == principalName || null == permissionName) {
log.error("Null params received, returning...");
return;
}
if (grant) {
// if we already have the user stored with rights we dont add the
// user again, just update the list if needed
if (null != parentDocsGrant.get(principalName)) {
// we already have the user - add the right to him
boolean shouldAddPermission = true;
for (String permission : parentDocsGrant.get(principalName)) {
// only add the right to list if the right is not already
// there
if (permission.equals(permissionName)) {
shouldAddPermission = false;
break;
}
}
if (shouldAddPermission) {
parentDocsGrant.get(principalName).add(permissionName);
}
} else {
// add the user and create a new list of rights for him
List<String> permissions = new ArrayList<String>();
permissions.add(permissionName);
parentDocsGrant.put(principalName, permissions);
}
} else {
// if we already have the user stored with rights we dont add the
// user again, just update the list if needed
if (null != parentDocsDeny.get(principalName)) {
// we already have the user - add the right to him
boolean shouldAddPermission = true;
for (String permission : parentDocsDeny.get(principalName)) {
// only add the right to list if the right is not already
// there
if (permission.equals(permissionName)) {
shouldAddPermission = false;
break;
}
}
if (shouldAddPermission) {
parentDocsDeny.get(principalName).add(permissionName);
}
} else {
// add the user and create a new list of rights for him
List<String> permissions = new ArrayList<String>();
permissions.add(permissionName);
parentDocsDeny.put(principalName, permissions);
}
}
rebuildUserLists();
}
public void clear() {
currentDocDeny.clear();
currentDocGrant.clear();
parentDocsDeny.clear();
parentDocsGrant.clear();
currentDocumentUsers.clear();
parentDocumentsUsers.clear();
log.debug("Cleared data...");
needSave = false;
}
public String getDocumentType() {
return documentType;
}
public void setDocumentType(String documentType) {
this.documentType = documentType;
}
}