Improve security
authorMathieu Baudier <mbaudier@argeo.org>
Tue, 1 Mar 2011 13:12:33 +0000 (13:12 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Tue, 1 Mar 2011 13:12:33 +0000 (13:12 +0000)
Extend Geotools support

git-svn-id: https://svn.argeo.org/commons/trunk@4250 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

46 files changed:
gis/runtime/org.argeo.gis.geotools/pom.xml
gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/GeoToolsUtils.java [new file with mode: 0644]
gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrIndex.java [new file with mode: 0644]
gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrUtils.java [new file with mode: 0644]
security/dep/org.argeo.security.dep.node/pom.xml
security/modules/org.argeo.security.manager.ldap/META-INF/MANIFEST.MF
security/modules/org.argeo.security.manager.ldap/META-INF/spring/ldap-osgi.xml
security/modules/org.argeo.security.manager.ldap/META-INF/spring/ldap.xml
security/modules/org.argeo.security.manager.ldap/ldap.properties
security/modules/org.argeo.security.services/META-INF/MANIFEST.MF
security/modules/org.argeo.security.services/META-INF/spring/osgi.xml
security/modules/org.argeo.security.services/META-INF/spring/services.xml
security/plugins/org.argeo.security.equinox/plugin.xml
security/plugins/org.argeo.security.ui.application/src/main/java/org/argeo/security/ui/application/AbstractSecureApplication.java
security/runtime/org.argeo.security.activemq/pom.xml
security/runtime/org.argeo.security.core/pom.xml
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ArgeoSecurityDao.java
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ArgeoSecurityService.java
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/CurrentUserDao.java [new file with mode: 0644]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/SystemAuthentication.java [new file with mode: 0644]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/SystemExecutionService.java [new file with mode: 0644]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserAdminDao.java [new file with mode: 0644]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserAdminService.java
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultCurrentUserService.java [new file with mode: 0644]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultSecurityService.java
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/InternalAuthentication.java
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/KeyBasedSystemExecutionService.java [new file with mode: 0644]
security/runtime/org.argeo.security.jackrabbit/.classpath [new file with mode: 0644]
security/runtime/org.argeo.security.jackrabbit/.project [new file with mode: 0644]
security/runtime/org.argeo.security.jackrabbit/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
security/runtime/org.argeo.security.jackrabbit/.settings/org.eclipse.pde.core.prefs [new file with mode: 0644]
security/runtime/org.argeo.security.jackrabbit/build.properties [new file with mode: 0644]
security/runtime/org.argeo.security.jackrabbit/pom.xml [new file with mode: 0644]
security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/spring/GrantedAuthorityPrincipal.java [new file with mode: 0644]
security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/spring/SpringLoginModule.java [new file with mode: 0644]
security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java
security/runtime/pom.xml
server/dep/org.argeo.server.dep.jackrabbit.server/pom.xml
server/modules/org.argeo.server.ext.jackrabbit/META-INF/MANIFEST.MF
server/runtime/org.argeo.server.jackrabbit/pom.xml
server/runtime/org.argeo.server.jcr/build.properties
server/runtime/org.argeo.server.jcr/pom.xml
server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java
server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisNames.java [new file with mode: 0644]
server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisTypes.java [new file with mode: 0644]
server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/gis/argeo_gis.cnd [new file with mode: 0644]

index 46168eb9df82f2721a2c7bc9ec84c84034416a24..92a81f8cd48a2bdbfbc4d9ac4b656882940520cb 100644 (file)
@@ -30,6 +30,7 @@
                                <configuration>
                                        <instructions>
                                                <Export-Package>org.argeo.geotools.*</Export-Package>
+                                               <Import-Package>org.argeo.jcr.gis,*</Import-Package>
                                        </instructions>
                                </configuration>
                        </plugin>
                </plugins>
        </build>
        <dependencies>
-               <!-- Geotools -->
+               <!-- JCR -->
+               <dependency>
+                       <groupId>org.argeo.commons.server</groupId>
+                       <artifactId>org.argeo.server.jcr</artifactId>
+                       <version>${version.argeo-commons}</version>
+               </dependency>
+
+               <!-- Geotools, JTS, etc. -->
                <dependency>
                        <groupId>org.argeo.dep.osgi</groupId>
                        <artifactId>org.argeo.dep.osgi.geotools</artifactId>
                        <groupId>org.argeo.dep.osgi</groupId>
                        <artifactId>org.argeo.dep.osgi.java3d</artifactId>
                </dependency>
+               <!-- For EPSG database -->
+               <dependency>
+                       <groupId>org.hsqldb</groupId>
+                       <artifactId>com.springsource.org.hsqldb</artifactId>
+               </dependency>
                <!-- Apache Commons -->
                <dependency>
                        <groupId>org.apache.commons</groupId>
diff --git a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/GeoToolsUtils.java b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/GeoToolsUtils.java
new file mode 100644 (file)
index 0000000..88ab849
--- /dev/null
@@ -0,0 +1,48 @@
+package org.argeo.geotools;
+
+import java.io.IOException;
+
+import org.argeo.ArgeoException;
+import org.geotools.data.DataStore;
+import org.geotools.data.FeatureSource;
+import org.geotools.data.FeatureStore;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.Name;
+
+/** Utilities related to the GeoTools framework */
+public class GeoToolsUtils {
+
+       /** Opens a read/write feature store */
+       public static FeatureStore<SimpleFeatureType, SimpleFeature> getFeatureStore(
+                       DataStore dataStore, Name name) {
+               FeatureSource<SimpleFeatureType, SimpleFeature> featureSource;
+               try {
+                       featureSource = dataStore.getFeatureSource(name);
+               } catch (IOException e) {
+                       throw new ArgeoException("Cannot open feature source " + name
+                                       + " in data store " + dataStore, e);
+               }
+               if (!(featureSource instanceof FeatureStore)) {
+                       throw new ArgeoException("Feature source " + name
+                                       + " is not writable.");
+               }
+               return (FeatureStore<SimpleFeatureType, SimpleFeature>) featureSource;
+       }
+
+       /** Creates the provided schema in the data store. */
+       public static void createSchemaIfNeeded(DataStore dataStore,
+                       SimpleFeatureType featureType) {
+               try {
+                       dataStore.getSchema(featureType.getName());
+               } catch (IOException e) {
+                       // assume it does not exist
+                       try {
+                               dataStore.createSchema(featureType);
+                       } catch (IOException e1) {
+                               throw new ArgeoException("Cannot create schema " + featureType,
+                                               e);
+                       }
+               }
+       }
+}
diff --git a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrIndex.java b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrIndex.java
new file mode 100644 (file)
index 0000000..e6afb94
--- /dev/null
@@ -0,0 +1,234 @@
+package org.argeo.geotools.jcr;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventIterator;
+import javax.jcr.observation.EventListener;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.ArgeoException;
+import org.argeo.geotools.GeoToolsUtils;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.gis.GisNames;
+import org.argeo.jcr.gis.GisTypes;
+import org.argeo.security.SystemExecutionService;
+import org.geotools.data.DataStore;
+import org.geotools.data.DefaultTransaction;
+import org.geotools.data.FeatureStore;
+import org.geotools.data.Transaction;
+import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.FeatureCollections;
+import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
+import org.geotools.filter.FilterFactoryImpl;
+import org.geotools.referencing.CRS;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.FilterFactory2;
+import org.opengis.filter.identity.FeatureId;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.MathTransform;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.Point;
+
+public class GeoJcrIndex implements EventListener {
+       public final static SimpleFeatureType JCR_POINT;
+
+       final static String JCR_POINT_NAME = "JCR_POINT";
+       // PostGIS convention
+       final static String DEFAULT_GEOM_NAME = "the_geom";
+
+       private final static Log log = LogFactory.getLog(GeoJcrIndex.class);
+
+       static {
+               SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
+               builder.setNamespaceURI(GisNames.GIS_NAMESPACE);
+               builder.setName(JCR_POINT_NAME);
+
+               builder.setDefaultGeometry(DEFAULT_GEOM_NAME);
+               builder.add(DEFAULT_GEOM_NAME, Point.class);
+
+               builder.add(JcrUtils.normalize(Property.JCR_UUID), String.class);
+               builder.add(JcrUtils.normalize(Property.JCR_PATH), String.class);
+               builder.add(JcrUtils.normalize(Property.JCR_PRIMARY_TYPE), String.class);
+               // mix:created
+               // builder.add(JcrUtils.normalize(Property.JCR_CREATED), Date.class);
+               // builder.add(JcrUtils.normalize(Property.JCR_CREATED_BY),
+               // String.class);
+               // mix:lastModified
+               builder.add(JcrUtils.normalize(Property.JCR_LAST_MODIFIED), Date.class);
+               builder.add(JcrUtils.normalize(Property.JCR_LAST_MODIFIED_BY),
+                               String.class);
+
+               JCR_POINT = builder.buildFeatureType();
+       }
+
+       private DataStore dataStore;
+       private FeatureStore<SimpleFeatureType, SimpleFeature> pointsIndex;
+       private Session session;
+       private SystemExecutionService systemExecutionService;
+
+       // TODO: use common factory finder?
+       private FilterFactory2 ff = new FilterFactoryImpl();
+
+       // TODO: use finder?
+       private GeometryFactory geometryFactory = new GeometryFactory();
+
+       public void init() {
+               GeoToolsUtils.createSchemaIfNeeded(dataStore, JCR_POINT);
+               pointsIndex = GeoToolsUtils.getFeatureStore(dataStore,
+                               JCR_POINT.getName());
+
+               systemExecutionService.executeAsSystem(new Runnable() {
+                       public void run() {
+                               try {
+                                       session.getWorkspace()
+                                                       .getObservationManager()
+                                                       .addEventListener(GeoJcrIndex.this,
+                                                                       Event.NODE_ADDED | Event.NODE_REMOVED, "/",
+                                                                       true, null,
+                                                                       new String[] { GisTypes.GIS_GEOMETRY },
+                                                                       false);
+                               } catch (RepositoryException e) {
+                                       throw new ArgeoException("Cannot initialize GeoJcr index",
+                                                       e);
+                               }
+
+                       }
+               });
+       }
+
+       public void dispose() {
+       }
+
+       public void onEvent(EventIterator events) {
+               FeatureCollection<SimpleFeatureType, SimpleFeature> pointsToAdd = FeatureCollections
+                               .newCollection();
+               Set<FeatureId> pointsToRemove = new HashSet<FeatureId>();
+               while (events.hasNext()) {
+                       Event event = events.nextEvent();
+                       try {
+                               Integer eventType = event.getType();
+                               if (Event.NODE_ADDED == eventType) {
+                                       Node node = session.getNodeByIdentifier(event
+                                                       .getIdentifier());
+                                       if (node.isNodeType(GisTypes.GIS_POINT)) {
+                                               Point point = nodeToPoint(node);
+                                               SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(
+                                                               JCR_POINT);
+                                               featureBuilder.set(DEFAULT_GEOM_NAME, point);
+                                               mapNodeToFeature(node, featureBuilder);
+                                               pointsToAdd.add(featureBuilder.buildFeature(node
+                                                               .getIdentifier()));
+                                       }
+                               } else if (Event.NODE_REMOVED == eventType) {
+                                       String id = event.getIdentifier();
+                                       pointsToRemove.add(ff.featureId(id));
+                               }
+                       } catch (Exception e) {
+                               log.error("Cannot process event " + event, e);
+                       }
+               }
+
+               // persist
+               // TODO: this may be more optimal to persist in one single transaction,
+               // but we will loose modifications on all nodes if one fails
+               try {
+                       Transaction transaction = new DefaultTransaction();
+                       pointsIndex.setTransaction(transaction);
+                       try {
+                               // points
+                               pointsIndex.addFeatures(pointsToAdd);
+                               if (pointsToRemove.size() != 0)
+                                       pointsIndex.removeFeatures(ff.id(pointsToRemove));
+                               transaction.commit();
+                       } catch (Exception e) {
+                               transaction.rollback();
+                               throw new ArgeoException("Cannot persist changes", e);
+                       } finally {
+                               transaction.close();
+                       }
+               } catch (ArgeoException e) {
+                       throw e;
+               } catch (IOException e) {
+                       throw new ArgeoException("Unexpected issue with the transaction", e);
+               }
+       }
+
+       protected void mapNodeToFeature(Node node,
+                       SimpleFeatureBuilder featureBuilder) {
+               try {
+                       featureBuilder.set(JcrUtils.normalize(Property.JCR_UUID),
+                                       node.getIdentifier());
+                       featureBuilder.set(JcrUtils.normalize(Property.JCR_PATH),
+                                       node.getPath());
+                       featureBuilder.set(JcrUtils.normalize(Property.JCR_PRIMARY_TYPE),
+                                       node.getPrimaryNodeType().getName());
+                       if (node.hasProperty(Property.JCR_LAST_MODIFIED))
+                               featureBuilder.set(
+                                               JcrUtils.normalize(Property.JCR_LAST_MODIFIED), node
+                                                               .getProperty(Property.JCR_LAST_MODIFIED)
+                                                               .getDate().getTime());
+                       if (node.hasProperty(Property.JCR_LAST_MODIFIED_BY))
+                               featureBuilder
+                                               .set(JcrUtils.normalize(Property.JCR_LAST_MODIFIED_BY),
+                                                               node.getProperty(Property.JCR_LAST_MODIFIED_BY)
+                                                                               .getString());
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot map " + node + " to "
+                                       + featureBuilder.getFeatureType(), e);
+               }
+       }
+
+       /** Return the node as a point in the CRS of the related feature store. */
+       protected Point nodeToPoint(Node node) {
+               CoordinateReferenceSystem featureStoreCrs = pointsIndex.getSchema()
+                               .getCoordinateReferenceSystem();
+               DirectPosition nodePosition = GeoJcrUtils.nodeToPosition(node);
+               CoordinateReferenceSystem nodeCrs = nodePosition
+                               .getCoordinateReferenceSystem();
+
+               // transform if not same CRS
+               DirectPosition targetPosition;
+               if (!featureStoreCrs.getIdentifiers().contains(nodeCrs.getName())) {
+                       MathTransform transform;
+                       try {
+                               transform = CRS.findMathTransform(nodeCrs, featureStoreCrs);
+                               targetPosition = transform.transform(nodePosition, null);
+                       } catch (Exception e) {
+                               throw new ArgeoException("Cannot transform from " + nodeCrs
+                                               + " to " + featureStoreCrs, e);
+                       }
+               } else {
+                       targetPosition = nodePosition;
+               }
+               double[] coo = targetPosition.getCoordinate();
+               return geometryFactory.createPoint(new Coordinate(coo[0], coo[1]));
+       }
+
+       public void setDataStore(DataStore dataStore) {
+               this.dataStore = dataStore;
+       }
+
+       public void setSession(Session session) {
+               this.session = session;
+       }
+
+       public void setSystemExecutionService(
+                       SystemExecutionService systemExecutionService) {
+               this.systemExecutionService = systemExecutionService;
+       }
+
+}
diff --git a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrUtils.java b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrUtils.java
new file mode 100644 (file)
index 0000000..7b390ca
--- /dev/null
@@ -0,0 +1,98 @@
+package org.argeo.geotools.jcr;
+
+import javax.jcr.Node;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.gis.GisNames;
+import org.argeo.jcr.gis.GisTypes;
+import org.geotools.geometry.DirectPosition2D;
+import org.geotools.referencing.CRS;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.Point;
+
+/** Utilities to map JCR from/to JTS and GeoTools */
+public class GeoJcrUtils {
+       private final static Log log = LogFactory.getLog(GeoJcrUtils.class);
+
+       /** Transforms a geometry node into position within its CRS */
+       public static DirectPosition nodeToPosition(Node node) {
+               try {
+                       if (node.isNodeType(GisTypes.GIS_POINT)) {
+                               CoordinateReferenceSystem crs = getCoordinateReferenceSystem(node);
+                               Point point = (Point) nodeToGeometry(node);
+                               return new DirectPosition2D(crs, point.getX(), point.getY());
+                       } else {
+                               throw new ArgeoException(node + " is not of a supported type");
+                       }
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot extract position from " + node, e);
+               }
+       }
+
+       /** Transforms a geometry node into a JTS geometry. */
+       public static Geometry nodeToGeometry(Node node) {
+               try {
+                       if (node.isNodeType(GisTypes.GIS_POINT)
+                                       || node.isNodeType(GisTypes.GIS_COORDINATE)) {
+                               Coordinate coo;
+                               if (node.hasProperty(GisNames.GIS_Z))
+                                       coo = new Coordinate(node.getProperty(GisNames.GIS_X)
+                                                       .getDouble(), node.getProperty(GisNames.GIS_Y)
+                                                       .getDouble(), node.getProperty(GisNames.GIS_Z)
+                                                       .getDouble());
+                               else
+                                       coo = new Coordinate(node.getProperty(GisNames.GIS_X)
+                                                       .getDouble(), node.getProperty(GisNames.GIS_Y)
+                                                       .getDouble());
+
+                               // TODO: use factory finder
+                               // GeometryFactory geometryFactory =
+                               // JTSFactoryFinder.getGeometryFactory(null);
+                               GeometryFactory geometryFactory = new GeometryFactory();
+                               return geometryFactory.createPoint(coo);
+                       } else {
+                               throw new ArgeoException(node + " is not of a supported type");
+                       }
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot map " + node + " to a geometry", e);
+               }
+       }
+
+       /** Reads and interpret the coordinate reference system from a node. */
+       public static CoordinateReferenceSystem getCoordinateReferenceSystem(
+                       Node node) {
+               try {
+                       if (!node.isNodeType(GisTypes.GIS_GEOMETRY))
+                               throw new ArgeoException(node + " is not of type "
+                                               + GisTypes.GIS_GEOMETRY);
+                       // Coordinate reference system
+                       String srs = node.getProperty(GisNames.GIS_SRS).getString();
+                       CoordinateReferenceSystem crs;
+                       try {
+                               // first, try to decode an EPSG code
+                               crs = CRS.decode(srs);
+                       } catch (Exception e) {
+                               // if it fails, try a WKT
+                               try {
+                                       crs = CRS.parseWKT(srs);
+                               } catch (Exception e1) {
+                                       // if it fails as well, log the error
+                                       log.error("Cannot parse WKT " + srs, e1);
+                                       // and then the previous error (probably more relevant)
+                                       throw e;
+                               }
+                       }
+                       return crs;
+               } catch (Exception e) {
+                       throw new ArgeoException(
+                                       "Cannot get coordinate reference system for " + node, e);
+               }
+       }
+}
index fa40e2525c2ab968a4c437dc33580cacbc80563c..4e2d71be78459de7ad6c9d2f78d3b49fc7d28836 100644 (file)
                        <version>${version.argeo-commons}</version>
                        <type>pom</type>
                </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons.security</groupId>
