You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by sm...@apache.org on 2014/10/22 17:44:40 UTC
[21/51] [partial] Rename packages from org.openldap.fortress to
org.apache.directory.fortress.core. Change default suffix to org.apache.
Switch default ldap api from unbound to apache ldap.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/RoleUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/RoleUtil.java b/src/main/java/org/apache/directory/fortress/core/rbac/RoleUtil.java
new file mode 100755
index 0000000..67ce3c5
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/RoleUtil.java
@@ -0,0 +1,358 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.directory.fortress.core.rbac;
+
+
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.jgrapht.graph.SimpleDirectedGraph;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.ValidationException;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+import org.apache.directory.fortress.core.util.cache.Cache;
+import org.apache.directory.fortress.core.util.cache.CacheMgr;
+
+
+/**
+ * This utility wraps {@link org.apache.directory.fortress.core.rbac.HierUtil} methods to provide hierarchical functionality for the {@link org.apache.directory.fortress.core.rbac.Role} data set.
+ * The {@code cn=Hierarchies, ou=Roles} data is stored within a cache, {@link #roleCache}, contained within this class. The parent-child edges are contained in LDAP,
+ * in {@code ftParents} attribute. The ldap data is retrieved {@link org.apache.directory.fortress.core.rbac.RoleP#getAllDescendants(String)} and loaded into {@code org.jgrapht.graph.SimpleDirectedGraph}.
+ * The graph...
+ * <ol>
+ * <li>is stored as singleton in this class with vertices of {@code String}, and edges, as {@link Relationship}s</li>
+ * <li>utilizes open source library, see <a href="http://www.jgrapht.org/">JGraphT</a>.</li>
+ * <li>contains a general hierarchical data structure i.e. allows multiple inheritance with parents.</li>
+ * <li>is a simple directed graph thus does not allow cycles.</li>
+ * </ol>
+ * After update is performed to ldap, the singleton is refreshed with latest info.
+ * <p/>
+ * Static methods on this class are intended for use by other Fortress classes, i.e. {@link org.apache.directory.fortress.core.rbac.dao.UserDAO} and {@link org.apache.directory.fortress.core.rbac.dao.PermDAO}
+ * and cannot be directly invoked by outside programs.
+ * <p/>
+ * This class contains singleton that can be updated but is thread safe.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public final class RoleUtil
+{
+ private static final Cache roleCache;
+ private static final RoleP roleP = new RoleP();
+ private static final String CLS_NM = RoleUtil.class.getName();
+ private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+ /**
+ * Initialize the Role hierarchies. This will read the {@link org.apache.directory.fortress.core.rbac.Hier} data set from ldap and load into
+ * the JGraphT simple digraph that referenced statically within this class.
+ */
+ static
+ {
+ CacheMgr cacheMgr = CacheMgr.getInstance();
+ roleCache = cacheMgr.getCache( "fortress.roles" );
+ }
+
+
+ /**
+ * Used to determine if one {@link org.apache.directory.fortress.core.rbac.Role} is the parent of another. This method
+ * will call recursive routine {@link #getAscendants(String, String)} to walk the {@code org.jgrapht.graph.SimpleDirectedGraph} data structure
+ * returning flag indicating if parent-child relationship is valid.
+ *
+ * @param child maps to logical {@link org.apache.directory.fortress.core.rbac.Role#name} on 'ftRls' object class.
+ * @param parent maps to logical {@link org.apache.directory.fortress.core.rbac.Role#name} on 'ftRels' object class.
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @return boolean result, 'true' indicates parent/child relationship exists.
+ */
+ public static boolean isParent( String child, String parent, String contextId )
+ {
+ boolean result = false;
+ Set<String> parents = getAscendants( child, contextId );
+ if ( parents != null && parents.size() > 0 )
+ {
+ result = parents.contains( parent.toUpperCase() );
+ }
+ return result;
+ }
+
+
+ /**
+ * Recursively traverse the {@link org.apache.directory.fortress.core.rbac.Role} graph and return all of the descendants of a given node {@link org.apache.directory.fortress.core.rbac.Role#name}.
+ *
+ * @param roleName {@link org.apache.directory.fortress.core.rbac.Role#name} on 'ftRls' object class.
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @return Set of Role names are descendants {@link org.apache.directory.fortress.core.rbac.Role}s of given parent.
+ */
+ public static Set<String> getDescendants( String roleName, String contextId )
+ {
+ return HierUtil.getDescendants( roleName.toUpperCase(), getGraph( contextId ) );
+ }
+
+
+ /**
+ * Traverse the {@link org.apache.directory.fortress.core.rbac.Role} graph and return all children (direct descendants) of a given parent node {@link org.apache.directory.fortress.core.rbac.Role#name}.
+ *
+ * @param roleName {@link org.apache.directory.fortress.core.rbac.Role#name} on 'ftRls' object class.
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @return Set of Role names are children {@link org.apache.directory.fortress.core.rbac.Role}s of given parent.
+ */
+ public static Set<String> getChildren( String roleName, String contextId )
+ {
+ return HierUtil.getChildren( roleName.toUpperCase(), getGraph( contextId ) );
+ }
+
+
+ /**
+ * Recursively traverse the hierarchical role graph and return all of the ascendants of a given role.
+ *
+ * @param roleName maps to logical {@link org.apache.directory.fortress.core.rbac.Role#name} on 'ftRls' object class.
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @return Set of Role names that are ascendants of given child.
+ */
+ public static Set<String> getAscendants( String roleName, String contextId )
+ {
+ return HierUtil.getAscendants( roleName.toUpperCase(), getGraph( contextId ) );
+ }
+
+
+ /**
+ * Traverse the hierarchical role graph and return all of the parents (direct ascendants) of a given role.
+ *
+ * @param roleName maps to logical {@link org.apache.directory.fortress.core.rbac.Role#name} on 'ftRls' object class.
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @return Set of Role names that are parents of given child.
+ */
+ static Set<String> getParents( String roleName, String contextId )
+ {
+ return HierUtil.getParents( roleName.toUpperCase(), getGraph( contextId ) );
+ }
+
+
+ /**
+ * Determine the number of children (direct descendants) a given parent role has.
+ *
+ * @param roleName maps to logical {@link org.apache.directory.fortress.core.rbac.Role#name} on 'ftRls' object class.
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @return int value contains the number of children of a given parent nRole.
+ */
+ static int numChildren( String roleName, String contextId )
+ {
+ return HierUtil.numChildren( roleName.toUpperCase(), getGraph( contextId ) );
+ }
+
+
+ /**
+ * Return Set of RBAC {@link org.apache.directory.fortress.core.rbac.Role#name}s ascendants. Used by {@link org.apache.directory.fortress.core.rbac.dao.PermDAO#checkPermission}
+ * for computing authorized {@link UserRole#name}s.
+ *
+ * @param uRoles contains list of Roles activated within a {@link org.apache.directory.fortress.core.rbac.User}'s {@link org.apache.directory.fortress.core.rbac.Session}.
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @return contains Set of all authorized RBAC Roles for a given User.
+ */
+ public static Set<String> getInheritedRoles( List<UserRole> uRoles, String contextId )
+ {
+ // create Set with case insensitive comparator:
+ Set<String> iRoles = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+ if ( VUtil.isNotNullOrEmpty( uRoles ) )
+ {
+ for ( UserRole uRole : uRoles )
+ {
+ String rleName = uRole.getName();
+ iRoles.add( rleName );
+ Set<String> parents = HierUtil.getAscendants( rleName, getGraph( contextId ) );
+ if ( VUtil.isNotNullOrEmpty( parents ) )
+ iRoles.addAll( parents );
+ }
+ }
+ return iRoles;
+ }
+
+
+ /**
+ *
+ * @param roles
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @return
+ */
+ static Set<String> getAscendantRoles( List<String> roles, String contextId )
+ {
+ // create Set with case insensitive comparator:
+ Set<String> iRoles = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+ if ( VUtil.isNotNullOrEmpty( roles ) )
+ {
+ for ( String role : roles )
+ {
+ iRoles.add( role );
+ Set<String> parents = HierUtil.getAscendants( role, getGraph( contextId ) );
+ if ( VUtil.isNotNullOrEmpty( parents ) )
+ iRoles.addAll( parents );
+ }
+ }
+ return iRoles;
+ }
+
+
+ /**
+ *
+ * @param roles
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @return
+ */
+ static Set<String> getDescendantRoles( Set<String> roles, String contextId )
+ {
+ // create Set with case insensitive comparator:
+ Set<String> iRoles = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+ if ( VUtil.isNotNullOrEmpty( roles ) )
+ {
+ for ( String role : roles )
+ {
+ iRoles.add( role );
+ Set<String> children = HierUtil.getDescendants( role, getGraph( contextId ) );
+ if ( VUtil.isNotNullOrEmpty( children ) )
+ iRoles.addAll( children );
+ }
+ }
+ return iRoles;
+ }
+
+
+ /**
+ * Recursively traverse the hierarchical graph and return all of the ascendants of a given child node.
+ *
+ * @param childName maps to vertex to determine parentage.
+ * @param parentName points to top most ascendant where traversal must stop.
+ * @param isInclusive if set to true will include the parentName in the result set. False will not return specified parentName.
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @return Set of names that are parents of given child.
+ */
+ static Set<String> getAscendants( String childName, String parentName, boolean isInclusive, String contextId )
+ {
+ return HierUtil.getAscendants( childName, parentName, isInclusive, getGraph( contextId ) );
+ }
+
+
+ /**
+ * This api is used by {@link AdminMgrImpl} to determine parentage for Hierarchical RBAC processing.
+ * It calls {@link HierUtil#validateRelationship(org.jgrapht.graph.SimpleDirectedGraph, String, String, boolean)} to evaluate three adminRole relationship expressions:
+ * <ol>
+ * <li>If child equals parent</li>
+ * <li>If mustExist true and parent-child relationship exists</li>
+ * <li>If mustExist false and parent-child relationship does not exist</li>
+ * </ol>
+ * Method will throw {@link org.apache.directory.fortress.core.ValidationException} if rule check fails meaning caller failed validation
+ * attempt to add/remove hierarchical relationship failed.
+ *
+ * @param childRole contains {@link org.apache.directory.fortress.core.rbac.Role#name} of child.
+ * @param parentRole contains {@link org.apache.directory.fortress.core.rbac.Role#name} of parent.
+ * @param mustExist boolean is used to specify if relationship must be true.
+ * @throws org.apache.directory.fortress.core.ValidationException
+ * in the event it fails one of the 3 checks.
+ */
+ static void validateRelationship( Role childRole, Role parentRole, boolean mustExist )
+ throws ValidationException
+ {
+ HierUtil.validateRelationship( getGraph( childRole.getContextId() ), childRole.getName(), parentRole.getName(),
+ mustExist );
+ }
+
+
+ /**
+ * This api allows synchronized access to allow updates to hierarchical relationships.
+ * Method will update the hierarchical data set and reload the JGraphT simple digraph with latest.
+ *
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @param relationship contains parent-child relationship targeted for addition.
+ * @param op used to pass the ldap op {@link org.apache.directory.fortress.core.rbac.Hier.Op#ADD}, {@link org.apache.directory.fortress.core.rbac.Hier.Op#MOD}, {@link org.apache.directory.fortress.core.rbac.Hier.Op#REM}
+ * @throws org.apache.directory.fortress.core.SecurityException in the event of a system error.
+ */
+ static void updateHier( String contextId, Relationship relationship, Hier.Op op ) throws SecurityException
+ {
+ HierUtil.updateHier( getGraph( contextId ), relationship, op );
+ }
+
+
+ /**
+ * Read this ldap record,{@code cn=Hierarchies, ou=OS-P} into this entity, {@link Hier}, before loading into this collection class,{@code org.jgrapht.graph.SimpleDirectedGraph}
+ * using 3rd party lib, <a href="http://www.jgrapht.org/">JGraphT</a>.
+ *
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @return
+ */
+ private static SimpleDirectedGraph<String, Relationship> loadGraph( String contextId )
+ {
+ Hier inHier = new Hier( Hier.Type.ROLE );
+ inHier.setContextId( contextId );
+ LOG.info( "loadGraph initializing ROLE context [" + inHier.getContextId() + "]" );
+ List<Graphable> descendants = null;
+ try
+ {
+ descendants = roleP.getAllDescendants( inHier.getContextId() );
+ }
+ catch ( SecurityException se )
+ {
+ LOG.info( "loadGraph caught SecurityException=" + se );
+ }
+ Hier hier = HierUtil.loadHier( contextId, descendants );
+ SimpleDirectedGraph<String, Relationship> graph;
+ synchronized ( HierUtil.getLock( contextId, HierUtil.Type.ROLE ) )
+ {
+ graph = HierUtil.buildGraph( hier );
+ }
+ roleCache.put( getKey( contextId ), graph );
+ return graph;
+ }
+
+
+ /**
+ *
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @return
+ */
+ private static String getKey( String contextId )
+ {
+ String key = HierUtil.Type.ROLE.toString();
+ if ( VUtil.isNotNullOrEmpty( contextId ) && !contextId.equalsIgnoreCase( GlobalIds.NULL ) )
+ {
+ key += ":" + contextId;
+ }
+ return key;
+ }
+
+
+ /**
+ *
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @return
+ */
+ private static SimpleDirectedGraph<String, Relationship> getGraph( String contextId )
+ {
+ SimpleDirectedGraph<String, Relationship> graph = ( SimpleDirectedGraph<String, Relationship> ) roleCache
+ .get( getKey( contextId ) );
+ if ( graph == null )
+ {
+ graph = loadGraph( contextId );
+ }
+ return graph;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/SDSet.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/SDSet.java b/src/main/java/org/apache/directory/fortress/core/rbac/SDSet.java
new file mode 100755
index 0000000..81889d3
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/SDSet.java
@@ -0,0 +1,413 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.directory.fortress.core.rbac;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.UUID;
+
+/**
+ * <h4>Static Separation of Duties Schema</h4>
+ * The Fortress SDSet entity is a composite of the following other Fortress structural and aux object classes:
+ * <p/>
+ * 1. organizationalRole Structural Object Class is used to store basic attributes like cn and description.
+ * <pre>
+ * ------------------------------------------
+ * objectclass ( 2.5.6.8 NAME 'organizationalRole'
+ * DESC 'RFC2256: an organizational role'
+ * SUP top STRUCTURAL
+ * MUST cn
+ * MAY (
+ * x121Address $ registeredAddress $ destinationIndicator $
+ * preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
+ * telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $
+ * seeAlso $ roleOccupant $ preferredDeliveryMethod $ street $
+ * postOfficeBox $ postalCode $ postalAddress $
+ * physicalDeliveryOfficeName $ ou $ st $ l $ description
+ * )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * 2. The RBAC Separation of14:14 Duties includes:
+ * <p/> Static Separation of Duties
+ * <img src="../doc-files/RbacSSD.png">
+ * <pre>
+ * ------------------------------------------
+ * Fortress Dynamic Separation of Duties Structural Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.2.5
+ * NAME 'ftDSDSet'
+ * DESC 'Fortress Role Dynamic Separation of Duty Set Structural Object Class'
+ * SUP organizationalrole
+ * STRUCTURAL
+ * MUST (
+ * ftId $
+ * ftSetName $
+ * ftSetCardinality
+ * )
+ * MAY (
+ * ftRoles $
+ * description
+ * )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * OR
+ * <p/> Dynamic Separation of Duties
+ * <img src="../doc-files/RbacDSD.png">
+ * <pre>
+ * ------------------------------------------
+ * Fortress Static Separation of Duties Structural Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.2.4
+ * NAME 'ftSSDSet'
+ * DESC 'Fortress Role Static Separation of Duty Set Structural Object Class'
+ * SUP organizationalrole
+ * STRUCTURAL
+ * MUST (
+ * ftId $
+ * ftSetName $
+ * ftSetCardinality
+ * )
+ * MAY (
+ * ftRoles $
+ * description
+ * )
+ *)
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * 3. ftMods AUXILIARY Object Class is used to store Fortress audit variables on target entity.
+ * <pre>
+ * ------------------------------------------
+ * Fortress Audit Modification Auxiliary Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.3.4
+ * NAME 'ftMods'
+ * DESC 'Fortress Modifiers AUX Object Class'
+ * AUXILIARY
+ * MAY (
+ * ftModifier $
+ * ftModCode $
+ * ftModId
+ * )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortSet")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "sdset", propOrder = {
+ "name",
+ "id",
+ "description",
+ "cardinality",
+ "members",
+ "type"
+})
+public class SDSet extends FortEntity
+ implements java.io.Serializable, Comparable
+{
+ private String id;
+ private String name;
+ private String description;
+ private Integer cardinality;
+ @XmlElement(nillable = true)
+ private Set<String> members;
+ private SDType type;
+
+
+ /**
+ * enum for SSD or DSD data sets. Both nodes will be stored in the same LDAP container but use different
+ * object classes.
+ * SDType determines if 'ftSSDSet' or 'ftDSDSet' object class is used.
+ */
+ @XmlType(name = "sdtype")
+ @XmlEnum
+ public enum SDType
+ {
+ /**
+ * Static Separation of Duty data set.
+ */
+ STATIC,
+
+ /**
+ * Dynamic Separation of Duty data set.
+ */
+ DYNAMIC
+ }
+
+ /**
+ * Get the required type of SD Set - 'STATIC' Or 'DYNAMIC'.
+ *
+ * @return type that maps to either 'ftSSDSet' or 'ftDSDSet' object class is used.
+ */
+ public SDType getType()
+ {
+ return type;
+ }
+
+ /**
+ * Set the required type of SD Set - 'STATIC' Or 'DYNAMIC'.
+ *
+ * @param type maps to either 'ftSSDSet' or 'ftDSDSet' object class is used.
+ */
+ public void setType(SDType type)
+ {
+ this.type = type;
+ }
+
+ /**
+ * Create a new, empty map that is used to load Role members. This method is called by any class
+ * that needs to create an SDSet set.
+ *
+ * @return Set that sorts members by alphabetical order.
+ */
+ private static Set<String> createMembers()
+ {
+ return new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+ }
+
+
+ /**
+ * Return the name of SDSet entity. This field is required.
+ *
+ * @return attribute maps to 'cn' attribute on the 'organizationalRole' object class.
+ */
+ public String getName()
+ {
+ return this.name;
+ }
+
+
+ /**
+ * Set the name of SDSet entity. This field is required.
+ *
+ * @param name maps to 'cn' attribute on the 'organizationalRole' object class.
+ */
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+
+ /**
+ * Returns optional description that is associated with SDSet. This attribute is validated but not constrained by Fortress.
+ *
+ * @return value that is mapped to 'description' in 'organizationalrole' object class.
+ */
+ public String getDescription()
+ {
+ return this.description;
+ }
+
+
+ /**
+ * Sets the optional description that is associated with SDSet. This attribute is validated but not constrained by Fortress.
+ *
+ * @param description that is mapped to same name in 'organizationalrole' object class.
+ */
+ public void setDescription(String description)
+ {
+ this.description = description;
+ }
+
+
+ /**
+ * Return the internal id that is associated with SDSet. This attribute is generated automatically
+ * by Fortress when new SDSet is added to directory and is not known or changeable by external client.
+ *
+ * @return attribute maps to 'ftId' in either 'ftSSDSet' or 'ftDSDSet' object class.
+ */
+ public String getId()
+ {
+ return id;
+ }
+
+
+ /**
+ * Generate an internal Id that is associated with SDSet. This method is used by DAO class and
+ * is not available to outside classes. The generated attribute maps to 'ftId' in either 'ftSSDSet' or 'ftDSDSet' object class.
+ */
+ public void setId()
+ {
+ // generate a unique id that will be used as the rDn for this entry:
+ UUID uuid = UUID.randomUUID();
+ this.id = uuid.toString();
+ }
+
+
+ /**
+ * Set the internal Id that is associated with Role. This method is used by DAO class and
+ * is generated automatically by Fortress. Attribute stored in LDAP cannot be changed by external caller.
+ * This method can be used by client for search purposes only.
+ *
+ * @param id maps to 'ftId' in either 'ftSSDSet' or 'ftDSDSet' object class.
+ */
+ public void setId(String id)
+ {
+ this.id = id;
+ }
+
+
+ /**
+ * Return the numeric value that reflects the membership cardinality for SDSet. A value of '2' indicates
+ * the Role membership is mutually exclusive amongst members. A value of '3' indicates no more than two Roles
+ * in set can be assigned to a single User (SSD) or activated within a single Session (DSD). A value of '4' indicates
+ * no more than three Roles may be used at a time, etc...
+ *
+ * @return attribute maps to 'ftSetCardinality' attribute in either 'ftSSDSet' or 'ftDSDSet' object class.
+ */
+ public Integer getCardinality()
+ {
+ return cardinality;
+ }
+
+ /**
+ * Set the numeric value that reflects the membership cardinality for SDSet. A value of '2' indicates
+ * the Role membership is mutually exclusive amongst members. A value of '3' indicates no more than two Roles
+ * in set can be assigned to a single User (SSD) or activated within a single Session (DSD). A value of '4' indicates
+ * no more than three Roles may be used at a time, etc...
+ *
+ */
+ public void setCardinality(Integer cardinality)
+ {
+ this.cardinality = cardinality;
+ }
+
+ /**
+ * Return the alphabetically sorted Set containing Role membership to SDSet.
+ *
+ * @return attribute maps to 'ftRoles' attribute in either 'ftSSDSet' or 'ftDSDSet' object class.
+ */
+ //@XmlJavaTypeAdapter(SetAdapter.class)
+ public Set<String> getMembers()
+ {
+ return members;
+ }
+
+ /**
+ * Set an alphabetically sorted Set containing Role membership to SDSet.
+ *
+ * @param members attribute maps to 'ftRoles' attribute in either 'ftSSDSet' or 'ftDSDSet' object class.
+ */
+ public void setMembers(Set<String> members)
+ {
+ this.members = members;
+ }
+
+
+ /**
+ * Add a member to the set.
+ *
+ * @param member role name.
+ */
+ public void setMember(String member)
+ {
+ if(this.members == null)
+ {
+ this.members = new HashSet<>();
+ }
+ this.members.add(member);
+ }
+
+
+ /**
+ * Add a member to an alphabetically sorted Set containing Role membership to SDSet.
+ *
+ * @param role attribute maps to 'ftRoles' attribute in either 'ftSSDSet' or 'ftDSDSet' object class.
+ */
+ public void addMember(String role)
+ {
+ if (this.members == null)
+ {
+ this.members = createMembers();
+ }
+ this.members.add(role);
+ }
+
+ /**
+ * Remove a member from the alphabetically sorted Set containing Role membership to SDSet.
+ *
+ * @param role attribute maps to 'ftRoles' attribute in either 'ftSSDSet' or 'ftDSDSet' object class.
+ */
+ public void delMember(String role)
+ {
+ if (this.members == null)
+ {
+ return;
+ }
+ this.members.remove(role);
+ }
+
+ public int compareTo(Object o)
+ {
+ SDSet k1 = this;
+ SDSet k2 = (SDSet) o;
+ String s1 = k1.getName();
+ String s2 = k2.getName();
+ return s1.compareToIgnoreCase(s2);
+ }
+
+ /**
+ * Matches the name from two SDSet entities.
+ *
+ * @param thatObj contains an SDSet entity.
+ * @return boolean indicating both objects contain matching SDSet names.
+ */
+ public boolean equals(Object thatObj)
+ {
+ if (this == thatObj)
+ {
+ return true;
+ }
+ if (this.getName() == null)
+ {
+ return false;
+ }
+ if (!(thatObj instanceof Role ))
+ {
+ return false;
+ }
+ SDSet thatSet = (SDSet) thatObj;
+ if (thatSet.getName() == null)
+ {
+ return false;
+ }
+ return thatSet.getName().equalsIgnoreCase(this.getName());
+ }
+
+ @Override
+ public String toString()
+ {
+ return "SDSet{" +
+ "name='" + name + '\'' +
+ '}';
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/SDUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/SDUtil.java b/src/main/java/org/apache/directory/fortress/core/rbac/SDUtil.java
new file mode 100755
index 0000000..0eb4c88
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/SDUtil.java
@@ -0,0 +1,533 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.directory.fortress.core.rbac;
+
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.ReviewMgrFactory;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.ReviewMgr;
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+import org.apache.directory.fortress.core.util.cache.Cache;
+import org.apache.directory.fortress.core.util.cache.CacheMgr;
+import org.apache.directory.fortress.core.util.cache.DsdCacheEntry;
+import org.apache.directory.fortress.core.util.time.Constraint;
+import net.sf.ehcache.search.Attribute;
+import net.sf.ehcache.search.Query;
+import net.sf.ehcache.search.Result;
+import net.sf.ehcache.search.Results;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This utilty provides functionality necessary for SSD and DSD processing and cannot be called by components outside fortress.
+ * This class also contains utility functions for maintaining the SSD and DSD cache.
+ * <p/>
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ * @created September 3, 2010
+ */
+final class SDUtil
+{
+ private static final Cache m_dsdCache;
+ private static final String FORTRESS_DSDS = "fortress.dsd";
+ private static final Cache m_ssdCache;
+ private static final String FORTRESS_SSDS = "fortress.ssd";
+ private static final SdP sp = new SdP();
+ private static final String IS_DSD_CACHE_DISABLED_PARM = "enable.dsd.cache";
+ private static final String MEMBER = "member";
+ private static final String DSD_NAME = "name";
+ private static final String EMPTY_ELEMENT = "empty";
+ private static final String CONTEXT_ID = "contextId";
+
+ static
+ {
+ // Get a reference to the CacheManager Singleton object:
+ CacheMgr cacheMgr = CacheMgr.getInstance();
+ // This cache contains a wrapper entry for DSD and is searchable by both DSD and Role name:
+ m_dsdCache = cacheMgr.getCache(FORTRESS_DSDS);
+ // This cache is not searchable and contains Lists of SSD objects by Role:
+ m_ssdCache = cacheMgr.getCache(FORTRESS_SSDS);
+ }
+
+ /**
+ * This method is called by AdminMgr.assignUser and is used to validate Static Separation of Duty
+ * constraints when assigning a role to user.
+ *
+ * @param uRole
+ * @throws org.apache.directory.fortress.core.SecurityException
+ *
+ */
+ static void validateSSD(UserRole uRole)
+ throws SecurityException
+ {
+ validateSSD(new User(uRole.getUserId()), new Role(uRole.getName()));
+ }
+
+ /**
+ * This method is called by AdminMgr.assignUser and is used to validate Static Separation of Duty
+ * constraints when assigning a role to user.
+ *
+ * @param user
+ * @param role
+ * @throws org.apache.directory.fortress.core.SecurityException
+ *
+ */
+ static void validateSSD(User user, Role role)
+ throws SecurityException
+ {
+ int matchCount;
+ // get all authorized roles for user
+ ReviewMgr rMgr = ReviewMgrFactory.createInstance(user.getContextId());
+ Set<String> rls = rMgr.authorizedRoles(user);
+ // Need to proceed?
+ if (!VUtil.isNotNullOrEmpty(rls))
+ {
+ return;
+ }
+
+ // get all SSD sets that contain the new role
+ List<SDSet> ssdSets = getSsdCache(role.getName(), user.getContextId());
+ for (SDSet ssd : ssdSets)
+ {
+ matchCount = 0;
+ Set<String> map = ssd.getMembers();
+ // iterate over every authorized role for user:
+ for (String authRole : rls)
+ {
+ // is there a match found between authorized role and SSD set's members?
+ if (map.contains(authRole))
+ {
+ matchCount++;
+ // does the match count exceed the cardinality allowed for this particular SSD set?
+ if (matchCount >= ssd.getCardinality() - 1)
+ {
+ String error = "validateSSD new role [" + role.getName() + "] validates SSD Set Name:" + ssd.getName() + " Cardinality:" + ssd.getCardinality();
+ throw new SecurityException(GlobalErrIds.SSD_VALIDATION_FAILED, error);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * This method is called by AccessMgr.addActiveRole and is used to validate Dynamic Separation of Duty
+ * constraints when activating a role one at a time. For activation of multiple roles simultaneously use
+ * the DSD.validate API which is used during createSession sequence.
+ *
+ * @param session
+ * @param role
+ * @throws org.apache.directory.fortress.core.SecurityException
+ *
+ */
+ static void validateDSD(Session session, Constraint role)
+ throws SecurityException
+ {
+ // get all activated roles from user's session:
+ List<UserRole> rls = session.getRoles();
+ if (!VUtil.isNotNullOrEmpty(rls))
+ {
+ // An empty list of roles was passed in the session variable.
+ // No need to continue.
+ return;
+ }
+
+ // get all DSD sets that contain the target role
+ Set<SDSet> dsdSets = getDsdCache(role.getName(), session.getContextId());
+ for (SDSet dsd : dsdSets)
+ {
+ // Keeps the number of matched roles to a particular DSD set.
+ int matchCount = 0;
+
+ // Contains the list of roles assigned to a particular DSD set.
+ Set<String> map = dsd.getMembers();
+
+ // iterate over every role active in session for match wth DSD members:
+ for (UserRole actRole : rls)
+ {
+ // is there a match found between active role in session and DSD set members?
+ if (map.contains(actRole.getName()))
+ {
+ // Yes, we found a match, increment the count.
+ matchCount++;
+
+ // Does the match count exceed the cardinality allowed for this particular DSD set?
+ if (matchCount >= dsd.getCardinality() - 1)
+ {
+ // Yes, the target role violates DSD cardinality rule.
+ String error = "validateDSD failed for role [" + role.getName() + "] DSD Set Name:" + dsd.getName() + " Cardinality:" + dsd.getCardinality();
+ throw new SecurityException(GlobalErrIds.DSD_VALIDATION_FAILED, error);
+ }
+ }
+ else // Check the parents of activated role for DSD match:
+ {
+ // Now pull the activated role's list of parents.
+ Set<String> parentSet = RoleUtil.getAscendants(actRole.getName(), session.getContextId());
+
+ // Iterate over the list of parent roles:
+ for (String parentRole : parentSet)
+ {
+ if (map.contains(parentRole)) // is there match between parent and DSD member?
+ {
+ matchCount++;
+ if (matchCount >= dsd.getCardinality() - 1) // Does the counter exceed max per cardinality on this DSD set?
+ {
+ String error = "validateDSD failed for role [" + role.getName() + "] parent role [" + parentRole + "] DSD Set Name:" + dsd.getName() + " Cardinality:" + dsd.getCardinality();
+ throw new SecurityException(GlobalErrIds.DSD_VALIDATION_FAILED, error);
+ }
+ // Breaking out of the loop here means the DSD algorithm will only match one
+ // role per parent of active role candidate.
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Given DSD entry name, clear its corresponding object values from the cache.
+ *
+ * @param name contains the name of object to be cleared.
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com. *
+ * @throws SecurityException in the event of system or rule violation.
+ */
+ static void clearDsdCacheEntry(String name, String contextId)
+ {
+ Attribute<String> context = m_dsdCache.getSearchAttribute(CONTEXT_ID);
+ Attribute<String> dsdName = m_dsdCache.getSearchAttribute(DSD_NAME);
+ Query query = m_dsdCache.createQuery();
+ query.includeKeys();
+ query.includeValues();
+ query.addCriteria(dsdName.eq(name).and(context.eq(contextId)));
+ Results results = query.execute();
+ for (Result result : results.all())
+ {
+ m_dsdCache.clear(result.getKey());
+ }
+ }
+
+ /**
+ * Given a role name, return the set of DSD's that have a matching member.
+ *
+ * @param name contains name of authorized Role used to search the cache.
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @return un-ordered set of matching DSD's.
+ * @throws SecurityException in the event of system or rule violation.
+ */
+ private static Set<SDSet> getDsdCache(String name, String contextId)
+ throws SecurityException
+ {
+ contextId = getContextId(contextId);
+ Set<SDSet> finalSet = new HashSet<>();
+ Attribute<String> context = m_dsdCache.getSearchAttribute(CONTEXT_ID);
+ Attribute<String> member = m_dsdCache.getSearchAttribute(MEMBER);
+ Query query = m_dsdCache.createQuery();
+ query.includeKeys();
+ query.includeValues();
+ query.addCriteria(member.eq(name).and(context.eq(contextId)));
+ Results results = query.execute();
+ boolean empty = false;
+ for (Result result : results.all())
+ {
+ DsdCacheEntry entry = (DsdCacheEntry) result.getValue();
+ if (!entry.isEmpty())
+ {
+ finalSet.add(entry.getSdSet());
+ finalSet = putDsdCache(name, contextId);
+ }
+ else
+ {
+ empty = true;
+ }
+ finalSet.add(entry.getSdSet());
+ }
+ // If nothing was found in the cache, determine if it needs to be seeded:
+ if (finalSet.size() == 0 && !empty)
+ {
+ finalSet = putDsdCache(name, contextId);
+ }
+ return finalSet;
+ }
+
+ /**
+ * Given a Set of authorized Roles, return the set of DSD's that have matching members.
+ *
+ * @param authorizedRoleSet contains an un-order Set of authorized Roles.
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @return un-ordered set of matching DSD's.
+ * @throws SecurityException in the event of system or rule violation.
+ */
+ static Set<SDSet> getDsdCache(Set<String> authorizedRoleSet, String contextId)
+ throws SecurityException
+ {
+ contextId = getContextId(contextId);
+ Set<SDSet> dsdRetSets = new HashSet<>();
+ // Need to proceed?
+ if (!VUtil.isNotNullOrEmpty(authorizedRoleSet))
+ {
+ return dsdRetSets;
+ }
+ // Was the DSD Cache switched off?
+ boolean isCacheDisabled = Config.getBoolean(IS_DSD_CACHE_DISABLED_PARM, false);
+ // If so, get DSD's from LDAP:
+ if (isCacheDisabled)
+ {
+ SDSet sdSet = new SDSet();
+ sdSet.setType(SDSet.SDType.DYNAMIC);
+ sdSet.setContextId(contextId);
+ dsdRetSets = sp.search(authorizedRoleSet, sdSet);
+ }
+ // Search the DSD cache for matching Role members:
+ else
+ {
+ // Search on roleName attribute which maps to 'member' attr on the cache record:
+ Attribute<String> member = m_dsdCache.getSearchAttribute(MEMBER);
+ Attribute<String> context = m_dsdCache.getSearchAttribute(CONTEXT_ID);
+ Query query = m_dsdCache.createQuery();
+ query.includeKeys();
+ query.includeValues();
+ // Add the passed in authorized Role names to this cache query:
+ Set<String> roles = new HashSet<>(authorizedRoleSet);
+ query.addCriteria(member.in(roles).and(context.eq(contextId)));
+ // Return all DSD cache entries that match roleName to the 'member' attribute in cache entry:
+ Results results = query.execute();
+ for (Result result : results.all())
+ {
+ DsdCacheEntry entry = (DsdCacheEntry) result.getValue();
+ // Do not add dummy DSD sets to the final list:
+ if (!entry.isEmpty())
+ {
+ dsdRetSets.add(entry.getSdSet());
+ }
+ // Remove role member from authorizedRoleSet to preclude from upcoming DSD search:
+ authorizedRoleSet.remove(entry.getMember());
+ }
+ // Authorized roles remaining in this set correspond to missed cache hits from above:
+ if (authorizedRoleSet.size() > 0)
+ {
+ dsdRetSets = putDsdCache(authorizedRoleSet, contextId);
+ }
+ }
+ return dsdRetSets;
+ }
+
+ /**
+ * Get the matching DSD's from directory and add to the cache (if found). If matching DSD not found,
+ * add dummy entry to cache to prevent repeated searches.
+ *
+ * @param authorizedRoleSet contains set of Roles used to search directory for matching DSD's.
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @return List of DSD's who have matching Role members.
+ * @throws SecurityException in the event of system or rule violation.
+ */
+ private static Set<SDSet> putDsdCache(Set<String> authorizedRoleSet, String contextId)
+ throws SecurityException
+ {
+ contextId = getContextId(contextId);
+ Set<SDSet> dsdSets = new HashSet<>();
+ // Search the DSD's iteratively to seed the DSD cache by Role name:
+ for (String roleName : authorizedRoleSet)
+ {
+ Role role = new Role(roleName);
+ role.setContextId(contextId);
+ List<SDSet> dsdList = sp.search(role, SDSet.SDType.DYNAMIC);
+ if (VUtil.isNotNullOrEmpty(dsdList))
+ {
+ for (SDSet dsd : dsdList)
+ {
+ dsd.setContextId(contextId);
+ Set<String> members = dsd.getMembers();
+ if (members != null)
+ {
+ // Seed the cache with DSD objects mapped to role name:
+ for (String member : members)
+ {
+ String key = buildKey(dsd.getName(), member);
+ DsdCacheEntry entry = new DsdCacheEntry(member, dsd, false);
+ entry.setName(dsd.getName());
+ m_dsdCache.put(getKey(key, contextId), entry);
+ }
+ }
+ }
+ // Maintain the set of DSD's to be returned to the caller:
+ dsdSets.addAll(dsdList);
+ }
+ else
+ {
+ // Seed the cache with dummy entry for a Role that is not referenced by DSD:
+ String key = buildKey(EMPTY_ELEMENT, roleName);
+ SDSet sdSet = new SDSet();
+ sdSet.setType(SDSet.SDType.DYNAMIC);
+ sdSet.setName(key);
+ sdSet.setMember(roleName);
+ sdSet.setContextId(contextId);
+ DsdCacheEntry entry = new DsdCacheEntry(roleName, sdSet, true);
+ entry.setName(key);
+ m_dsdCache.put(getKey(sdSet.getName(), contextId), entry);
+ }
+ }
+ return dsdSets;
+ }
+
+ /**
+ * Get the matching DSD's from directory and add to the cache (if found). If matching DSD not found,
+ * add dummy entry to cache to prevent repeated searches.
+ *
+ * @param roleName of Role is used to search directory for matching DSD's.
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @return Set of DSD's who have matching Role member.
+ * @throws SecurityException in the event of system or rule violation.
+ */
+ private static Set<SDSet> putDsdCache(String roleName, String contextId)
+ throws SecurityException
+ {
+ contextId = getContextId(contextId);
+ Role role = new Role(roleName);
+ role.setContextId(contextId);
+ List<SDSet> dsdList = sp.search(role, SDSet.SDType.DYNAMIC);
+ Set<SDSet> finalSet = new HashSet<>(dsdList);
+ if (VUtil.isNotNullOrEmpty(dsdList))
+ {
+ for (SDSet dsd : dsdList)
+ {
+ dsd.setContextId(contextId);
+ Set<String> members = dsd.getMembers();
+ if (members != null)
+ {
+ // Seed the cache with DSD objects mapped to role name:
+ for (String member : members)
+ {
+ String key = buildKey(dsd.getName(), member);
+ DsdCacheEntry entry = new DsdCacheEntry(member, dsd, false);
+ entry.setName(dsd.getName());
+ m_dsdCache.put(getKey(key, contextId), entry);
+ }
+ }
+ }
+ }
+ else
+ {
+ // Seed the cache with dummy entry for Role that does not have DSD:
+ String key = buildKey(EMPTY_ELEMENT, roleName);
+ SDSet sdSet = new SDSet();
+ sdSet.setType(SDSet.SDType.DYNAMIC);
+ sdSet.setName(key);
+ sdSet.setMember(roleName);
+ sdSet.setContextId(contextId);
+ DsdCacheEntry entry = new DsdCacheEntry(roleName, sdSet, true);
+ entry.setName(key);
+ m_dsdCache.put(getKey(sdSet.getName(), contextId), entry);
+ }
+ return finalSet;
+ }
+
+ /**
+ * Given entry name, clear its corresponding object value from the cache.
+ *
+ * @param name contains the name of object to be cleared.
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @throws SecurityException in the event of system or rule violation.
+ */
+ static void clearSsdCacheEntry(String name, String contextId)
+ {
+ contextId = getContextId(contextId);
+ m_ssdCache.clear(getKey(name, contextId));
+ }
+
+ /**
+ * Get the matching SSD's from directory and add to the cache (if found).
+ *
+ * @param name of Role is used to search directory for matching SSD's.
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @return List of SSD's who have matching Role member.
+ * @throws SecurityException in the event of system or rule violation.
+ */
+ private static List<SDSet> putSsdCache(String name, String contextId)
+ throws SecurityException
+ {
+ Role role = new Role(name);
+ role.setContextId(contextId);
+ List<SDSet> ssdSets = sp.search(role, SDSet.SDType.STATIC);
+ m_ssdCache.put(getKey(name, contextId), ssdSets);
+ return ssdSets;
+ }
+
+ /**
+ * Look in cache for matching List of SSD's.
+ *
+ * @param name of Role is used to search directory for matching SSD's.
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ * @return List of SSD's who have matching Role member.
+ * @throws SecurityException in the event of system or rule violation.
+ */
+ private static List<SDSet> getSsdCache(String name, String contextId)
+ throws SecurityException
+ {
+ List<SDSet> ssdSets = (List<SDSet>) m_ssdCache.get(getKey(name, contextId));
+ if (ssdSets == null)
+ {
+ ssdSets = putSsdCache(name, contextId);
+ }
+ return ssdSets;
+ }
+
+ /**
+ *
+ * @param parm1
+ * @param parm2
+ * @return
+ */
+ private static String buildKey(String parm1, String parm2)
+ {
+ return parm1 + ":" + parm2;
+ }
+
+ /**
+ *
+ * @param name
+ * @param contextId
+ * @return
+ */
+ private static String getKey(String name, String contextId)
+ {
+ contextId = getContextId(contextId);
+ return name += ":" + contextId;
+ }
+
+ /**
+ *
+ * @param contextId
+ * @return
+ */
+ private static String getContextId(String contextId)
+ {
+ String szContextId = GlobalIds.HOME;
+ if(VUtil.isNotNullOrEmpty(contextId) && !contextId.equals(GlobalIds.NULL))
+ {
+ szContextId = contextId;
+ }
+ return szContextId;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/SdP.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/SdP.java b/src/main/java/org/apache/directory/fortress/core/rbac/SdP.java
new file mode 100755
index 0000000..fa06867
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/SdP.java
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.directory.fortress.core.rbac;
+
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.rbac.dao.unboundid.SdDAO;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+
+/**
+ * Process module for Separation of Duty Relation data sets. The Fortress SD data set can be of two types:
+ * <ol>
+ * <li>Static Separation of Duties (SSD)</li>
+ * <li>Dynamic Separation of Duties (DSD)</li>
+ * </ol>
+ * The SDSet entity itself distinguishes which is being targeted by {@link SDSet.SDType} which is equal to {@link SDSet.SDType#STATIC} or {@link SDSet.SDType#DYNAMIC}.
+ * This class performs data validations and error mapping in addition to calling DAO methods. It is typically called
+ * by internal Fortress Manager classes ({@link org.apache.directory.fortress.core.AdminMgr}, {@link org.apache.directory.fortress.core.ReviewMgr}) and also by internal SD utils.
+ * This class is not intended to be called externally or outside of Fortress Core itself. This class will accept {@link SDSet},
+ * validate its contents and forward on to it's corresponding DAO {@link org.apache.directory.fortress.core.rbac.dao.unboundid.SdDAO}.
+ * <p>
+ * Class will throw {@link SecurityException} to caller in the event of security policy, data constraint violation or system
+ * error internal to DAO object. This class will forward DAO exceptions ({@link org.apache.directory.fortress.core.FinderException},
+ * {@link org.apache.directory.fortress.core.CreateException},{@link org.apache.directory.fortress.core.UpdateException},{@link org.apache.directory.fortress.core.RemoveException}),
+ * or {@link org.apache.directory.fortress.core.ValidationException} as {@link SecurityException}s with appropriate
+ * error id from {@link org.apache.directory.fortress.core.GlobalErrIds}.
+ * <p>
+ * This class is thread safe.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ * @created September 11, 2010
+ */
+public final class SdP
+{
+ /**
+ * Get the DAO created:
+ */
+ private static final SdDAO sdDao = new SdDAO();
+
+
+ /**
+ * Package private constructor.
+ */
+ SdP()
+ {
+ }
+
+
+ /**
+ * Adds a new SDSet to directory. The OrgUnit SDType enum will determine which data set insertion will
+ * occur - STATIC or DYNAMIC. The SDSet entity input will be validated to ensure that:
+ * name is present, and reasonability checks on all of the other populated values.
+ *
+ * @param entity SDSet contains data targeted for insertion.
+ * @return SDSet entity copy of input + additional attributes (internalId) that were added by op.
+ * @throws SecurityException in the event of data validation or DAO system error.
+ */
+ final SDSet add( SDSet entity ) throws SecurityException
+ {
+ validate( entity );
+ return sdDao.create( entity );
+ }
+
+
+ /**
+ * Updates existing SDSet in directory. The SDSet type enum will determine which data set insertion will
+ * occur - STATIC or DYNAMIC. The SDSet entity input will be validated to ensure that:
+ * name is present, and reasonability checks on all of the other populated values.
+ * Null or empty attributes are ignored.
+ *
+ * @param entity SDSet contains data targeted for updating. Null attributes ignored.
+ * @return SDSet entity copy of input + additional attributes (internalId) that were updated by op.
+ * @throws SecurityException in the event of data validation or DAO system error.
+ */
+ final SDSet update( SDSet entity ) throws SecurityException
+ {
+ validate( entity );
+ return sdDao.update( entity );
+ }
+
+
+ /**
+ * This method performs a "hard" delete. It completely the SDSet node from the ldap directory.
+ * The SDSet type enum will determine where deletion will occur - STATIC or DYNAMIC data sets.
+ * SDSet entity must exist in directory prior to making this call else exception will be thrown.
+ *
+ * @param entity Contains the name of the SDSet node targeted for deletion.
+ * @return SDSet is a copy of entity.
+ * @throws SecurityException in the event of data validation or DAO system error.
+ */
+ final SDSet delete( SDSet entity ) throws SecurityException
+ {
+ return sdDao.remove( entity );
+ }
+
+
+ /**
+ * Return a fully populated SDSet entity for a given STATIC or DYNAMIC SDSet name. If matching record not found a
+ * SecurityException will be thrown.
+ *
+ * @param entity contains full SDSet name used for STATIC or DYNAMIC data sets in directory.
+ * @return SDSet entity containing all attributes associated with ou in directory.
+ * @throws SecurityException in the event SDSet not found or DAO search error.
+ */
+ final SDSet read( SDSet entity ) throws SecurityException
+ {
+ SDSet sde;
+ // The assumption is this method is called from ReviewMgr.ssdRoleSetRoles or ReviewMgr.dsdRoleSetRoles.
+ // If called from ReviewMgr, the object class type will be passed in:
+ SDSet.SDType type = entity.getType();
+ sde = sdDao.getSD( entity );
+ // Load the previously saved type onto the return entity:
+ sde.setType( type );
+ return sde;
+ }
+
+
+ /**
+ * Will search using a single RBAC Role name either STATIC or DYNAMIC SDSet depending on which type is passed.
+ * The role entity contains full RBAC Role name associated with SDSet node in directory.
+ *
+ * @param sdSet contains sdset name or partial name along with sdset type of STATIC or DYNAMIC.
+ * @return List of SDSet entities found.
+ * @throws SecurityException in the event of DAO search error.
+ */
+ final List<SDSet> search( SDSet sdSet ) throws SecurityException
+ {
+ return sdDao.search( sdSet );
+ }
+
+
+ /**
+ * Will search using a single RBAC Role name either STATIC or DYNAMIC SDSet depending on which type is passed.
+ * The role entity contains full RBAC Role name associated with SDSet node in directory.
+ *
+ * @param role contains full role name associated with SDSet.
+ * @param type either STATIC or DYNAMIC depending on target search data set.
+ * @return List of SDSet entities found.
+ * @throws SecurityException in the event of DAO search error.
+ */
+ final List<SDSet> search( Role role, SDSet.SDType type ) throws SecurityException
+ {
+ return sdDao.search( role, type );
+ }
+
+
+ /**
+ * Will search using list of input RBAC role names either STATIC or DYNAMIC SDSet depending on which type is passed.
+ * The role entity contains full RBAC Role name associated with SDSet node in directory.
+ *
+ * @param rls contains set of type String containing full role names associated with SDSet.
+ * @param sdSet contains type either STATIC or DYNAMIC depending on target search data set.
+ * @return List of SDSet entities found.
+ * @throws SecurityException in the event of DAO search error.
+ */
+ final Set<SDSet> search( Set<String> rls, SDSet sdSet ) throws SecurityException
+ {
+ return sdDao.search( rls, sdSet );
+ }
+
+
+ /**
+ * Method will perform simple validations to ensure the integrity of the SDSet entity targeted for insertion
+ * or updating in directory. This method will ensure the name and type enum are specified. Method will
+ * also ensure every Role name set is valid RBAC role entity in directory. It will also perform
+ * reasonability check on description if set.
+ *
+ * @param entity contains the enum type to validate
+ * @throws SecurityException thrown in the event the attribute is null.
+ */
+ private void validate( SDSet entity )
+ throws SecurityException
+ {
+ // TODO: Add more validations here:
+ VUtil.safeText( entity.getName(), GlobalIds.OU_LEN );
+ if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+ {
+ VUtil.description( entity.getDescription() );
+ }
+ Set<String> roles = entity.getMembers();
+ if ( roles != null )
+ {
+ RoleP rp = new RoleP();
+ for ( String key : roles )
+ {
+ // when removing last role member a placeholder must be left in data set:
+ if ( !key.equalsIgnoreCase( GlobalIds.NONE ) )
+ {
+ // Ensure the name exists:
+ Role role = new Role( key );
+ role.setContextId( entity.getContextId() );
+ rp.read( role );
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/Session.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/Session.java b/src/main/java/org/apache/directory/fortress/core/rbac/Session.java
new file mode 100755
index 0000000..3e95094
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/Session.java
@@ -0,0 +1,688 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.directory.fortress.core.rbac;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * This contains attributes related to a user's RBAC session.
+ * The following example shows the mapping to Session attributes on this entity:
+ * <p/>
+ * <ul> <li><code>Session</code>
+ * <li> <code>session.getUserId() => demoUser4</code>
+ * <li> <code>session.getInternalUserId() => be2dd2e:12a82ba707e:-7fee</code>
+ * <li> <code>session.getMessage() => Fortress checkPwPolicies userId <demouser4> VALIDATION GOOD</code>
+ * <li> <code>session.getErrorId() => 0</code>
+ * <li> <code>session.getWarningId() => 11</code>
+ * <li> <code>session.getExpirationSeconds() => 469831</code>
+ * <li> <code>session.getGraceLogins() => 0</code>
+ * <li> <code>session.getIsAuthenticated() => true</code>
+ * <li> <code>session.getLastAccess() => 1283623680440</code>
+ * <li> <code>session.getSessionId() => -7410986f:12addeea576:-7fff</code>
+ * <li> ------------------------------------------
+ * <li> <code>User user = session.getUser();</code>
+ * <ul> <li> <code>user.getUserId() => demoUser4</code>
+ * <li> <code>user.getInternalId() => be2dd2e:12a82ba707e:-7fee</code>
+ * <li> <code>user.getCn() => JoeUser4</code>
+ * <li> <code>user.getDescription() => Demo Test User 4</code>
+ * <li> <code>user.getOu() => test</code>
+ * <li> <code>user.getSn() => User4</code>
+ * <li> <code>user.getBeginDate() => 20090101</code>
+ * <li> <code>user.getEndDate() => none</code>
+ * <li> <code>user.getBeginLockDate() => none</code>
+ * <li> <code>user.getEndLockDate() => none</code>
+ * <li> <code>user.getDayMask() => 1234567</code>
+ * <li> <code>user.getTimeout() => 60</code>
+ * <li> <code>List<UserRole> roles = session.getRoles();</code>
+ * <ul> <li><code>UserRole userRole = roles.get(i);</code>
+ * <li> <code>userRole.getName() => role1</code>
+ * <li> <code>userRole.getBeginTime() => 0000</code>
+ * <li> <code>userRole.getEndTime() => 0000</code>
+ * <li> <code>userRole.getBeginDate() => none</code>
+ * <li> <code>userRole.getEndDate() => none</code>
+ * <li> <code>userRole.getBeginLockDate() => null</code>
+ * <li> <code>userRole.getEndLockDate() => null</code>
+ * <li> <code>userRole.getDayMask() => null</code>
+ * <li> <code>userRole.getTimeout() => 0</code>
+ * <li> <code>List<UserAdminRole> adminRoles = session.getAdminRoles();</code>
+ * </ul>
+ * <ul> <li><code>UserAdminRole userAdminRole = adminRoles.get(i);</code>
+ * <li> <code>userAdminRole.getName() => DemoAdminUsers</code>
+ * <li> <code>userAdminRole.getBeginTime() => 0000</code>
+ * <li> <code>userAdminRole.getEndTime() => 0000</code>
+ * <li> <code>userAdminRole.getBeginDate() => none</code>
+ * <li> <code>userAdminRole.getEndDate() => none</code>
+ * <li> <code>userAdminRole.getBeginLockDate() => null</code>
+ * <li> <code>userAdminRole.getEndLockDate() => null</code>
+ * <li> <code>userAdminRole.getDayMask() => null</code>
+ * <li> <code>userAdminRole.getTimeout() => 0</code>
+ * <li> <code>userAdminRole.getOsPs() => [ftT3POrg10, ftT4POrg10]</code>
+ * <li> <code>userAdminRole.getOsUs() => [ftT1UOrg10, ftT2UOrg10]</code>
+ * <li> <code>userAdminRole.getBeginRange() => ftT14Role1</code>
+ * <li> <code>userAdminRole.getEndRange() => ftT14Role10</code>
+ * <li> <code>userAdminRole.getBeginInclusive() => true</code>
+ * <li> <code>userAdminRole.getEndInclusive() => false</code>
+ * </ul>
+ * </ul>
+ * <p/>
+ * Sample Data data contained within this Entity.
+ * <p/>
+ * Ses UID [demoUser4]:<br />
+ * Ses IID [ccbb2929-bf01-413d-b768-529de4d428e5]<br />
+ * Ses ERR [0]<br />
+ * Ses WARN [10]<br />
+ * Ses MSG [checkPwPolicies for userId <demouser4> PASSWORD CHECK SUCCESS]<br />
+ * Ses EXP [0]<br />
+ * Ses GRAC [0]<br />
+ * Ses AUTH [true]<br />
+ * Ses LAST [1297408501356]<br />
+ * Ses SID [fc228713-1242-4061-9d8a-d4860bf8d3d8]<br />
+ * ------------------------------------------<br />
+ * Usr UID [demoUser4]<br />
+ * Usr IID [ccbb2929-bf01-413d-b768-529de4d428e5]<br />
+ * Usr CN [JoeUser4]<br />
+ * Usr DESC [Demo Test User 4]<br />
+ * Usr OU [demousrs1]<br />
+ * Usr SN [User4]<br />
+ * Usr BDTE [20090101]<br />
+ * Usr EDTE [20990101]<br />
+ * Usr BLDT [none]<br />
+ * Usr ELDT [none]<br />
+ * Usr DMSK [1234567]<br />
+ * Usr TO [60]<br />
+ * Usr REST [false]<br />
+ * Usr PROP1 [customerNumber, 3213432]<br />
+ * <p/>
+ * USER RBAC ROLE[0]:<br />
+ * Rle role name [role1]<br />
+ * Rle begin time [0000]<br />
+ * Rle end time [0000]<br />
+ * Rle begin date [20110101]<br />
+ * Rle end date [none]<br />
+ * Rle begin lock [none]<br />
+ * Rle end lock [none]<br />
+ * Rle day mask [all]<br />
+ * Rle time out [60]<br />
+ * <p/>
+ * USER ADMIN ROLE[0]:<br />
+ * Adm admin role name [DemoAdminUsers]<br />
+ * Adm OsU [Dev1]<br />
+ * Adm OsP [App1]<br />
+ * Adm begin range [role1]<br />
+ * Adm end range [role3]<br />
+ * Adm begin time [0000]<br />
+ * Adm end time [0000]<br />
+ * Adm begin date [20110101]<br />
+ * Adm end date [none]<br />
+ * Adm begin lock [none]<br />
+ * Adm end lock [none]<br />
+ * Adm day mask [23456]<br />
+ * Adm time out [30]<br />
+ * <p/>
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortSession")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "session", propOrder = {
+ "user",
+ "isAuthenticated",
+ "sessionId",
+ "lastAccess",
+ "timeout",
+ "errorId",
+ "expirationSeconds",
+ "graceLogins",
+ "message",
+ "warnings"
+/* "warningId"*/
+})
+public class Session extends FortEntity implements PwMessage, java.io.Serializable
+{
+ private User user;
+ private String sessionId;
+ private long lastAccess;
+ private int timeout;
+/* private int warningId;*/
+ private int errorId;
+ private int graceLogins;
+ private int expirationSeconds;
+ private boolean isAuthenticated;
+ private String message;
+ @XmlElement(nillable = true)
+ private List<Warning> warnings;
+
+ /**
+ * A 'true' value here indicates user successfully authenticated with Fortress.
+ *
+ * @return boolean indicating successful authentication.
+ */
+ public boolean isAuthenticated()
+ {
+ return isAuthenticated;
+ }
+
+ private void init()
+ {
+ // generate a unique id that will be used as the id for this session:
+ UUID uuid = UUID.randomUUID();
+ this.sessionId = uuid.toString();
+ }
+
+ /**
+ * Copy values from incoming Session object.
+ *
+ * @param inSession contains Session values.
+ */
+ public void copy(Session inSession)
+ {
+ this.user = inSession.getUser();
+ // don't copy session id:
+ //this.sessionId = inSession.getSessionId();
+ this.lastAccess = inSession.getLastAccess();
+ this.timeout = inSession.getTimeout();
+/* this.warningId = inSession.getWarningId();*/
+ this.errorId = inSession.getErrorId();
+ this.graceLogins = inSession.getGraceLogins();
+ this.expirationSeconds = inSession.expirationSeconds;
+ this.isAuthenticated = inSession.isAuthenticated();
+ this.message = inSession.getMsg();
+ this.warnings = inSession.getWarnings();
+ }
+
+ /**
+ * Default constructor for Fortress Session.
+ */
+ public Session()
+ {
+ init();
+ // this class will not check for null on user object.
+ this.user = new User();
+ }
+
+ /**
+ * Construct a new Session instance with given User entity.
+ *
+ * @param user contains the User attributes that are associated with the Session.
+ */
+ public Session(User user)
+ {
+ init();
+ this.user = user;
+ }
+
+ /**
+ * Construct a new Session instance with given User entity.
+ *
+ * @param user contains the User attributes that are associated with the Session.
+ */
+ public Session(User user, String sessionId)
+ {
+ this.sessionId = sessionId;
+ this.user = user;
+ }
+
+ /**
+ * Return the unique id that is associated with User. This attribute is generated automatically
+ * by Fortress when new Session is created and is not known or changeable by external client.
+ *
+ * @return attribute maps to unique sessionId associated with user's session.
+ */
+ public String getSessionId()
+ {
+ return this.sessionId;
+ }
+
+
+ /**
+ * Return the User entity that is associated with this entity.
+ *
+ * Sample User data contained in Session object:
+ * <p/>
+ * ------------------------------------------<br />
+ * U UID [demoUser4]<br />
+ * U IID [ccbb2929-bf01-413d-b768-529de4d428e5]<br />
+ * U CN [JoeUser4]<br />
+ * U DESC [Demo Test User 4]<br />
+ * U OU [demousrs1]<br />
+ * U SN [User4]<br />
+ * U BDTE [20090101]<br />
+ * U EDTE [20990101]<br />
+ * U BLDT [none]<br />
+ * U ELDT [none]<br />
+ * U DMSK [1234567]<br />
+ * U TO [60]<br />
+ * U REST [false]<br />
+ * U PROP[0]=customerNumber VAL=3213432<br />
+ * <p/>
+ * USER ROLE[0]:<br />
+ * role name <role1><br />
+ * begin time <0000><br />
+ * end time <0000><br />
+ * begin date <none><br />
+ * end date <none><br />
+ * begin lock <none><br />
+ * end lock <none><br />
+ * day mask <all><br />
+ * time out <0><br />
+ * <p/>
+ * USER ADMIN ROLE[0]:<br />
+ * admin role name <DemoAdminUsers><br />
+ * OsU <null><br />
+ * OsP <null><br />
+ * begin range <null><br />
+ * end range <null><br />
+ * begin time <0000><br />
+ * end time <0000><br />
+ * begin date <none><br />
+ * end date <none><br />
+ * begin lock <none><br />
+ * end lock <none><br />
+ * day mask <all><br />
+ * time out <0><br />
+ * <p/>
+ * @return User entity that contains userid, roles and other attributes valid for Session.
+ */
+ public User getUser()
+ {
+ return this.user;
+ }
+
+ /**
+ * Return the userId that is associated with this Session object.
+ *
+ * @return userId maps to the 'uid' attribute on the 'inetOrgPerson' object class.
+ */
+ public String getUserId()
+ {
+ return this.user.getUserId();
+ }
+
+ /**
+ * Return the internal userId that is associated with User. This attribute is generated automatically
+ * by Fortress when new User is added to directory and is not known or changeable by external client.
+ *
+ * @return attribute maps to 'ftId' in 'ftUserAttrs' object class.
+ */
+ public String getInternalUserId()
+ {
+ return this.user.getInternalId();
+ }
+
+ /**
+ * Return the list of User's RBAC Roles that have been activated into User's session. This list will not include
+ * ascendant RBAC roles which may be retrieved using {@link AccessMgrImpl#authorizedRoles(Session)}.
+ *
+ * @return List containing User's RBAC roles. This list may be empty if User not assigned RBAC.
+ */
+ public List<UserRole> getRoles()
+ {
+ List<UserRole> roles = null;
+
+ if (user != null)
+ roles = user.getRoles();
+
+ return roles;
+ }
+
+ /**
+ * Return a list of User's Admin Roles that have been activated into User's session. This list will not include
+ * ascendant ARBAC roles which may be retrieved using {@link org.apache.directory.fortress.core.DelAccessMgr#authorizedAdminRoles(Session)}.
+ *
+ * @return List containing User's Admin roles. This list may be empty if User not assigned Administrative role.
+ */
+ public List<UserAdminRole> getAdminRoles()
+ {
+ List<UserAdminRole> roles = null;
+
+ if (user != null)
+ roles = user.getAdminRoles();
+
+ return roles;
+ }
+
+ /**
+ * Returns the last access time in milliseconds. Note that while the unit of time of the return value is a millisecond,
+ * the granularity of the value depends on the underlying operating system and may be larger. For example, many
+ * operating systems measure time in units of tens of milliseconds.
+ *
+ * @return the difference, measured in milliseconds, between the last access time and midnight, January 1, 1970 UTC.
+ */
+ public long getLastAccess()
+ {
+ return this.lastAccess;
+ }
+
+ /**
+ * Gets the message that is associated with the user's last authentication attempt.
+ *
+ * @return String contains text explaining result of user's last authentication.
+ */
+ public String getMsg()
+ {
+ return this.message;
+ }
+
+ /**
+ * Gets the attribute that specifies the number of times an expired password can
+ * be used to authenticate before failure.
+ *
+ * @return The number of logins the user has left before password fails.
+ */
+ public int getGraceLogins()
+ {
+ return this.graceLogins;
+ }
+
+ /**
+ * This attribute specifies the maximum number of seconds before a
+ * password is due to expire that expiration warning messages will be
+ * returned to an authenticating user.
+ * <p/>
+ * If this attribute is not present, or if the value is 0 no warnings
+ * will be returned. If not 0, the value must be smaller than the value
+ * of the pwdMaxAge attribute.
+ *
+ * @return attribute is computed based on last time user has changed their password.
+ */
+ public int getExpirationSeconds()
+ {
+ return this.expirationSeconds;
+ }
+
+ /**
+ * Get the integer timeout that contains max time (in seconds) that User's session may remain inactive.
+ * This attribute is optional but if set will be validated for reasonableness.
+ *
+ * @return int maps to 'ftCstr' attribute in 'ftUserAttrs' object class.
+ */
+ private int getTimeout()
+ {
+ return this.timeout;
+ }
+
+ /**
+ * Get the value that will be set to 'true' if user has successfully authenticated with Fortress for this Session. This value is set by
+ * the Fortress DAO object.
+ *
+ * @return value indicates result of authentication.
+ */
+ public boolean setAuthenticated()
+ {
+ return this.isAuthenticated;
+ }
+
+ /**
+ * Return the error id that is associated with the password policy checks. a '0' indicates no errors.
+ * <ul>
+ * <li> <code>INVALID_PASSWORD_MESSAGE = -10;</code>
+ * <li> <code>GOOD = 0;</code>
+ * <li> <code>PASSWORD_HAS_EXPIRED = 100;</code>
+ * <li> <code>ACCOUNT_LOCKED = 101;</code>
+ * <li> <code>CHANGE_AFTER_RESET = 102;</code>
+ * <li> <code>NO_MODIFICATIONS = 103;</code>
+ * <li> <code>MUST_SUPPLY_OLD = 104;</code>
+ * <li> <code>INSUFFICIENT_QUALITY = 105;</code>
+ * <li> <code>PASSWORD_TOO_SHORT = 106;</code>
+ * <li> <code>PASSWORD_TOO_YOUNG = 107;</code>
+ * <li> <code>HISTORY_VIOLATION = 108;</code>
+ * <li> <code>ACCOUNT_LOCKED_CONSTRAINTS = 109;</code>
+ * </ul>
+ * <p/>
+ *
+ * @return int contains the error id that was generated on the user's last authentication.
+ */
+ public int getErrorId()
+ {
+ return this.errorId;
+ }
+
+ /**
+ * Set a User entity into the Session.
+ * Sample User data contained in Session object:
+ * <p/>
+ * ------------------------------------------<br />
+ * U UID [demoUser4]<br />
+ * U IID [ccbb2929-bf01-413d-b768-529de4d428e5]<br />
+ * U CN [JoeUser4]<br />
+ * U DESC [Demo Test User 4]<br />
+ * U OU [demousrs1]<br />
+ * U SN [User4]<br />
+ * U BDTE [20090101]<br />
+ * U EDTE [20990101]<br />
+ * U BLDT [none]<br />
+ * U ELDT [none]<br />
+ * U DMSK [1234567]<br />
+ * U TO [60]<br />
+ * U REST [false]<br />
+ * U PROP[0]=customerNumber VAL=3213432<br />
+ * <p/>
+ * USER ROLE[0]:<br />
+ * role name <role1><br />
+ * begin time <0000><br />
+ * end time <0000><br />
+ * begin date <none><br />
+ * end date <none><br />
+ * begin lock <none><br />
+ * end lock <none><br />
+ * day mask <all><br />
+ * time out <0><br />
+ * <p/>
+ * USER ADMIN ROLE[0]:<br />
+ * admin role name <DemoAdminUsers><br />
+ * OsU <null><br />
+ * OsP <null><br />
+ * begin range <null><br />
+ * end range <null><br />
+ * begin time <0000><br />
+ * end time <0000><br />
+ * begin date <none><br />
+ * end date <none><br />
+ * begin lock <none><br />
+ * end lock <none><br />
+ * day mask <all><br />
+ * time out <0><br />
+ * <p/>
+ * @param user Contains userId, roles and other security attributes used for access control.
+ */
+ public void setUser(User user)
+ {
+ this.user = user;
+ }
+
+ /**
+ * Set the internal userId that is associated with User. This method is used by DAO class and
+ * is generated automatically by Fortress. Attribute stored in LDAP cannot be changed by external caller.
+ * This method can be used by client for search purposes only.
+ *
+ * @param internalUserId maps to 'ftId' in 'ftUserAttrs' object class.
+ */
+ public void setInternalUserId(String internalUserId)
+ {
+ this.user.setInternalId(internalUserId);
+ }
+
+ /**
+ * Set the value to 'true' indicating that user has successfully authenticated with Fortress. This value is set by
+ * the Fortress DAO object.
+ *
+ * @param authenticated indicates result of authentication.
+ */
+ public void setAuthenticated(boolean authenticated)
+ {
+ isAuthenticated = authenticated;
+ }
+
+ /**
+ * Set the userId that is associated with User. UserId is required attribute and must be set on add, update, delete, createSession, authenticate, etc..
+ *
+ * @param userId maps to 'uid' attribute in 'inNetOrgPerson' object class.
+ */
+ public void setUserId(String userId)
+ {
+ this.user.setUserId(userId);
+ }
+
+
+ /**
+ * Add a list of RBAC Roles to this entity that have been activated into Session or are under consideration for activation.
+ *
+ * @param roles List of type UserRole that contains at minimum UserId and Role name.
+ */
+ public void setRoles(List<UserRole> roles)
+ {
+ this.user.setRoles(roles);
+ }
+
+ /**
+ * Add a single user-role object to the list of UserRoles for User.
+ *
+ * @param role UserRole contains at least userId and role name (activation) and additional constraints (assignment)
+ */
+ public void setRole(UserRole role)
+ {
+ user.setRole(role);
+ }
+
+ /**
+ * Set the integer timeout that contains max time (in seconds) that User's session may remain inactive.
+ * This attribute is optional but if set will be validated for reasonableness.
+ *
+ * @param timeout maps to 'ftCstr' attribute in 'ftUserAttrs' object class.
+ */
+ private void setTimeout(int timeout)
+ {
+ this.timeout = timeout;
+ }
+
+ /**
+ * Set the last access time in milliseconds. Note that while the unit of time of the return value is a millisecond,
+ * the granularity of the value depends on the underlying operating system and may be larger. For example, many
+ * operating systems measure time in units of tens of milliseconds.
+ */
+ public void setLastAccess()
+ {
+ this.lastAccess = System.currentTimeMillis();
+ }
+
+ /**
+ * Set the message that is associated with the user's last authentication attempt.
+ *
+ * @param message Contains text explaining result of user's last authentication.
+ */
+ public void setMsg(String message)
+ {
+ this.message = message;
+ }
+
+ /**
+ * Set the error id that is associated with the password policy checks. a '0' indicates no errors.
+ * <ul>
+ * <li> <code>INVALID_PASSWORD_MESSAGE = -10;</code>
+ * <li> <code>GOOD = 0;</code>
+ * <li> <code>PASSWORD_HAS_EXPIRED = 100;</code>
+ * <li> <code>ACCOUNT_LOCKED = 101;</code>
+ * <li> <code>CHANGE_AFTER_RESET = 102;</code>
+ * <li> <code>NO_MODIFICATIONS = 103;</code>
+ * <li> <code>MUST_SUPPLY_OLD = 104;</code>
+ * <li> <code>INSUFFICIENT_QUALITY = 105;</code>
+ * <li> <code>PASSWORD_TOO_SHORT = 106;</code>
+ * <li> <code>PASSWORD_TOO_YOUNG = 107;</code>
+ * <li> <code>HISTORY_VIOLATION = 108;</code>
+ * <li> <code>ACCOUNT_LOCKED_CONSTRAINTS = 109;</code>
+ * </ul>
+ * <p/>
+ *
+ * @param error contains the error id that was generated on the user's last authentication.
+ */
+ public void setErrorId(int error)
+ {
+ this.errorId = error;
+ }
+
+ /**
+ * This attribute specifies the number of times an expired password can
+ * be used to authenticate.
+ *
+ * @param grace The number of logins the user has left before password fails.
+ */
+ public void setGraceLogins(int grace)
+ {
+ this.graceLogins = grace;
+ }
+
+ /**
+ * This attribute specifies the maximum number of seconds before a
+ * password is due to expire that expiration warning messages will be
+ * returned to an authenticating user.
+ * <p/>
+ * If this attribute is not present, or if the value is 0 no warnings
+ * will be returned. If not 0, the value must be smaller than the value
+ * of the pwdMaxAge attribute.
+ *
+ * @param expire attribute is computed based on last time user has changed their password.
+ */
+ public void setExpirationSeconds(int expire)
+ {
+ this.expirationSeconds = expire;
+ }
+
+ /**
+ * Get the warnings attached to this Session. Used for processing password policy scenarios, e.g.. password expiring message.
+ *
+ * @return null value, zero or more objects of type {@link Warning} will be returned. Note: the caller of this method must ensure a not null condition before use.
+ */
+ public List<Warning> getWarnings()
+ {
+ return warnings;
+ }
+
+ /**
+ * Set the warnings on this Session. Used for processing password policy scenarios, e.g.. password expiring message.
+ * Not intended for use outside of Fortress packages.
+ *
+ * @param warnings zero or more objects of type warning may be set on a Fortress session.
+ */
+ public void setWarnings( List<Warning> warnings )
+ {
+ this.warnings = warnings;
+ }
+
+ /**
+ * Add a warning to the collection into Fortress Session object. Used for processing password policy scenarios, e.g.. password expiring message.
+ * Not intended for use outside of Fortress packages.
+ *
+ * @param warning one object of type warning will be added to Fortress session.
+ */
+ public void setWarning( Warning warning )
+ {
+ if ( warnings == null )
+ {
+ warnings = new ArrayList<>();
+ }
+ this.warnings.add( warning );
+ }
+}
\ No newline at end of file