/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2006 by:
EXSE, Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/deegree/
lat/lon GmbH
http://www.lat-lon.de
This library 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 2.1 of the License, or (at your option) any later version.
This library 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 this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstr. 19
53177 Bonn
Germany
E-Mail: poth@lat-lon.de
Prof. Dr. Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: greve@giub.uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.portal.standard.security.control;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.deegree.datatypes.QualifiedName;
import org.deegree.enterprise.control.AbstractListener;
import org.deegree.enterprise.control.FormEvent;
import org.deegree.enterprise.control.RPCException;
import org.deegree.enterprise.control.RPCMethodCall;
import org.deegree.enterprise.control.RPCParameter;
import org.deegree.enterprise.control.RPCWebEvent;
import org.deegree.model.filterencoding.ComplexFilter;
import org.deegree.model.filterencoding.Filter;
import org.deegree.model.filterencoding.Literal;
import org.deegree.model.filterencoding.LogicalOperation;
import org.deegree.model.filterencoding.Operation;
import org.deegree.model.filterencoding.OperationDefines;
import org.deegree.model.filterencoding.PropertyIsCOMPOperation;
import org.deegree.model.filterencoding.PropertyName;
import org.deegree.model.filterencoding.SpatialOperation;
import org.deegree.model.spatialschema.Envelope;
import org.deegree.model.spatialschema.Position;
import org.deegree.ogcbase.PropertyPath;
import org.deegree.ogcbase.PropertyPathFactory;
import org.deegree.security.GeneralSecurityException;
import org.deegree.security.drm.SecurityAccess;
import org.deegree.security.drm.model.Right;
import org.deegree.security.drm.model.RightType;
import org.deegree.security.drm.model.Role;
import org.deegree.security.drm.model.SecuredObject;
import org.deegree.security.drm.model.User;
/**
* This <code>Listener</code> reacts on RPC-EditRole events, extracts the
* submitted role-id and passes the role + known securable objects on the JSP.
* <p>
* Access constraints:
* <ul>
* <li>only users that have the 'SEC_ADMIN'-role are allowed
* </ul>
*
* @author <a href="mschneider@lat-lon.de">Markus Schneider </a>
*/
public class InitRightsEditorListener extends AbstractListener {
public void actionPerformed(FormEvent event) {
try {
// perform access check
SecurityAccess access = SecurityHelper.acquireAccess(this);
SecurityHelper.checkForAdminRole(access);
User user = access.getUser();
RPCWebEvent ev = (RPCWebEvent) event;
RPCMethodCall rpcCall = ev.getRPCMethodCall();
RPCParameter[] params = rpcCall.getParameters();
if (params.length != 1) {
throw new RPCException(
"Invalid RPC. Exactly one 'param'-element below 'params' is required.");
}
if (params[0].getType() != String.class) {
throw new RPCException(
"Invalid RPC. 'param'-element below 'params' must contain a 'string'.");
}
int roleId = -1;
try {
roleId = Integer.parseInt((String) params[0].getValue());
} catch (NumberFormatException e) {
throw new RPCException(
"Invalid RPC. Role must be specified by a valid integer value.");
}
// get Role to be edited
Role role = access.getRoleById(roleId);
// check if user has the right to update the role
if (!user.hasRight(access, RightType.UPDATE, role)) {
throw new GeneralSecurityException(
"Sie haben keine Berechtigung zur Modifikation der Rolle '"
+ role.getName() + "'.");
}
// fetch all datasets for which access can be granted
// SecuredObject[] objects = access.getAllSecuredObjects("dataset");
// ArrayList grantable = new ArrayList(objects.length);
// Role[] userRoles = user.getRoles(access);
// for (int i = 0; i < objects.length; i++) {
// if (subadminRole.hasRight(access, RightType.GRANT, objects[i])) {
// grantable.add(objects[i]);
// }
// }
SecuredObject[] layers = access.getAllSecuredObjects(ClientHelper.TYPE_LAYER);
SecuredObjectRight[] getMapRights = new SecuredObjectRight[layers.length];
for (int i = 0; i < layers.length; i++) {
Right right = role.getRights(access, layers[i]).getRight(
layers[i], RightType.GETMAP);
boolean isAccessible = right != null ? true : false;
Map constraintsMap = new HashMap();
if (right != null && right.getConstraints() != null) {
constraintsMap = buildConstraintsMap(right.getConstraints());
}
getMapRights[i] = new SecuredObjectRight(isAccessible,
layers[i], constraintsMap);
}
SecuredObject[] featureTypes =
access.getAllSecuredObjects(ClientHelper.TYPE_FEATURETYPE);
SecuredObjectRight[] getFeatureRights = new SecuredObjectRight[featureTypes.length];
for (int i = 0; i < featureTypes.length; i++) {
Right right = role.getRights(access, featureTypes[i]).getRight(
featureTypes[i], RightType.GETFEATURE);
boolean isAccessible = right != null ? true : false;
Map constraints = new HashMap();
getFeatureRights[i] = new SecuredObjectRight(isAccessible,
featureTypes[i], constraints);
}
getRequest().setAttribute("ROLE", role);
getRequest().setAttribute("RIGHTS_GET_MAP", getMapRights);
getRequest().setAttribute("RIGHTS_GET_FEATURE", getFeatureRights);
} catch (RPCException e) {
getRequest().setAttribute("SOURCE", this.getClass().getName());
getRequest().setAttribute( "MESSAGE", "Der Rechteeditor konnte nicht aufgerufen werden, "
+ "da die Anfrage fehlerhaft war.<br><br>"
+ "Die Fehlermeldung lautet: <code>"
+ e.getMessage() + "</code>");
setNextPage("error.jsp");
e.printStackTrace();
} catch (GeneralSecurityException e) {
getRequest().setAttribute("SOURCE", this.getClass().getName());
getRequest().setAttribute( "MESSAGE","Der Rechteeditor konnte nicht aufgerufen werden, "
+ "da ein Fehler aufgetreten ist.<br><br>"
+ "Die Fehlermeldung lautet: <code>"
+ e.getMessage() + "</code>");
setNextPage("error.jsp");
e.printStackTrace();
}
}
/**
* Reconstructs the constraints map (keys are Strings, values are arrays of
* Strings) from the given <code>Filter</code> expression. This only works
* if the expression meets the very format used by the
* <code>StoreRightsListener</code>.
*
* @param filter
* @return
* @throws SecurityException
*/
private Map buildConstraintsMap(Filter filter) throws SecurityException {
Map constraintsMap = new HashMap();
if (filter instanceof ComplexFilter) {
Operation operation = ((ComplexFilter) filter).getOperation();
if (operation.getOperatorId() == OperationDefines.AND) {
LogicalOperation andOperation = (LogicalOperation) operation;
Iterator it = andOperation.getArguments().iterator();
while (it.hasNext()) {
addConstraintToMap((Operation) it.next(), constraintsMap);
}
} else {
addConstraintToMap(operation, constraintsMap);
}
}
return constraintsMap;
}
/**
* Extracts the constraint in the given <code>Operation</code> and adds it
* to the also supplied <code>Map</code>. The <code>Operation</code>
* must be of type OperationDefines.OR (with children that are all of type
* <code>PropertyIsCOMPOperations</code> or <code>BBOX</code>) or of
* type <code>PropertyIsCOMPOperation</code>(<code>BBOX</code>), in
* any other case this method will fail.
*
* @param operation
* @param map
* @throws SecurityException
*/
private void addConstraintToMap(Operation operation, Map map) throws SecurityException {
PropertyPath constraintName = null;
String[] parameters = new String[1];
if (operation instanceof PropertyIsCOMPOperation) {
PropertyIsCOMPOperation comparison = (PropertyIsCOMPOperation) operation;
try {
constraintName = ((PropertyName) comparison.getFirstExpression()).getValue();
parameters[0] = ((Literal) comparison.getSecondExpression()).getValue();
} catch (ClassCastException e) {
throw new SecurityException(
"Unable to reconstruct constraint map from stored filter expression. "
+ "Invalid filter format.");
}
} else if ( operation.getOperatorId() == OperationDefines.BBOX ||
operation.getOperatorId() == OperationDefines.WITHIN ) {
constraintName = PropertyPathFactory.createPropertyPath( new QualifiedName( "bbox" ) );
SpatialOperation spatialOperation = (SpatialOperation) operation;
Envelope envelope = spatialOperation.getGeometry().getEnvelope();
try {
Position max = envelope.getMax();
Position min = envelope.getMin();
parameters = new String[4];
parameters [0] = "" + min.getX();
parameters [1] = "" + min.getY();
parameters [2] = "" + max.getX();
parameters [3] = "" + max.getY();
} catch (ClassCastException e) {
throw new SecurityException(
"Unable to reconstruct constraint map from stored filter expression. "
+ "Invalid filter format.");
}
} else if (operation.getOperatorId() == OperationDefines.OR) {
LogicalOperation logical = (LogicalOperation) operation;
Iterator it = logical.getArguments().iterator();
ArrayList parameterList = new ArrayList( 10 );
while (it.hasNext()) {
try {
PropertyIsCOMPOperation argument = (PropertyIsCOMPOperation) it.next();
PropertyName propertyName = (PropertyName) argument.getFirstExpression();
if ( constraintName != null &&
(!constraintName.equals(propertyName.getValue() ) ) ) {
throw new SecurityException(
"Unable to reconstruct constraint map from stored " +
"filter expression. Invalid filter format.");
}
constraintName = propertyName.getValue();
parameterList.add(((Literal) argument.getSecondExpression()).getValue());
} catch (ClassCastException e) {
throw new SecurityException(
"Unable to reconstruct constraint map from stored filter expression. "
+ "Invalid filter format.");
}
}
parameters = (String[]) parameterList.toArray( new String[parameterList.size()] );
} else {
throw new SecurityException(
"Unable to reconstruct constraint map from stored filter expression. "
+ "Invalid filter format.");
}
map.put(constraintName, parameters);
}
}/* ********************************************************************
Changes to this class. What the people have been up to:
$Log: InitRightsEditorListener.java,v $
Revision 1.6 2006/08/29 19:54:14 poth
footer corrected
Revision 1.5 2006/07/13 08:10:56 poth
file header added / references to Debug.XXXX removed
Revision 1.4 2006/07/12 14:46:15 poth
comment footer added
********************************************************************** */