+                       <artifactId>org.argeo.security.activemq</artifactId>
+                       <version>${version.argeo-commons}</version>
+               </dependency>
                <!-- Jackrabbit -->
                <dependency>
                        <groupId>org.argeo.commons.server</groupId>
                        <artifactId>org.argeo.server.jackrabbit</artifactId>
                        <version>${version.argeo-commons}</version>
                </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons.security</groupId>
+                       <artifactId>org.argeo.security.jackrabbit</artifactId>
+                       <version>${version.argeo-commons}</version>
+               </dependency>
                <dependency>
                        <groupId>org.argeo.commons.server</groupId>
                        <artifactId>org.argeo.server.jcr.mvc</artifactId>
index b800a45c9948322a173e80aec5fa159544c7f098..5325587bb713daea564007ad035f1680ef7094f8 100644 (file)
@@ -9,13 +9,12 @@ Import-Package: com.sun.jndi.ldap;resolution:=optional,
  org.springframework.beans.factory.config,
  org.springframework.ldap.core.support,
  org.springframework.security,
- org.springframework.security.adapters;specification-version="2.0.4.A",
  org.springframework.security.ldap,
  org.springframework.security.ldap.populator,
  org.springframework.security.providers,
+ org.springframework.security.providers.encoding;specification-version="2.0.6.RELEASE",
  org.springframework.security.providers.ldap,
  org.springframework.security.providers.ldap.authenticator,
