Changeset 2490

Show
Ignore:
Timestamp:
10/03/08 13:26:17 (3 months ago)
Author:
dsanders
Message:

Added ability to read entities from a context. Also added ability to do anonymous reads.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/otis/src/org/bandit/otis/server/EntityHandler.java

    r2467 r2490  
    1818import javax.servlet.http.HttpServletRequest; 
    1919 
     20import org.bandit.otis.api.AuthSessionException; 
    2021import org.bandit.otis.impl.LocalAuthSession; 
     22import org.bandit.otis.impl.AuthMaterial; 
    2123 
    2224import org.eclipse.higgins.util.jscript.JScriptExec; 
     
    5153import java.util.List; 
    5254import java.util.Iterator; 
     55import java.util.Stack; 
    5356import java.util.regex.Pattern; 
    5457import java.util.regex.Matcher; 
     
    6265public class EntityHandler implements IOtisNounHandler 
    6366{ 
     67        public static final String              GET_CONTEXT_TEMPLATE_FILE_SETTING = "GET_ContextTemplateFile"; 
    6468        public static final String              GET_ENTITY_TEMPLATE_FILE_SETTING = "GET_EntityTemplateFile"; 
    6569        public static final String              GET_ATTRIBUTE_TEMPLATE_FILE_SETTING = "GET_AttributeTemplateFile"; 
    6670        public static final String              ENTITY_ID_POLICY_SETTING = "EntityIDPolicy"; 
    67          
    68         private Log     m_log = LogFactory.getLog( EntityHandler.class.getName()); 
    69         private Map     m_settings = null; 
     71        public static final String              ANONYMOUS_READ_SETTING = "AnonymousRead"; 
     72        public static final String              ANONYMOUS_READ_AUTH_METHOD_SETTING = "AnonymousReadAuthMethod"; 
     73        public static final String              ANONYMOUS_READ_AUTH_MATERIAL_SETTING = "AnonymousReadAuthMaterial"; 
     74        public static final String              AUTH_MATERIAL_ID_SETTING = "AuthMaterialID"; 
     75        public static final String              CHILD_MATERIALS_SETTING = "ChildMaterials"; 
     76        public static final String              AUTH_MATERIAL_VALUE_SETTING = "AuthMaterialValue"; 
     77         
     78        private Log                             m_log = LogFactory.getLog( EntityHandler.class.getName()); 
     79        private Map                             m_settings = null; 
     80        private boolean         m_bAnonReadAllowed = false; 
     81        private AuthMaterial    m_anonAuthMaterial = null; 
     82        private String                  m_strAnonAuthMethod = null; 
     83        private static Stack    m_availAnonSessions = new Stack(); 
     84        private Map                             m_localAuthSessionSettings = null; 
    7085 
    7186        EntityHandler() 
     
    7994                Map                             responseMap) throws OtisException 
    8095        { 
     96                Map     anonReadSettings; 
     97                 
    8198                m_settings = configuration; 
     99                m_localAuthSessionSettings = otisServlet.getLocalAuthSessionSettings(); 
     100                 
     101                // See if there is an authentication method and material for anonymous reading of entities. 
     102                 
     103                if ((anonReadSettings = (Map)m_settings.get( ANONYMOUS_READ_SETTING)) != null) 
     104                { 
     105                        if ((m_strAnonAuthMethod = (String)anonReadSettings.get( ANONYMOUS_READ_AUTH_METHOD_SETTING)) != null) 
     106                        { 
     107                                Map     authMaterialMap; 
     108                                 
     109                                // Get the authentication material, if any 
     110                                 
     111                                if ((authMaterialMap = (Map)anonReadSettings.get( ANONYMOUS_READ_AUTH_MATERIAL_SETTING)) != null) 
     112                                { 
     113                                        m_anonAuthMaterial = getAuthMaterial( authMaterialMap, responseMap); 
     114                                } 
     115                        } 
     116                } 
     117        } 
     118         
     119        private AuthMaterial getAuthMaterial( 
     120                Map     authMaterialMap, 
     121                Map     responseMap) throws OtisException 
     122        { 
     123                String                  strMaterialID = (String)authMaterialMap.get( AUTH_MATERIAL_ID_SETTING); 
     124                 
     125                if (strMaterialID == null) 
     126                { 
     127                        throwException( new OtisErrMsg( "No " + AUTH_MATERIAL_ID_SETTING + " setting specified for authentication material"), 
     128                                                                                null, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, responseMap); 
     129                } 
     130                AuthMaterial    authMaterial = new AuthMaterial( strMaterialID, null, false); 
     131                List                            childMaterials; 
     132                Object                  value; 
     133                 
     134                if ((childMaterials = (List)authMaterialMap.get( CHILD_MATERIALS_SETTING)) != null) 
     135                { 
     136                        for (int iLoop = 0; iLoop < childMaterials.size(); iLoop++) 
     137                        { 
     138                                try 
     139                                { 
     140                                        authMaterial.addChildMaterial( getAuthMaterial( (Map)childMaterials.get( iLoop), responseMap)); 
     141                                } 
     142                                catch (AuthSessionException e) 
     143                                { 
     144                                        throwException( new OtisErrMsg( "Exception " + e.getClass().getName() + " adding child material auth material '" + 
     145                                                                                                                        strMaterialID + "'", 
     146                                                                                        OtisErrMsg.OPTIONAL_STR( ": " + e.getMessage())), 
     147                                                                                e, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, responseMap); 
     148                                } 
     149                        } 
     150                } 
     151                else if ((value = authMaterialMap.get( AUTH_MATERIAL_VALUE_SETTING)) != null) 
     152                { 
     153                        try 
     154                        { 
     155                                authMaterial.setValue( value); 
     156                        } 
     157                        catch (AuthSessionException e) 
     158                        { 
     159                                throwException( new OtisErrMsg( "Exception " + e.getClass().getName() + " setting value for auth material '" + 
     160                                                                                                                        strMaterialID + "'", 
     161                                                                                        OtisErrMsg.OPTIONAL_STR( ": " + e.getMessage())), 
     162                                                                                e, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, responseMap); 
     163                        } 
     164                } 
     165                else 
     166                { 
     167                        throwException( new OtisErrMsg( "No " + CHILD_MATERIALS_SETTING + " or " + AUTH_MATERIAL_VALUE_SETTING + 
     168                                                                                " setting specified for authentication material '" + strMaterialID + "'"), 
     169                                                                                null, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, responseMap); 
     170                } 
     171                return( authMaterial); 
     172        } 
     173         
     174        private LocalAuthSession getAnonSession( 
     175                Map     responseMap) throws OtisException 
     176        { 
     177                LocalAuthSession        localAuthSession = null; 
     178                 
     179                synchronized( m_availAnonSessions) 
     180                { 
     181                        if (!m_availAnonSessions.empty()) 
     182                        { 
     183                                localAuthSession = (LocalAuthSession)m_availAnonSessions.pop(); 
     184                        } 
     185                } 
     186                 
     187                if (localAuthSession == null) 
     188                { 
     189                        try 
     190                        { 
     191                                localAuthSession = new LocalAuthSession( m_localAuthSessionSettings); 
     192                        } 
     193                        catch (AuthSessionException e) 
     194                        { 
     195                                throwException( new OtisErrMsg( "Exception " + e.getClass().getName() + " creating session object for anonymous read", 
     196                                        OtisErrMsg.OPTIONAL_STR( ": " + e.getMessage())), 
     197                                        e, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, responseMap); 
     198                        } 
     199                         
     200                        // Try to authenticate 
     201                         
     202                        try 
     203                        { 
     204                                localAuthSession.authenticate( m_strAnonAuthMethod, m_anonAuthMaterial); 
     205                        } 
     206                        catch (AuthSessionException e) 
     207                        { 
     208                                throwException( new OtisErrMsg( "Exception " + e.getClass().getName() + " authenticating session for anonymous read", 
     209                                        OtisErrMsg.OPTIONAL_STR( ": " + e.getMessage())), 
     210                                        e, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, responseMap); 
     211                        } 
     212                } 
     213                return( localAuthSession); 
     214        } 
     215         
     216        private void makeAnonSessionAvailable( 
     217                LocalAuthSession        localAuthSession) 
     218        { 
     219                synchronized( m_availAnonSessions) 
     220                { 
     221                        m_availAnonSessions.push( localAuthSession); 
     222                } 
    82223        } 
    83224         
     
    286427        private List makeAttrList( 
    287428                String          strSessionID, 
    288                 String          strEntityID, 
     429                String          strAttrContainer, 
    289430                String []       strAttrList, 
    290431                Map                     responseMap) throws OtisException 
     
    299440                                if (!strAttrList [iLoop].trim().equals( "")) 
    300441                                { 
    301                                         validateAttrID( strSessionID, "EntityID='" + strEntityID + "'", strAttrList [iLoop], null, "read", responseMap); 
     442                                        validateAttrID( strSessionID, strAttrContainer, strAttrList [iLoop], null, "read", responseMap); 
    302443                                        try 
    303444                                        { 
     
    307448                                        { 
    308449                                                throwException( new OtisErrMsg( "EntityHandler", 
    309                                                         OtisErrMsg.OPTIONAL_STR( "(session='" + strSessionID + "', Entity='" + strEntityID + "')"), 
     450                                                        OtisErrMsg.OPTIONAL_STR( "(session='" + strSessionID + "', " + strAttrContainer + ")"), 
    310451                                                        ": URISyntaxException parsing attribute URI", 
    311452                                                        OtisErrMsg.OPTIONAL_STR( " '" + strAttrList [iLoop] + "': " + e.getMessage())), 
     
    317458                        { 
    318459                                throwException( new OtisErrMsg( "EntityHandler", 
    319                                         OtisErrMsg.OPTIONAL_STR( "(session='" + strSessionID + "', Entity='" + strEntityID + "')"), 
     460                                        OtisErrMsg.OPTIONAL_STR( "(session='" + strSessionID + "', " + strAttrContainer + ")"), 
    320461                                        ": Empty attribute list specified for Entity"), 
    321462                                        null, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, responseMap); 
     
    370511                Map                                     responseMap) throws OtisException 
    371512        { 
    372                 List            attrList = this.makeAttrList( strSessionID, strEntityID, strAttrList, responseMap); 
     513                List            attrList = this.makeAttrList( strSessionID, "EntityID='" + strEntityID + "'", strAttrList, responseMap); 
    373514                IEntity entity = this.getEntity( localAuthSession, strSessionID, strEntityID, attrList, responseMap); 
    374515 
     
    395536                { 
    396537                        responseMap.put( Constants.TEMPLATE_ATTR_LIST, entityAttrList); 
     538                } 
     539        } 
     540         
     541        private void queryContext( 
     542                LocalAuthSession        localAuthSession, 
     543                String                          strSessionID, 
     544                String []                       strAttrList, 
     545                Map                                     responseMap) throws OtisException 
     546        { 
     547                List            attrList = this.makeAttrList( strSessionID, "Context", strAttrList, responseMap); 
     548                Iterator        entityIter = null; 
     549                List            entityList = new ArrayList(); 
     550 
     551                // Get the entities 
     552                 
     553                try 
     554                { 
     555                        entityIter = localAuthSession.getEntities( null, (attrList != null) ? attrList.iterator() : null); 
     556                        while (entityIter.hasNext()) 
     557                        { 
     558                                IEntity entity = (IEntity)entityIter.next(); 
     559                                Map             entityMap = new HashMap(); 
     560//                              URI             entityType = entity.getModel().getType(); 
     561                                URI             entityType = entity.getEntityType(); 
     562                                String  strEntityID = entity.getEntityID(); 
     563                         
     564                                entityMap.put( Constants.TEMPLATE_ENTITY_TYPE, entityType.toString()); 
     565                                entityMap.put( Constants.TEMPLATE_ENTITY_ID, strEntityID); 
     566                                 
     567                                List    entityAttrList; 
     568                                if ((entityAttrList = queryAttributes( strSessionID, "Entity='" + strEntityID + "'", entity, attrList, responseMap)) != null) 
     569                                { 
     570                                        entityMap.put( Constants.TEMPLATE_ATTR_LIST, entityAttrList); 
     571                                } 
     572                                entityList.add( entityMap); 
     573                        } 
     574                } 
     575                catch (IdASException e) 
     576                { 
     577                        throwException( new OtisErrMsg( "EntityHandler", 
     578                                                OtisErrMsg.OPTIONAL_STR( "(session='" + strSessionID + ")"), 
     579                                                ": Exception '" + e.getClass().getName() + " occurred while reading entities", 
     580                                                OtisErrMsg.OPTIONAL_STR( ": " + e.getMessage())), 
     581                                        e, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, responseMap); 
     582                } 
     583                 
     584                if (entityList.size() > 0) 
     585                { 
     586                        responseMap.put( Constants.TEMPLATE_ENTITY_LIST, entityList); 
    397587                } 
    398588        } 
     
    17451935                        // VISIT: We may need to ask for any attributes that are to be modified 
    17461936                         
    1747                         attrList = this.makeAttrList( strSessionID, strEntityID, null, responseMap); 
     1937                        attrList = this.makeAttrList( strSessionID, "EntityID='" + strEntityID + "'", null, responseMap); 
    17481938                        entity = this.getEntity( localAuthSession, strSessionID, strEntityID, attrList, responseMap); 
    17491939                         
     
    18442034                try 
    18452035                { 
    1846                         List            attrList = this.makeAttrList( strSessionID, strEntityID, strAttrList, responseMap); 
     2036                        List            attrList = this.makeAttrList( strSessionID, "EntityID='" + strEntityID + "'", strAttrList, responseMap); 
    18472037                        IEntity entity = this.getEntity( localAuthSession, strSessionID, strEntityID, attrList, responseMap); 
    18482038                         
     
    21192309                String []                       strAttrList; 
    21202310                int                                     iHttpResponseCode = HttpServletResponse.SC_OK; 
    2121                 LocalAuthSession        localAuthSession; 
     2311                LocalAuthSession        localAuthSession = null; 
    21222312                int                                     iMainNounPos = 0; 
    21232313                String                          strGetTemplateSetting; 
     2314                boolean                         bAnonSession = false; 
    21242315                 
    21252316                // If the path did not begin with AuthenticatedSession, we need to get the authenticated session from the header 
     
    21572348                                if (strSessionID == null) 
    21582349                                { 
    2159                                         throwException( new OtisErrMsg( "EntityHandler: No session ID specified in URL, headers, or cookies"), 
     2350                                        if (m_strAnonAuthMethod != null && iHttpOperation == Constants.RESOURCE_READ) 
     2351                                        { 
     2352                                                localAuthSession = getAnonSession( responseMap); 
     2353                                                strSessionID = "ANONYMOUS"; 
     2354                                                bAnonSession = true; 
     2355                                        } 
     2356                                        else 
     2357                                        { 
     2358                                                throwException( new OtisErrMsg( "EntityHandler: No session ID specified in URL, headers, or cookies"), 
    21602359                                                        null, HttpServletResponse.SC_NOT_FOUND, responseMap); 
    2161                                 } 
    2162                         } 
    2163                 } 
    2164                 strSubnoun = (String)nounList.get( iMainNounPos); 
    2165  
    2166                 if ((localAuthSession = AuthenticatedSessionHandler.getSession(strSessionID)) == null) 
    2167                 { 
    2168                         throwException( new OtisErrMsg( "EntityHandler: Session ", 
    2169                                         OtisErrMsg.OPTIONAL_STR( "'" + strSessionID + "' "), "not found"), 
    2170                                         null, HttpServletResponse.SC_NOT_FOUND, responseMap); 
    2171                 } 
    2172                  
    2173                 synchronized (localAuthSession) 
    2174                 { 
    2175                         AuthenticatedSessionHandler.validateSessionSecret( m_log, localAuthSession, request.getHeader( Constants.OTIS_SESSION_SECRET_HEADER), responseMap); 
    2176                         switch (iHttpOperation) 
    2177                         { 
    2178                                 case Constants.RESOURCE_READ: 
    2179                                         if (!strSubnoun.equals( Constants.NOUN_ENTITY)) 
    2180                                         { 
    2181                                                 throwException( new OtisErrMsg( "EntityHandler", 
    2182                                                         OtisErrMsg.OPTIONAL_STR( "(session='" + strSessionID + "')"), 
    2183                                                         ": Invalid sub-noun", 
    2184                                                         OtisErrMsg.OPTIONAL_STR( ": " + strSubnoun)), 
     2360                                        } 
     2361                                } 
     2362                        } 
     2363                } 
     2364                try 
     2365                {                
     2366                        strSubnoun = (String)nounList.get( iMainNounPos); 
     2367         
     2368                        if (localAuthSession == null) 
     2369                        { 
     2370                                if ((localAuthSession = AuthenticatedSessionHandler.getSession(strSessionID)) == null) 
     2371                                { 
     2372                                        throwException( new OtisErrMsg( "EntityHandler: Session ", 
     2373                                                        OtisErrMsg.OPTIONAL_STR( "'" + strSessionID + "' "), "not found"), 
    21852374                                                        null, HttpServletResponse.SC_NOT_FOUND, responseMap); 
    2186                                         } 
    2187                                         if (nounList.size() < iMainNounPos + 2) 
    2188                                         { 
    2189                                                 throwException( new OtisErrMsg( "EntityHandler(GET", 
    2190                                                         OtisErrMsg.OPTIONAL_STR( ", session='" + strSessionID + "'"), 
    2191                                                         "): No entity ID specified in URL", 
    2192                                                         OtisErrMsg.OPTIONAL_STR( " '" + request.getRequestURL().toString() + "'")), 
    2193                                                         null, HttpServletResponse.SC_NOT_FOUND, responseMap); 
    2194                                         } 
    2195                                         strEntityID = (String)nounList.get( iMainNounPos + 1); 
    2196                                         validateEntityID( strSessionID, strEntityID, responseMap); 
    2197                                         strAttrList = request.getParameterValues( Constants.PARAM_ATTR); 
    2198                                         strGetTemplateSetting = GET_ENTITY_TEMPLATE_FILE_SETTING; 
    2199                                         if (nounList.size() == iMainNounPos + 2) 
    2200                                         { 
    2201                                                 queryEntity( localAuthSession, strSessionID, strEntityID, strAttrList, responseMap); 
    2202                                         } 
    2203                                         else 
    2204                                         { 
    2205                                                 strSubnoun = (String)nounList.get( iMainNounPos + 2); 
    2206                                                  
    2207                                                 if (!strSubnoun.equals( Constants.NOUN_ATTRIBUTE)) 
     2375                                } 
     2376                        } 
     2377 
     2378                        synchronized (localAuthSession) 
     2379                        { 
     2380                                if (!bAnonSession) 
     2381                                { 
     2382                                        AuthenticatedSessionHandler.validateSessionSecret( m_log, localAuthSession, request.getHeader( Constants.OTIS_SESSION_SECRET_HEADER), responseMap); 
     2383                                } 
     2384                                switch (iHttpOperation) 
     2385                                { 
     2386                                        case Constants.RESOURCE_READ: 
     2387                                                if (strSubnoun.equals( Constants.NOUN_CONTEXT)) 
    22082388                                                { 
    2209                                                         throwException( new OtisErrMsg( "EntityHandler", 
    2210                                                                 OtisErrMsg.OPTIONAL_STR( "(session='" + strSessionID + "', Entity='" + strEntityID + "')"), 
    2211                                                                 ": Invalid Entity sub-noun", 
    2212                                                                 OtisErrMsg.OPTIONAL_STR( ": " + strSubnoun)), 
    2213                                                                 null, HttpServletResponse.SC_NOT_FOUND, responseMap); 
    2214                                                 } 
    2215                                                 else if (nounList.size() < iMainNounPos + 4) 
    2216                                                 { 
    2217                                                         throwException( new OtisErrMsg( "EntityHandler", 
    2218                                                                 OtisErrMsg.OPTIONAL_STR( "(session='" + strSessionID + "', Entity='" + strEntityID + "')"), 
    2219                                                                 ": Expecting attribute ID after the ", 
    2220                                                                 OtisErrMsg.OPTIONAL_STR( strSubnoun + " "), "sub-noun"), 
    2221                                                                 null, HttpServletResponse.SC_NOT_FOUND, responseMap); 
     2389                                                        strAttrList = request.getParameterValues( Constants.PARAM_ATTR); 
     2390                                                        queryContext( localAuthSession, strSessionID, strAttrList, responseMap);  
     2391                                                        if ((strTemplateFile = (String)m_settings.get( GET_CONTEXT_TEMPLATE_FILE_SETTING)) == null) 
     2392                                                        { 
     2393                                                                throwException( new OtisErrMsg( "EntityHandler(GET Context", 
     2394                                                                        OtisErrMsg.OPTIONAL_STR( ", session='" + strSessionID + "'"), 
     2395                                                                        "): No " + GET_CONTEXT_TEMPLATE_FILE_SETTING + " specified in settings"), 
     2396                                                                        null, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, responseMap);  
     2397                                                        } 
    22222398                                                } 
    22232399                                                else 
    22242400                                                { 
    2225                                                         strGetTemplateSetting = GET_ATTRIBUTE_TEMPLATE_FILE_SETTING; 
    2226                                                          
    2227                                                         // Make an attribute list consisting of exactly one attribute 
    2228                                                          
    2229                                                         strAttrList = new String [1]; 
    2230                                                         strAttrList [0] = (String)nounList.get( iMainNounPos + 3); 
    2231                                                         List            attrList = this.makeAttrList( strSessionID, strEntityID, strAttrList, responseMap); 
    2232                                                         IEntity entity = this.getEntity( localAuthSession, strSessionID, strEntityID, attrList, responseMap); 
    2233                                                         List            attrs = this.queryAttributes( strSessionID, "Entity='" + strEntityID + "'", entity, attrList, responseMap); 
    2234                                                          
    2235                                                         // transfer the single attribute's stuff directly into the responseMap 
    2236          
    2237                                                         if (attrs == null) 
     2401                                                        if (!strSubnoun.equals( Constants.NOUN_ENTITY)) 
    22382402                                                        { 
    22392403                                                                throwException( new OtisErrMsg( "EntityHandler", 
    2240                                                                         OtisErrMsg.OPTIONAL_STR( "(session='" + strSessionID + "', Entity='" + strEntityID + "')"), 
    2241                                                                         ": Attribute ID ", 
    2242                                                                         OtisErrMsg.OPTIONAL_STR( "'" + ((URI)attrList.get( 0)).toString() + "' "), 
    2243                                                                         "not found"), 
     2404                                                                        OtisErrMsg.OPTIONAL_STR( "(session='" + strSessionID + "')"), 
     2405                                                                        ": Invalid sub-noun", 
     2406                                                                        OtisErrMsg.OPTIONAL_STR( ": " + strSubnoun)), 
    22442407                                                                        null, HttpServletResponse.SC_NOT_FOUND, responseMap); 
     2408                                                        } 
     2409                                                        if (nounList.size() < iMainNounPos + 2) 
     2410                                                        { 
     2411                                                                throwException( new OtisErrMsg( "EntityHandler(GET", 
     2412                                                                        OtisErrMsg.OPTIONAL_STR( ", session='" + strSessionID + "'"), 
     2413                                                                        "): No entity ID specified in URL", 
     2414                                                                        OtisErrMsg.OPTIONAL_STR( " '" + request.getRequestURL().toString() + "'")), 
     2415                                                                        null, HttpServletResponse.SC_NOT_FOUND, responseMap); 
     2416                                                        } 
     2417                                                        strEntityID = (String)nounList.get( iMainNounPos + 1); 
     2418                                                        validateEntityID( strSessionID, strEntityID, responseMap); 
     2419                                                        strAttrList = request.getParameterValues( Constants.PARAM_ATTR); 
     2420                                                        strGetTemplateSetting = GET_ENTITY_TEMPLATE_FILE_SETTING; 
     2421                                                        if (nounList.size() == iMainNounPos + 2) 
     2422                                                        { 
     2423                                                                queryEntity( localAuthSession, strSessionID, strEntityID, strAttrList, responseMap); 
    22452424                                                        } 
    22462425                                                        else 
    22472426                                                        {