/*---------------- 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.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.deegree.enterprise.control.AbstractListener;
import org.deegree.enterprise.control.FormEvent;
import org.deegree.enterprise.control.RPCException;
import org.deegree.enterprise.control.RPCMember;
import org.deegree.enterprise.control.RPCMethodCall;
import org.deegree.enterprise.control.RPCParameter;
import org.deegree.enterprise.control.RPCStruct;
import org.deegree.enterprise.control.RPCWebEvent;
import org.deegree.framework.util.Debug;
import org.deegree.security.GeneralSecurityException;
import org.deegree.security.drm.SecurityAccessManager;
import org.deegree.security.drm.SecurityTransaction;
import org.deegree.security.drm.model.SecuredObject;
/**
* This <code>Listener</code> reacts on 'storeSecuredObjects' events, extracts
* the contained Layer/FeatureType definitions and updates the
* <code>SecurityManager</code> accordingly.
*
* 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 StoreSecuredObjectsListener extends AbstractListener {
public void actionPerformed(FormEvent event) {
Debug.debugMethodBegin();
// keys are Strings (types), values are ArrayLists (which contain
// Strings)
Map newObjectTypes = new HashMap();
// keys are Strings (types), values are ArrayLists (which contain
// Integers)
Map oldObjectTypes = new HashMap();
SecurityAccessManager manager = null;
SecurityTransaction transaction = null;
try {
RPCWebEvent ev = (RPCWebEvent) event;
RPCMethodCall rpcCall = ev.getRPCMethodCall();
RPCParameter[] params = rpcCall.getParameters();
for (int i = 0; i < params.length; i++) {
if (!(params[0].getValue() instanceof RPCStruct)) {
throw new RPCException(
"Invalid RPC. Param elements must contain 'struct'-values.");
}
RPCStruct struct = (RPCStruct) params[i].getValue();
// extract details of one SecuredObject
RPCMember idRPC = struct.getMember("id");
RPCMember nameRPC = struct.getMember("name");
RPCMember typeRPC = struct.getMember("type");
int id;
String name = null;
String type = null;
// extract id
if (idRPC == null) {
throw new RPCException(
"Invalid RPC. Every object must have an 'id'.");
}
if (!(idRPC.getValue() instanceof String)) {
throw new RPCException(
"Invalid RPC. 'id' members must be 'string'-values.");
}
try {
id = Integer.parseInt(((String) idRPC.getValue()));
} catch (NumberFormatException e) {
throw new RPCException(
"Invalid RPC. 'id' members must be valid integer values.");
}
// extract name
if (nameRPC != null) {
if (!(nameRPC.getValue() instanceof String)) {
throw new RPCException(
"Invalid RPC. 'name' members must be 'string'-values.");
}
name = (String) nameRPC.getValue();
}
// extract type
if (typeRPC != null) {
if (!(typeRPC.getValue() instanceof String)) {
throw new RPCException(
"Invalid RPC. 'type' members must be 'string'-values.");
}
type = (String) typeRPC.getValue();
}
if (name == null) {
throw new GeneralSecurityException(
"Every SecuredObject must have a name.");
}
if (type == null) {
throw new GeneralSecurityException(
"Every SecuredObject must have a type.");
}
// new or existing SecuredObject?
if (id == -1) {
ArrayList list = (ArrayList) newObjectTypes.get(type);
if (list == null) {
list = new ArrayList(20);
newObjectTypes.put(type, list);
}
list.add(name);
} else {
ArrayList list = (ArrayList) oldObjectTypes.get(type);
if (list == null) {
list = new ArrayList(20);
oldObjectTypes.put(type, list);
}
list.add(new Integer(id));
}
}
// get Transaction and perform access check
manager = SecurityAccessManager.getInstance();
transaction = SecurityHelper.acquireTransaction(this);
SecurityHelper.checkForAdminRole (transaction);
// remove deleted Layers
SecuredObject[] obsoleteLayers = getObjectsToDelete(
(ArrayList) oldObjectTypes.get(ClientHelper.TYPE_LAYER), transaction
.getAllSecuredObjects(ClientHelper.TYPE_LAYER));
for (int i = 0; i < obsoleteLayers.length; i++) {
transaction.deregisterSecuredObject(obsoleteLayers[i]);
}
// register new Layers
ArrayList newLayerList = (ArrayList) newObjectTypes.get(ClientHelper.TYPE_LAYER);
if (newLayerList != null) {
Iterator it = newLayerList.iterator();
while (it.hasNext()) {
String name = (String) it.next ();
transaction.registerSecuredObject(ClientHelper.TYPE_LAYER, name, name);
}
}
// remove deleted FeatureTypes
SecuredObject[] obsoleteFeatureTypes = getObjectsToDelete(
(ArrayList) oldObjectTypes.get(ClientHelper.TYPE_FEATURETYPE), transaction
.getAllSecuredObjects(ClientHelper.TYPE_FEATURETYPE));
for (int i = 0; i < obsoleteFeatureTypes.length; i++) {
transaction.deregisterSecuredObject(obsoleteFeatureTypes[i]);
}
// register new FeatureTypes
ArrayList newFeatureTypeList = (ArrayList) newObjectTypes.get(ClientHelper.TYPE_FEATURETYPE);
if (newFeatureTypeList != null) {
Iterator it = newFeatureTypeList.iterator();
while (it.hasNext()) {
String name = (String) it.next ();
transaction.registerSecuredObject(ClientHelper.TYPE_FEATURETYPE, name, name);
}
}
manager.commitTransaction(transaction);
transaction = null;
getRequest()
.setAttribute(
"MESSAGE",
"Ihre Änderungen wurden erfolgreich in der Datenbank gespeichert.<BR/>"
+ "<BR/><p><a href='javascript:initSecuredObjectsEditor()'>--> zurück zum"
+ " Layer-/FeatureType-Editor</a></p>");
} catch (RPCException e) {
getRequest().setAttribute("SOURCE", this.getClass().getName());
getRequest().setAttribute(
"MESSAGE",
"Ihre Änderungen konnten nicht in der Datenbank gespeichert werden, "
+ "da Ihre Anfrage fehlerhaft war.<br><br>"
+ "Die Fehlermeldung lautet: <code>"
+ e.getMessage() + "</code>");
setNextPage("error.jsp");
} catch (GeneralSecurityException e) {
e.printStackTrace();
getRequest().setAttribute("SOURCE", this.getClass().getName());
getRequest().setAttribute(
"MESSAGE",
"Ihre Änderungen konnten nicht in der Datenbank gespeichert werden, "
+ "da ein Fehler aufgetreten ist.<br><br>"
+ "Die Fehlermeldung lautet: <code>"
+ e.getMessage() + "</code>");
setNextPage("error.jsp");
} finally {
if (manager != null && transaction != null) {
try {
manager.abortTransaction(transaction);
} catch (GeneralSecurityException ex) {
ex.printStackTrace();
}
}
}
Debug.debugMethodEnd();
}
private SecuredObject[] getObjectsToDelete(ArrayList remainingObjects,
SecuredObject[] presentObjects) {
Set lookup = new HashSet();
ArrayList deleteList = new ArrayList(10);
if (remainingObjects != null) {
lookup = new HashSet(remainingObjects);
}
for (int i = 0; i < presentObjects.length; i++) {
if (!lookup.contains(new Integer(presentObjects[i].getID()))) {
deleteList.add(presentObjects[i]);
}
}
return (SecuredObject[]) deleteList
.toArray(new SecuredObject[deleteList.size()]);
}
}/* ********************************************************************
Changes to this class. What the people have been up to:
$Log: StoreSecuredObjectsListener.java,v $
Revision 1.4 2006/08/29 19:54:14 poth
footer corrected
Revision 1.3 2006/07/13 08:10:56 poth
file header added / references to Debug.XXXX removed
Revision 1.2 2006/07/12 14:46:15 poth
comment footer added
********************************************************************** */