- org.springframework.security.providers.rememberme;specification-version="2.0.4.A",
  org.springframework.security.userdetails,
  org.springframework.security.userdetails.ldap
 Bundle-Name: Security Manager LDAP
index 12f8909eb28da77ac58ebcde2e1e0ce5eac984fb..b3a95cefc84e9e132bc449df9249fc9823aa750a 100644 (file)
@@ -6,19 +6,22 @@
        http://www.springframework.org/schema/beans   \r
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
 \r
-       <service ref="_authenticationManager"\r
-               interface="org.springframework.security.AuthenticationManager"\r
-               context-class-loader="service-provider" />\r
+       <!-- REFERENCES -->\r
+       <list id="userNatureMappers" interface="org.argeo.security.ldap.UserNatureMapper"\r
+               cardinality="0..N" />\r
 \r
+       <!-- SERVICES -->\r
+       <service ref="passwordEncoder"\r
+               interface="org.springframework.security.providers.encoding.PasswordEncoder" />\r
+       <service ref="authenticationProvider"\r
+               interface="org.springframework.security.providers.AuthenticationProvider"\r
+               context-class-loader="service-provider" />\r
        <service ref="securityDao" interface="org.argeo.security.ArgeoSecurityDao"\r
                context-class-loader="service-provider" />\r
        <service ref="userDetailsService"\r
                interface="org.springframework.security.userdetails.UserDetailsService"\r
                context-class-loader="service-provider" />\r
 \r
-       <list id="userNatureMappers" interface="org.argeo.security.ldap.UserNatureMapper"\r
-               cardinality="0..N" />\r
-\r
        <!-- Provides deserialization -->\r
        <service interface="org.argeo.server.json.JsonObjectFactory">\r
                <beans:bean class="org.argeo.server.json.JsonObjectFactoryImpl" />\r
index bd117530d814198547a7cabce1219ca861e708a8..0c3c8a68453a38ef2276f49bf04daeced2e6edfe 100644 (file)
                </property>
        </bean>
 
-       <bean id="_authenticationManager" class="org.springframework.security.providers.ProviderManager">
-               <property name="providers">
-                       <list>
-                               <bean class="org.springframework.security.adapters.AuthByAdapterProvider">
-                                       <property name="key" value="${argeo.security.systemKey}" />
-                               </bean>
-                               <bean
-                                       class="org.springframework.security.providers.rememberme.RememberMeAuthenticationProvider">
-                                       <property name="key" value="${argeo.security.systemKey}" />
-                               </bean>
-                               <ref bean="authenticationProvider" />
-                       </list>
-               </property>
-       </bean>
+       <bean id="passwordEncoder"
+               class="org.springframework.security.providers.ldap.authenticator.LdapShaPasswordEncoder" />
 
        <bean id="contextSource"
                class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
index bb429829226011e6a49aec96fd5a16e305c3fdcf..1b24ee3d16d6551659255c792b9dbb6eff23b4a3 100644 (file)
@@ -4,5 +4,3 @@ argeo.ldap.host=localhost
 argeo.ldap.port=10389
 argeo.ldap.manager.userdn=uid=admin,ou=system
 argeo.ldap.manager.password=secret
-
-argeo.security.systemKey=argeo
index d005b164f44c1fca9e8fa4a074da2a976bf6c7ad..3d22df281a9d82c96a7fe7c6884d209a78f8406b 100644 (file)
@@ -3,5 +3,9 @@ Bundle-Version: 0.2.3.SNAPSHOT
 Import-Package: org.argeo.security,
  org.argeo.security.core,
  org.springframework.beans.factory.config;specification-version="2.5.6.SEC01",
- org.springframework.security;specification-version="2.0.4.A"
+ org.springframework.security;specification-version="2.0.4.A",
+ org.springframework.security.adapters;specification-version="2.0.6.RELEASE",
+ org.springframework.security.providers;specification-version="2.0.6.RELEASE",
+ org.springframework.security.providers.encoding;specification-version="2.0.6.RELEASE",
+ org.springframework.security.providers.rememberme;specification-version="2.0.6.RELEASE"
 Bundle-Name: Security Services
index 8913486fc10129adb534c9b2480c83c22bd44bc6..62872b1c0ac2335d679e3bf23ffc5eccf879840a 100644 (file)
@@ -6,8 +6,21 @@
        http://www.springframework.org/schema/beans   \r
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
 \r
-       <service ref="securityService" interface="org.argeo.security.ArgeoSecurityService" />\r
+       <!-- REFERENCES -->\r
+       <reference id="passwordEncoder"\r
+               interface="org.springframework.security.providers.encoding.PasswordEncoder" />\r
 \r
        <reference id="securityDao" interface="org.argeo.security.ArgeoSecurityDao" />\r
-       <reference id="authenticationManager" interface="org.springframework.security.AuthenticationManager" />\r
+\r
+       <reference id="authenticationProvider"\r
+               interface="org.springframework.security.providers.AuthenticationProvider" />\r
+\r
+       <!-- SERVICES -->\r
+       <service ref="securityService" interface="org.argeo.security.ArgeoSecurityService" />\r
+       <service ref="securityService" interface="org.argeo.security.CurrentUserService" />\r
+       <service ref="securityService" interface="org.argeo.security.UserAdminService" />\r
+       <service ref="systemExecutionService" interface="org.argeo.security.SystemExecutionService" />\r
+\r
+       <service ref="authenticationManager"\r
+               interface="org.springframework.security.AuthenticationManager" />\r
 </beans:beans>
\ No newline at end of file
index 97fe92eda942ce6d0212323677f0bab8d20200eb..bb79de26555d897065b83007998ea4afc2a8938e 100644 (file)
 
        <bean id="securityService" class="org.argeo.security.core.DefaultSecurityService">
                <property name="securityDao" ref="securityDao" />
+               <property name="passwordEncoder" ref="passwordEncoder" />
                <property name="authenticationManager" ref="authenticationManager" />
                <property name="systemAuthenticationKey" value="${argeo.security.systemKey}" />
        </bean>
+
+       <bean id="systemExecutionService" class="org.argeo.security.core.KeyBasedSystemExecutionService">
+               <property name="authenticationManager" ref="authenticationManager" />
+               <property name="systemAuthenticationKey" value="${argeo.security.systemKey}" />
+       </bean>
+
+       <bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
+               <property name="providers">
+                       <list>
+                               <bean class="org.springframework.security.adapters.AuthByAdapterProvider">
+                                       <property name="key" value="${argeo.security.systemKey}" />
+                               </bean>
+                               <bean
+                                       class="org.springframework.security.providers.rememberme.RememberMeAuthenticationProvider">
+                                       <property name="key" value="${argeo.security.systemKey}" />
+                               </bean>
+                               <ref bean="authenticationProvider" />
+                       </list>
+               </property>
+       </bean>
 </beans>
\ No newline at end of file
index b407360acdca0a921c647c7c7bc33b3d1f86287d..78f0d9cb12dcadb18b31c23654ce11ef777bc99c 100644 (file)
@@ -19,8 +19,8 @@
    </extension>
   <extension
         id="springLoginModule"
-        point="org.eclipse.equinox.security.loginModule">
-        name="Spring Login Module"
+        point="org.eclipse.equinox.security.loginModule"
+        name="Spring Login Module">
      <loginModule
            class="org.argeo.eclipse.spring.SpringExtensionFactory"
            description="Spring Login Module">
index a0a2f922bbe31bc16384c087a80cf64c613582ff..9550660004fbb22a4c9376c3ca42ae3c4073195d 100644 (file)
@@ -16,13 +16,16 @@ import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.application.WorkbenchAdvisor;
 
+/**
+ * Common base class for authenticated access to the Eclipse UI framework (RAP and
+ * RCP)
+ */
 public abstract class AbstractSecureApplication implements IApplication {
        private static final Log log = LogFactory
                        .getLog(AbstractSecureApplication.class);
 
        protected abstract WorkbenchAdvisor createWorkbenchAdvisor();
 
-       @SuppressWarnings("unchecked")
        public Object start(IApplicationContext context) throws Exception {
 
                Integer returnCode = null;
@@ -51,8 +54,7 @@ public abstract class AbstractSecureApplication implements IApplication {
                                ErrorDialog.openError(null, "Error", "Shutdown...", status);
                                return status.getSeverity();
                        }
-                       if (log.isDebugEnabled())
-                               log.debug("Logged in as " + username);
+
                        returnCode = (Integer) Subject.doAs(subject, getRunAction(display));
                        SecureApplicationActivator.getLoginContext().logout();
                        return processReturnCode(returnCode);
index 0405a5c057d995464aa766de62092714ede03e93..d9e4089567f81e8c7c283460436f10734b00e6cc 100644 (file)
                <dependency>
                        <groupId>org.argeo.commons.basic</groupId>
                        <artifactId>org.argeo.basic.nodeps</artifactId>
-                       <version>0.2.3-SNAPSHOT</version>
+                       <version>${version.argeo-commons}</version>
                </dependency>
                <dependency>
                        <groupId>org.argeo.commons.security</groupId>
                        <artifactId>org.argeo.security.core</artifactId>
-                       <version>0.2.3-SNAPSHOT</version>
+                       <version>${version.argeo-commons}</version>
                </dependency>
 
                <!-- Spring -->
index b36f10d56e7dfddd7d0e48338a13e2774f46f48f..5c9a1f9eb05c204891d5e4908e5e20b702782ba6 100644 (file)
                        <groupId>org.springframework.security</groupId>
                        <artifactId>org.springframework.security.core</artifactId>
                </dependency>
-
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>org.springframework.transaction</artifactId>
+               </dependency>
                <!-- Logging -->
                <dependency>
                        <groupId>org.slf4j</groupId>
index 67c4cb2ec39e9e315e3c2fa486aa9b72914020ed..81baa5e2853c1b05792ff5e696207a2b93de43f1 100644 (file)
 
 package org.argeo.security;
 
-import java.util.Set;
 
 /**
  * Access to the users and roles referential (dependent from the underlying
  * storage, e.g. LDAP).
  */
-public interface ArgeoSecurityDao {
-       // public ArgeoUser getCurrentUser();
-
-       /** List all users */
-       public Set<ArgeoUser> listUsers();
-
-       /** List roles that can be modified */
-       public Set<String> listEditableRoles();
-
-       /**
-        * Creates a new user in the underlying storage. <b>DO NOT CALL DIRECTLY</b>
-        * use {@link ArgeoSecurityService#newUser(ArgeoUser)} instead.
-        */
-       public void createUser(ArgeoUser user);
-
-       public void updateUser(ArgeoUser user);
-
-       public void deleteUser(String username);
-
-       /**
-        * Creates a new role in the underlying storage. <b>DO NOT CALL DIRECTLY</b>
-        * use {@link ArgeoSecurityService#newRole(String)} instead.
-        */
-       public void createRole(String role, String superuserName);
-
-       public void deleteRole(String role);
-
-       /** List all users having this role. */
-       public Set<ArgeoUser> listUsersInRole(String role);
-
-       public Boolean userExists(String username);
-
-       public ArgeoUser getUser(String username);
-
-       public ArgeoUser getUserWithPassword(String username);
-
-       public String getDefaultRole();
-
-       /** Validates a raw password against an encoded one. */
-       public Boolean isPasswordValid(String encoded, String raw);
-
-       /** Encodes a raw password. */
-       public String encodePassword(String raw);
+@Deprecated
+public interface ArgeoSecurityDao extends CurrentUserDao,UserAdminDao{
 }
index 76933e0e566d670f0b1254700edb36af5a11a866..172fba1895afeedb07437bcbbba6f62a99915c93 100644 (file)
@@ -21,6 +21,7 @@ package org.argeo.security;
  * High level access to the user referential (independent from the underlying
  * storage).
  */
+@Deprecated
 public interface ArgeoSecurityService extends CurrentUserService,
                UserAdminService {
 }
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/CurrentUserDao.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/CurrentUserDao.java
new file mode 100644 (file)
index 0000000..b9fee6f
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ *
+ * 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.
+ */
+
+package org.argeo.security;
+
+/**
+ * Access to user backend for the currently logged in user
+ */
+public interface CurrentUserDao {
+       public void updateUser(ArgeoUser user);
+
+       public String getDefaultRole();
+
+}
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/SystemAuthentication.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/SystemAuthentication.java
new file mode 100644 (file)
index 0000000..0aa5533
--- /dev/null
@@ -0,0 +1,8 @@
+package org.argeo.security;
+
+/**
+ * Marks a system authentication, that is which did not require a login process.
+ */
+public interface SystemAuthentication {
+
+}
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/SystemExecutionService.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/SystemExecutionService.java
new file mode 100644 (file)
index 0000000..f5ef357
--- /dev/null
@@ -0,0 +1,18 @@
+package org.argeo.security;
+
+import org.springframework.core.task.TaskExecutor;
+
+/**
+ * Allows to execute code authenticated as a system user (that is not a real
+ * person)
+ */
+public interface SystemExecutionService {
+       /**
+        * Executes this Runnable within a system authenticated context.
+        * Implementations should make sure that this method is properly secured via
+        * Java permissions since it could access to everything without credentials.
+        */
+       public void executeAsSystem(Runnable runnable);
+       
+       public TaskExecutor createSystemAuthenticatedTaskExecutor();
+}
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserAdminDao.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserAdminDao.java
new file mode 100644 (file)
index 0000000..0d07dae
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ *
+ * 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.
+ */
+
+package org.argeo.security;
+
+import java.util.Set;
+
+/**
+ * Access to the users and roles referential (dependent from the underlying
+ * storage, e.g. LDAP).
+ */
+public interface UserAdminDao{
+       /** List all users */
+       public Set<ArgeoUser> listUsers();
+
+       /** List roles that can be modified */
+       public Set<String> listEditableRoles();
+
+       /**
+        * Creates a new user in the underlying storage. <b>DO NOT CALL DIRECTLY</b>
+        * use {@link ArgeoSecurityService#newUser(ArgeoUser)} instead.
+        */
+       public void createUser(ArgeoUser user);
+
+       public void deleteUser(String username);
+
+       /**
+        * Creates a new role in the underlying storage. <b>DO NOT CALL DIRECTLY</b>
+        * use {@link ArgeoSecurityService#newRole(String)} instead.
+        */
+       public void createRole(String role, String superuserName);
+
+       public void deleteRole(String role);
+
+       /** List all users having this role. */
+       public Set<ArgeoUser> listUsersInRole(String role);
+
+       public Boolean userExists(String username);
+
+       public ArgeoUser getUser(String username);
+
+       public ArgeoUser getUserWithPassword(String username);
+}
index 47ea65ecccc1fda91d337c826f0c5b7f4b96ed45..4bd887ec7224bd0096215952ec7f36323c1277ce 100644 (file)
@@ -35,5 +35,7 @@ public interface UserAdminService {
        /*
         * SYSTEM
         */
+       @Deprecated
+       /** @deprecated Use ${link SystemExecutionService} instead.*/
        public Runnable wrapWithSystemAuthentication(final Runnable runnable);
 }
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultCurrentUserService.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultCurrentUserService.java
new file mode 100644 (file)
index 0000000..49e9efe
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ *
+ * 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.
+ */
+
+package org.argeo.security.core;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Map;
+import java.util.Random;
+
+import org.argeo.ArgeoException;
+import org.argeo.security.ArgeoUser;
+import org.argeo.security.CurrentUserDao;
+import org.argeo.security.CurrentUserService;
+import org.argeo.security.SimpleArgeoUser;
+import org.argeo.security.UserNature;
+import org.springframework.security.providers.encoding.PasswordEncoder;
+
+public class DefaultCurrentUserService implements CurrentUserService {
+       private CurrentUserDao currentUserDao;
+       private PasswordEncoder passwordEncoder;
+       private Random random;
+
+       public DefaultCurrentUserService() {
+               try {
+                       random = SecureRandom.getInstance("SHA1PRNG");
+               } catch (NoSuchAlgorithmException e) {
+                       random = new Random(System.currentTimeMillis());
+               }
+       }
+
+       public ArgeoUser getCurrentUser() {
+               ArgeoUser argeoUser = ArgeoUserDetails.securityContextUser();
+               if (argeoUser == null)
+                       return null;
+               if (argeoUser.getRoles().contains(currentUserDao.getDefaultRole()))
+                       argeoUser.getRoles().remove(currentUserDao.getDefaultRole());
+               return argeoUser;
+       }
+
+       public void updateCurrentUserPassword(String oldPassword, String newPassword) {
+               SimpleArgeoUser user = new SimpleArgeoUser(getCurrentUser());
+               if (!passwordEncoder.isPasswordValid(user.getPassword(), oldPassword,
+                               null))
+                       throw new ArgeoException("Old password is not correct.");
+               user.setPassword(encodePassword(newPassword));
+               currentUserDao.updateUser(user);
+       }
+
+       protected String encodePassword(String password) {
+               byte[] salt = new byte[16];
+               random.nextBytes(salt);
+               return passwordEncoder.encodePassword(password, salt);
+       }
+
+       public void updateCurrentUserNatures(Map<String, UserNature> userNatures) {
+               // TODO Auto-generated method stub
+
+       }
+
+       public void setCurrentUserDao(CurrentUserDao dao) {
+               this.currentUserDao = dao;
+       }
+
+       public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
+               this.passwordEncoder = passwordEncoder;
+       }
+
+}
index e005e1ad4fac8bcb794417a56322c25381141078..68f97d4a069e3eaa73257d943da72913ea5bf24d 100644 (file)
 package org.argeo.security.core;
 
 import java.util.Iterator;
-import java.util.Map;
 import java.util.Set;
 
-import org.argeo.ArgeoException;
 import org.argeo.security.ArgeoSecurity;
 import org.argeo.security.ArgeoSecurityDao;
 import org.argeo.security.ArgeoSecurityService;
 import org.argeo.security.ArgeoUser;
 import org.argeo.security.SimpleArgeoUser;
-import org.argeo.security.UserNature;
+import org.argeo.security.UserAdminService;
 import org.springframework.core.task.SimpleAsyncTaskExecutor;
 import org.springframework.core.task.TaskExecutor;
 import org.springframework.security.Authentication;
@@ -34,22 +32,14 @@ import org.springframework.security.AuthenticationManager;
 import org.springframework.security.context.SecurityContext;
 import org.springframework.security.context.SecurityContextHolder;
 
-public class DefaultSecurityService implements ArgeoSecurityService {
+public class DefaultSecurityService extends DefaultCurrentUserService implements
+               UserAdminService, ArgeoSecurityService {
        private ArgeoSecurity argeoSecurity = new DefaultArgeoSecurity();
        private ArgeoSecurityDao securityDao;
        private AuthenticationManager authenticationManager;
 
        private String systemAuthenticationKey;
 
-       public ArgeoUser getCurrentUser() {
-               ArgeoUser argeoUser = ArgeoUserDetails.securityContextUser();
-               if (argeoUser == null)
-                       return null;
-               if (argeoUser.getRoles().contains(securityDao.getDefaultRole()))
-                       argeoUser.getRoles().remove(securityDao.getDefaultRole());
-               return argeoUser;
-       }
-
        public ArgeoSecurityDao getSecurityDao() {
                return securityDao;
        }
@@ -61,15 +51,7 @@ public class DefaultSecurityService implements ArgeoSecurityService {
        public void updateUserPassword(String username, String password) {
                SimpleArgeoUser user = new SimpleArgeoUser(
                                securityDao.getUser(username));
-               user.setPassword(securityDao.encodePassword(password));
-               securityDao.updateUser(user);
-       }
-
-       public void updateCurrentUserPassword(String oldPassword, String newPassword) {
-               SimpleArgeoUser user = new SimpleArgeoUser(getCurrentUser());
-               if (!securityDao.isPasswordValid(user.getPassword(), oldPassword))
-                       throw new ArgeoException("Old password is not correct.");
-               user.setPassword(securityDao.encodePassword(newPassword));
+               user.setPassword(encodePassword(password));
                securityDao.updateUser(user);
        }
 
@@ -78,11 +60,11 @@ public class DefaultSecurityService implements ArgeoSecurityService {
                // normalize password
                if (user instanceof SimpleArgeoUser) {
                        if (user.getPassword() == null || user.getPassword().equals(""))
-                               ((SimpleArgeoUser) user).setPassword(securityDao
-                                               .encodePassword(user.getUsername()));
+                               ((SimpleArgeoUser) user).setPassword(encodePassword(user
+                                               .getUsername()));
                        else if (!user.getPassword().startsWith("{"))
-                               ((SimpleArgeoUser) user).setPassword(securityDao
-                                               .encodePassword(user.getPassword()));
+                               ((SimpleArgeoUser) user).setPassword(encodePassword(user
+                                               .getPassword()));
                }
                securityDao.createUser(user);
        }
@@ -101,7 +83,7 @@ public class DefaultSecurityService implements ArgeoSecurityService {
                        password = securityDao.getUserWithPassword(user.getUsername())
                                        .getPassword();
                if (!password.startsWith("{"))
-                       password = securityDao.encodePassword(user.getPassword());
+                       password = encodePassword(user.getPassword());
                SimpleArgeoUser simpleArgeoUser = new SimpleArgeoUser(user);
                simpleArgeoUser.setPassword(password);
                securityDao.updateUser(simpleArgeoUser);
@@ -116,6 +98,7 @@ public class DefaultSecurityService implements ArgeoSecurityService {
                securityDao.deleteRole(role);
        }
 
+       @Deprecated
        public TaskExecutor createSystemAuthenticatedTaskExecutor() {
                return new SimpleAsyncTaskExecutor() {
                        private static final long serialVersionUID = -8126773862193265020L;
@@ -133,6 +116,7 @@ public class DefaultSecurityService implements ArgeoSecurityService {
         * Wraps another runnable, adding security context <br/>
         * TODO: secure the call to this method with Java Security
         */
+       @Deprecated
        public Runnable wrapWithSystemAuthentication(final Runnable runnable) {
                return new Runnable() {
 
@@ -162,11 +146,6 @@ public class DefaultSecurityService implements ArgeoSecurityService {
                return lst;
        }
 
-       public void updateCurrentUserNatures(Map<String, UserNature> userNatures) {
-               // TODO Auto-generated method stub
-
-       }
-
        public Set<ArgeoUser> listUsers() {
                return securityDao.listUsers();
        }
@@ -182,6 +161,7 @@ public class DefaultSecurityService implements ArgeoSecurityService {
 
        public void setSecurityDao(ArgeoSecurityDao dao) {
                this.securityDao = dao;
+               setCurrentUserDao(dao);
        }
 
        public void setAuthenticationManager(
index 9b65ee04228c4ce33925737346748db23538fc06..f20f6805bdb5c4a6042ce3a4a631f330365e18bc 100644 (file)
 
 package org.argeo.security.core;
 
+import org.argeo.security.SystemAuthentication;
 import org.springframework.security.GrantedAuthority;
 import org.springframework.security.GrantedAuthorityImpl;
 import org.springframework.security.adapters.PrincipalSpringSecurityUserToken;
 
-public class InternalAuthentication extends PrincipalSpringSecurityUserToken {
+public class InternalAuthentication extends PrincipalSpringSecurityUserToken
+               implements SystemAuthentication {
        private static final long serialVersionUID = -6783376375615949315L;
        public final static String DEFAULT_SYSTEM_USERNAME = "system";
        public final static String DEFAULT_SYSTEM_ROLE = "ROLE_SYSTEM";
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/KeyBasedSystemExecutionService.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/KeyBasedSystemExecutionService.java
new file mode 100644 (file)
index 0000000..d586d11
--- /dev/null
@@ -0,0 +1,57 @@
+package org.argeo.security.core;
+
+import org.argeo.security.SystemExecutionService;
+import org.springframework.core.task.SimpleAsyncTaskExecutor;
+import org.springframework.core.task.TaskExecutor;
+import org.springframework.security.Authentication;
+import org.springframework.security.AuthenticationManager;
+import org.springframework.security.context.SecurityContext;
+import org.springframework.security.context.SecurityContextHolder;
+
+public class KeyBasedSystemExecutionService implements SystemExecutionService {
+       private AuthenticationManager authenticationManager;
+       private String systemAuthenticationKey;
+
+       public void executeAsSystem(Runnable runnable) {
+               wrapWithSystemAuthentication(runnable).run();
+       }
+
+       public TaskExecutor createSystemAuthenticatedTaskExecutor() {
+               return new SimpleAsyncTaskExecutor() {
+                       private static final long serialVersionUID = -8126773862193265020L;
+
+                       @Override
+                       public Thread createThread(Runnable runnable) {
+                               return super
+                                               .createThread(wrapWithSystemAuthentication(runnable));
+                       }
+
+               };
+       }
+
+       protected Runnable wrapWithSystemAuthentication(final Runnable runnable) {
+               return new Runnable() {
+
+                       public void run() {
+                               SecurityContext securityContext = SecurityContextHolder
+                                               .getContext();
+                               Authentication auth = authenticationManager
+                                               .authenticate(new InternalAuthentication(
+                                                               systemAuthenticationKey));
+                               securityContext.setAuthentication(auth);
+
+                               runnable.run();
+                       }
+               };
+       }
+
+       public void setAuthenticationManager(
+                       AuthenticationManager authenticationManager) {
+               this.authenticationManager = authenticationManager;
+       }
+
+       public void setSystemAuthenticationKey(String systemAuthenticationKey) {
+               this.systemAuthenticationKey = systemAuthenticationKey;
+       }
+
+}
diff --git a/security/runtime/org.argeo.security.jackrabbit/.classpath b/security/runtime/org.argeo.security.jackrabbit/.classpath
new file mode 100644 (file)
index 0000000..92f19d2
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="src" path="src/main/java"/>
+       <classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/security/runtime/org.argeo.security.jackrabbit/.project b/security/runtime/org.argeo.security.jackrabbit/.project
new file mode 100644 (file)
index 0000000..35bcca2
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>org.argeo.security.jackrabbit</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.pde.PluginNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/security/runtime/org.argeo.security.jackrabbit/.settings/org.eclipse.jdt.core.prefs b/security/runtime/org.argeo.security.jackrabbit/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..fef3e94
--- /dev/null
@@ -0,0 +1,8 @@
+#Tue Mar 01 09:49:47 CET 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/security/runtime/org.argeo.security.jackrabbit/.settings/org.eclipse.pde.core.prefs b/security/runtime/org.argeo.security.jackrabbit/.settings/org.eclipse.pde.core.prefs
new file mode 100644 (file)
index 0000000..f99c55a
--- /dev/null
@@ -0,0 +1,4 @@
+#Tue Mar 01 09:49:47 CET 2011
+eclipse.preferences.version=1
+pluginProject.extensions=false
+resolve.requirebundle=false
diff --git a/security/runtime/org.argeo.security.jackrabbit/build.properties b/security/runtime/org.argeo.security.jackrabbit/build.properties
new file mode 100644 (file)
index 0000000..5fc538b
--- /dev/null
@@ -0,0 +1,4 @@
+source.. = src/main/java/
+output.. = target/classes/
+bin.includes = META-INF/,\
+               .
diff --git a/security/runtime/org.argeo.security.jackrabbit/pom.xml b/security/runtime/org.argeo.security.jackrabbit/pom.xml
new file mode 100644 (file)
index 0000000..b676aef
--- /dev/null
@@ -0,0 +1,58 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+       <modelVersion>4.0.0</modelVersion>
+       <parent>
+               <groupId>org.argeo.commons.security</groupId>
+               <artifactId>runtime</artifactId>
+               <version>0.2.3-SNAPSHOT</version>
+               <relativePath>..</relativePath>
+       </parent>
+       <artifactId>org.argeo.security.jackrabbit</artifactId>
+       <name>Commons Security Jackrabbit</name>
+       <build>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-compiler-plugin</artifactId>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-source-plugin</artifactId>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-jar-plugin</artifactId>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.felix</groupId>
+                               <artifactId>maven-bundle-plugin</artifactId>
+                               <version>${version.maven-bundle-plugin}</version>
+                               <configuration>
+                                       <instructions>
+                                               <Fragment-Host>org.argeo.dep.osgi.jackrabbit</Fragment-Host>
+                                               <Export-Package>org.argeo.security.jackrabbit.*</Export-Package>
+                                       </instructions>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </build>
+       <dependencies>
+               <dependency>
+                       <groupId>org.argeo.commons.security</groupId>
+                       <artifactId>org.argeo.security.core</artifactId>
+                       <version>${version.argeo-commons}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.dep.osgi</groupId>
+                       <artifactId>org.argeo.dep.osgi.jcr</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.dep.osgi</groupId>
+                       <artifactId>org.argeo.dep.osgi.jackrabbit</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework.security</groupId>
+                       <artifactId>org.springframework.security.core</artifactId>
+               </dependency>
+       </dependencies>
+</project>
diff --git a/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/spring/GrantedAuthorityPrincipal.java b/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/spring/GrantedAuthorityPrincipal.java
new file mode 100644 (file)
index 0000000..ec6152e
--- /dev/null
@@ -0,0 +1,20 @@
+package org.argeo.security.jackrabbit.spring;
+
+import java.security.Principal;
+
+import org.springframework.security.GrantedAuthority;
+
+/** Wraps a {@link GrantedAuthority} as a prin,cipal. */
+public class GrantedAuthorityPrincipal implements Principal {
+       private final GrantedAuthority grantedAuthority;
+
+       public GrantedAuthorityPrincipal(GrantedAuthority grantedAuthority) {
+               super();
+               this.grantedAuthority = grantedAuthority;
+       }
+
+       public String getName() {
+               return grantedAuthority.getAuthority();
+       }
+
+}
diff --git a/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/spring/SpringLoginModule.java b/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/spring/SpringLoginModule.java
new file mode 100644 (file)
index 0000000..c6b456d
--- /dev/null
@@ -0,0 +1,85 @@
+package org.argeo.security.jackrabbit.spring;
+
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.Credentials;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginException;
+
+import org.apache.jackrabbit.core.security.AnonymousPrincipal;
+import org.apache.jackrabbit.core.security.authentication.AbstractLoginModule;
+import org.apache.jackrabbit.core.security.authentication.Authentication;
+import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
+import org.argeo.security.SystemAuthentication;
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.context.SecurityContextHolder;
+import org.springframework.security.providers.anonymous.AnonymousAuthenticationToken;
+
+public class SpringLoginModule extends AbstractLoginModule {
+
+       /**
+        * Returns the Spring {@link org.springframework.security.Authentication}
+        * (which can be null)
+        */
+       @Override
+       protected Principal getPrincipal(Credentials credentials) {
+               return SecurityContextHolder.getContext().getAuthentication();
+       }
+
+       protected Set<Principal> getPrincipals() {
+               // use linked HashSet instead of HashSet in order to maintain the order
+               // of principals (as in the Subject).
+               Set<Principal> principals = new LinkedHashSet<Principal>();
+               principals.add(principal);
+
+               org.springframework.security.Authentication authen = (org.springframework.security.Authentication) principal;
+
+               if (authen instanceof AnonymousAuthenticationToken)
+                       principals.add(new AnonymousPrincipal());
+               if (authen instanceof SystemAuthentication)
+                       principals.add(new AdminPrincipal(authen.getName()));
+
+               for (GrantedAuthority authority : authen.getAuthorities())
+                       principals.add(new GrantedAuthorityPrincipal(authority));
+
+               return principals;
+       }
+
+       @SuppressWarnings("rawtypes")
+       @Override
+       protected void doInit(CallbackHandler callbackHandler, Session session,
+                       Map options) throws LoginException {
+       }
+
+       @Override
+       protected boolean impersonate(Principal principal, Credentials credentials)
+                       throws RepositoryException, LoginException {
+               throw new UnsupportedOperationException(
+                               "Impersonation is not yet supported");
+       }
+
+       @Override
+       protected Authentication getAuthentication(Principal principal,
+                       Credentials creds) throws RepositoryException {
+               if (principal instanceof Group) {
+                       return null;
+               }
+               return new Authentication() {
+                       public boolean canHandle(Credentials credentials) {
+                               return true;
+                       }
+
+                       public boolean authenticate(Credentials credentials)
+                                       throws RepositoryException {
+                               return true;
+                       }
+               };
+       }
+
+}
index 838a3cb97c2e0607616c63582fbc31f49946cc41..f5e41232e1033cf675bd3c8c2a069010a67997a3 100644 (file)
@@ -18,11 +18,8 @@ package org.argeo.security.ldap;
 
 import static org.argeo.security.core.ArgeoUserDetails.createSimpleArgeoUser;
 
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
 import java.util.Collections;
 import java.util.List;
-import java.util.Random;
 import java.util.Set;
 import java.util.TreeSet;
 
@@ -32,7 +29,9 @@ import javax.naming.directory.DirContext;
 
 import org.argeo.security.ArgeoSecurityDao;
 import org.argeo.security.ArgeoUser;
+import org.argeo.security.CurrentUserDao;
 import org.argeo.security.SimpleArgeoUser;
+import org.argeo.security.UserAdminDao;
 import org.argeo.security.core.ArgeoUserDetails;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.ldap.core.ContextExecutor;
@@ -49,7 +48,6 @@ import org.springframework.security.ldap.LdapUtils;
 import org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator;
 import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
 import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
-import org.springframework.security.providers.ldap.authenticator.LdapShaPasswordEncoder;
 import org.springframework.security.userdetails.UserDetails;
 import org.springframework.security.userdetails.UserDetailsManager;
 import org.springframework.security.userdetails.UserDetailsService;
@@ -57,7 +55,8 @@ import org.springframework.security.userdetails.ldap.LdapUserDetailsManager;
 import org.springframework.security.userdetails.ldap.LdapUserDetailsService;
 import org.springframework.security.userdetails.ldap.UserDetailsContextMapper;
 
-public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, InitializingBean {
+public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, CurrentUserDao,
+               UserAdminDao, InitializingBean {
        // private final static Log log = LogFactory.getLog(UserDaoLdap.class);
 
        private UserDetailsManager userDetailsManager;
@@ -80,17 +79,9 @@ public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, InitializingBean
        private LdapUserDetailsService ldapUserDetailsService;
        private List<UserNatureMapper> userNatureMappers;
 
-       private LdapShaPasswordEncoder ldapShaPasswordEncoder = new LdapShaPasswordEncoder();
-       private Random random;
-
        public ArgeoSecurityDaoLdap(BaseLdapPathContextSource contextSource) {
                this.contextSource = contextSource;
                ldapTemplate = new LdapTemplate(this.contextSource);
-               try {
-                       random = SecureRandom.getInstance("SHA1PRNG");
-               } catch (NoSuchAlgorithmException e) {
-                       random = new Random(System.currentTimeMillis());
-               }
        }
 
        public void afterPropertiesSet() throws Exception {
@@ -254,17 +245,6 @@ public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, InitializingBean
                ldapTemplate.unbind(dn);
        }
 
-       public Boolean isPasswordValid(String encoded, String raw) {
-               return ldapShaPasswordEncoder.isPasswordValid(encoded, raw, null);
-       }
-
-       public String encodePassword(String raw) {
-               byte[] salt = null;
-               // byte[] salt = new byte[16];
-               // random.nextBytes(salt);
-               return ldapShaPasswordEncoder.encodePassword(raw, salt);
-       }
-
        protected String convertRoleToGroup(String role) {
                String group = role;
                if (group.startsWith(rolePrefix)) {
index c04649e6f5e71b2306cfdbf3ea1b1d98f5e7c224..641ca066a3fb9f2efc6542c6831dc55dc7228071 100644 (file)
@@ -16,6 +16,7 @@
                <module>org.argeo.security.mvc</module>
                <module>org.argeo.security.ldap</module>
                <module>org.argeo.security.activemq</module>
+               <module>org.argeo.security.jackrabbit</module>
        </modules>
        <build>
                <resources>
index cc63f5a76aa6c65616dc5e17246b6d3d54cdc944..927608a18267357cc20ce8ffcfe5fc9b0d313710 100644 (file)
                        <artifactId>org.argeo.server.tika.jackrabbit</artifactId>
                        <version>${version.argeo-commons}</version>
                </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons.server</groupId>
+                       <artifactId>org.argeo.server.ext.jackrabbit</artifactId>
+                       <version>${version.argeo-commons}</version>
+               </dependency>
                <dependency>
                        <groupId>org.apache.xalan</groupId>
                        <artifactId>com.springsource.org.apache.xalan</artifactId>
index e1c13f3b1e22fd55788ce307f49a3465bbd5e40f..271e52de851b39f10da5fe3c9cbaa91e8855704e 100644 (file)
@@ -2,6 +2,6 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: Jackrabbit
 Bundle-SymbolicName: org.argeo.server.ext.jackrabbit
-Bundle-Description: provides additional DLLs to Jackrabbit
+Bundle-Description: provides additional DLLs and imports to Jackrabbit
 Bundle-Version: 0.2.3.SNAPSHOT
 Fragment-Host: org.argeo.dep.osgi.jackrabbit
index cce6833350c36c36ad8afc5da4a2074fe60cb09f..756e0787d87e2de936f0b9ae1e592dba939a68ca 100644 (file)
@@ -38,8 +38,6 @@
                                                        org.springframework.web.context,
                                                        org.xml.sax;version="0.0.0",
                                                        org.apache.jackrabbit.webdav.jcr,
-                                                       org.springframework.security.providers.jaas;resolution:="optional",
-                                                       junit.framework;resolution:="optional",
                                                        *
                                                </Import-Package>
                                        </instructions>
                <dependency>
                        <groupId>org.argeo.commons.basic</groupId>
                        <artifactId>org.argeo.basic.nodeps</artifactId>
-                       <version>0.2.3-SNAPSHOT</version>
+                       <version>${version.argeo-commons}</version>
                </dependency>
 
                <dependency>
                        <groupId>org.argeo.commons.server</groupId>
                        <artifactId>org.argeo.server.core</artifactId>
-                       <version>0.2.3-SNAPSHOT</version>
+                       <version>${version.argeo-commons}</version>
                </dependency>
                <dependency>
                        <groupId>org.argeo.commons.server</groupId>
                        <artifactId>org.argeo.server.jcr.mvc</artifactId>
-                       <version>0.2.3-SNAPSHOT</version>
+                       <version>${version.argeo-commons}</version>
                </dependency>
 
                <!-- Jackrabbit -->
                <dependency>
                        <groupId>org.argeo.commons.server</groupId>
                        <artifactId>org.argeo.server.dep.jackrabbit.server</artifactId>
-                       <version>0.2.3-SNAPSHOT</version>
+                       <version>${version.argeo-commons}</version>
                        <type>pom</type>
                </dependency>
                <dependency>
                        <artifactId>org.springframework.web.servlet</artifactId>
                </dependency>
 
-               <dependency>
-                       <groupId>org.springframework.security</groupId>
-                       <artifactId>org.springframework.security.core</artifactId>
-               </dependency>
-
                <dependency>
                        <groupId>org.springframework.ws</groupId>
                        <artifactId>org.springframework.xml</artifactId>
                <dependency>
                        <groupId>org.argeo.commons.basic</groupId>
                        <artifactId>org.argeo.support.junit</artifactId>
-                       <version>0.2.3-SNAPSHOT</version>
+                       <version>${version.argeo-commons}</version>
                        <scope>test</scope>
                </dependency>
                <dependency>
                        <groupId>org.argeo.commons.basic</groupId>
                        <artifactId>org.argeo.basic.dep.log4j</artifactId>
-                       <version>0.2.3-SNAPSHOT</version>
+                       <version>${version.argeo-commons}</version>
                        <type>pom</type>
                        <scope>test</scope>
                </dependency>
index a9dd55a1d4eac71e22dbd22e131ddd52165dc32f..a4f357883922f5984461fc62505a751dd9c058f9 100644 (file)
@@ -1,7 +1,9 @@
 source.. = src/main/java/,\
            src/test/java/,\
-           src/test/resources/
-output.. = target/classes/
+           src/test/resources/,\
+           src/main/resources/
+output.. = target/classes/,\
+           target/test-classes/
 bin.includes = META-INF/,\
                .
 additional.bundles = com.springsource.slf4j.api,\
index 415c4fd0513817bf4fa0b019bfd4d0aad21aab55..0177d1d55434c205f8c7cb4a82e5ebcbf0861633 100644 (file)
@@ -30,6 +30,7 @@
                                <configuration>
                                        <instructions>
                                                <Export-Package>org.argeo.jcr.*</Export-Package>
+                                               <Import-Package>junit.framework;resolution:=optional,*</Import-Package>
                                        </instructions>
                                </configuration>
                        </plugin>
@@ -55,7 +56,7 @@
                <dependency>
                        <groupId>org.argeo.commons.basic</groupId>
                        <artifactId>org.argeo.basic.nodeps</artifactId>
-                       <version>0.2.3-SNAPSHOT</version>
+                       <version>${version.argeo-commons}</version>
                </dependency>
 
                <!-- JCR -->
@@ -98,7 +99,7 @@
                <dependency>
                        <groupId>org.argeo.commons.server</groupId>
                        <artifactId>org.argeo.server.dep.jackrabbit.server</artifactId>
-                       <version>0.2.3-SNAPSHOT</version>
+                       <version>${version.argeo-commons}</version>
                        <type>pom</type>
                        <scope>test</scope>
                </dependency>
                <dependency>
                        <groupId>org.argeo.commons.basic</groupId>
                        <artifactId>org.argeo.support.junit</artifactId>
-                       <version>0.2.3-SNAPSHOT</version>
+                       <version>${version.argeo-commons}</version>
                        <scope>test</scope>
                </dependency>
                <dependency>
                        <groupId>org.argeo.commons.basic</groupId>
                        <artifactId>org.argeo.basic.dep.log4j</artifactId>
-                       <version>0.2.3-SNAPSHOT</version>
+                       <version>${version.argeo-commons}</version>
                        <type>pom</type>
                        <scope>test</scope>
                </dependency>
                <dependency>
                        <groupId>org.argeo.commons.osgi</groupId>
                        <artifactId>org.argeo.osgi.boot</artifactId>
-                       <version>0.2.3-SNAPSHOT</version>
+                       <version>${version.argeo-commons}</version>
                        <scope>test</scope>
                </dependency>
        </dependencies>
index 554e9f34c6e8ff2118699a16cd172760238a9ab4..59778556a955d727d6dacb6d11249dbc535ac0a7 100644 (file)
@@ -486,4 +486,12 @@ public class JcrUtils {
                else
                        return baseRelPath + '/' + propertyName;
        }
+
+       /**
+        * Normalize a name so taht it can be stores in contexts not supporting
+        * names with ':' (typically databases). Replaces ':' by '_'.
+        */
+       public static String normalize(String name) {
+               return name.replace(':', '_');
+       }
 }
diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisNames.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisNames.java
new file mode 100644 (file)
index 0000000..3a97f7b
--- /dev/null
@@ -0,0 +1,12 @@
+package org.argeo.jcr.gis;
+
+/** JCR names in the http://www.argeo.org/gis namespace */
+public interface GisNames {
+       public final static String GIS_NAMESPACE = "http://www.argeo.org/gis";
+       public final static String GIS_ = "gis:";
+       
+       public final static String GIS_SRS = "gis:srs";
+       public final static String GIS_X = "gis:x";
+       public final static String GIS_Y = "gis:y";
+       public final static String GIS_Z = "gis:z";
+}
diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisTypes.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisTypes.java
new file mode 100644 (file)
index 0000000..83ebe6f
--- /dev/null
@@ -0,0 +1,8 @@
+package org.argeo.jcr.gis;
+
+/** JCR types in the http://www.argeo.org/gis namespace */
+public interface GisTypes {
+       public final static String GIS_COORDINATE = "gis:coordinate";
+       public final static String GIS_GEOMETRY = "gis:geometry";
+       public final static String GIS_POINT = "gis:point";
+}
diff --git a/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/gis/argeo_gis.cnd b/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/gis/argeo_gis.cnd
new file mode 100644 (file)
index 0000000..43e3b57
--- /dev/null
@@ -0,0 +1,16 @@
+<gis = 'http://www.argeo.org/gis'>
+
+// GEOMETRIES (based on JTS http://www.vividsolutions.com/jts/JTSHome.htm) 
+[gis:coordinate] > nt:base
+mixin
+- gis:x (DOUBLE) m
+- gis:y (DOUBLE) m
+- gis:z (DOUBLE)
+
+[gis:geometry] > mix:created, mix:lastModified
+mixin
+// either an EPSG code (EPSG:4326 for WGS 84) or a WKT representation
+- gis:srs (STRING)
+
+[gis:point] > gis:geometry, gis:coordinate
+mixin