Revise attribute APIs to use vectors in place of multimaps.
[shibboleth/sp.git] / shibsp / impl / XMLAccessControl.cpp
index e1f1383..9f223c9 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
- *  Copyright 2001-2005 Internet2\r
+ *  Copyright 2001-2007 Internet2\r
  * \r
  * Licensed under the Apache License, Version 2.0 (the "License");\r
  * you may not use this file except in compliance with the License.\r
@@ -24,6 +24,8 @@
 #include "exceptions.h"\r
 #include "AccessControl.h"\r
 #include "SessionCache.h"\r
+#include "SPRequest.h"\r
+#include "attribute/Attribute.h"\r
 \r
 #include <xmltooling/util/ReloadableXMLFile.h>\r
 #include <xmltooling/util/XMLHelper.h>\r
@@ -79,7 +81,8 @@ namespace {
     class XMLAccessControl : public AccessControl, public ReloadableXMLFile\r
     {\r
     public:\r
-        XMLAccessControl(const DOMElement* e) : ReloadableXMLFile(e), m_rootAuthz(NULL) {\r
+        XMLAccessControl(const DOMElement* e)\r
+                : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".AccessControl")), m_rootAuthz(NULL) {\r
             load(); // guarantees an exception or the policy is loaded\r
         }\r
         \r
@@ -115,7 +118,9 @@ namespace {
 \r
 void SHIBSP_API shibsp::registerAccessControls()\r
 {\r
-    SPConfig::getConfig().AccessControlManager.registerFactory(XML_ACCESS_CONTROL, XMLAccessControlFactory);\r
+    SPConfig& conf=SPConfig::getConfig();\r
+    conf.AccessControlManager.registerFactory(XML_ACCESS_CONTROL, XMLAccessControlFactory);\r
+    conf.AccessControlManager.registerFactory("edu.internet2.middleware.shibboleth.sp.provider.XMLAccessControl", XMLAccessControlFactory);\r
 }\r
 \r
 Rule::Rule(const DOMElement* e)\r
@@ -144,55 +149,39 @@ Rule::Rule(const DOMElement* e)
 \r
 bool Rule::authorized(const SPRequest& request, const Session* session) const\r
 {\r
-    /*\r
-    TODO: port...\r
+    // We can make this more complex later using pluggable comparison functions,\r
+    // but for now, just a straight port to the new Attribute API.\r
+\r
     // Map alias in rule to the attribute.\r
-    Iterator<IAAP*> provs=st->getApplication()->getAAPProviders();\r
-    AAP wrapper(provs,m_alias.c_str());\r
-    if (wrapper.fail()) {\r
-        st->log(ShibTarget::LogLevelWarn, string("AccessControl plugin didn't recognize rule (") + m_alias + "), check AAP for corresponding Alias");\r
+    if (!session) {\r
+        request.log(SPRequest::SPWarn, "AccessControl plugin not given a valid session to evaluate, are you using lazy sessions?");\r
         return false;\r
     }\r
-    else if (!entry) {\r
-        st->log(ShibTarget::LogLevelWarn, "AccessControl plugin not given a valid session to evaluate, are you using lazy sessions?");\r
+    \r
+    // Find the attribute(s) matching the require rule.\r
+    pair<multimap<string,const Attribute*>::const_iterator, multimap<string,const Attribute*>::const_iterator> attrs =\r
+        session->getIndexedAttributes().equal_range(m_alias);\r
+    if (attrs.first == attrs.second) {\r
+        request.log(SPRequest::SPWarn, string("rule requires attribute (") + m_alias + "), not found in session");\r
         return false;\r
     }\r
-    \r
-    // Find the corresponding attribute. This isn't very efficient...\r
-    pair<const char*,const SAMLResponse*> filtered=entry->getFilteredTokens(false,true);\r
-    Iterator<SAMLAssertion*> a_iter(filtered.second ? filtered.second->getAssertions() : EMPTY(SAMLAssertion*));\r
-    while (a_iter.hasNext()) {\r
-        SAMLAssertion* assert=a_iter.next();\r
-        Iterator<SAMLStatement*> statements=assert->getStatements();\r
-        while (statements.hasNext()) {\r
-            SAMLAttributeStatement* astate=dynamic_cast<SAMLAttributeStatement*>(statements.next());\r
-            if (!astate)\r
-                continue;\r
-            Iterator<SAMLAttribute*> attrs=astate->getAttributes();\r
-            while (attrs.hasNext()) {\r
-                SAMLAttribute* attr=attrs.next();\r
-                if (!XMLString::compareString(attr->getName(),wrapper->getName()) &&\r
-                    !XMLString::compareString(attr->getNamespace(),wrapper->getNamespace())) {\r
-                    // Now we have to intersect the attribute's values against the rule's list.\r
-                    Iterator<string> vals=attr->getSingleByteValues();\r
-                    if (!vals.hasNext())\r
-                        return false;\r
-                    for (vector<string>::const_iterator ival=m_vals.begin(); ival!=m_vals.end(); ival++) {\r
-                        vals.reset();\r
-                        while (vals.hasNext()) {\r
-                            const string& v=vals.next();\r
-                            if ((wrapper->getCaseSensitive() && v == *ival) || (!wrapper->getCaseSensitive() && !strcasecmp(v.c_str(),ival->c_str()))) {\r
-                                st->log(ShibTarget::LogLevelDebug, string("XMLAccessControl plugin expecting " + *ival + ", authz granted"));\r
-                                return true;\r
-                            }\r
-                        }\r
-                    }\r
+\r
+    for (; attrs.first != attrs.second; ++attrs.first) {\r
+        bool caseSensitive = attrs.first->second->isCaseSensitive();\r
+\r
+        // Now we have to intersect the attribute's values against the rule's list.\r
+        const vector<string>& vals = attrs.first->second->getSerializedValues();\r
+        for (vector<string>::const_iterator i=m_vals.begin(); i!=m_vals.end(); ++i) {\r
+            for (vector<string>::const_iterator j=vals.begin(); j!=vals.end(); ++j) {\r
+                if ((caseSensitive && *i == *j) || (!caseSensitive && !strcasecmp(i->c_str(),j->c_str()))) {\r
+                    request.log(SPRequest::SPDebug, string("AccessControl plugin expecting ") + *j + ", authz granted");\r
+                    return true;\r
                 }\r
             }\r
         }\r
     }\r
-    */\r
-    return true;\r
+\r
+    return false;\r
 }\r
 \r
 Operator::Operator(const DOMElement* e)\r
@@ -260,7 +249,7 @@ bool Operator::authorized(const SPRequest& request, const Session* session) cons
             return false;\r
         }\r
     }\r
-    //st->log(ShibTarget::LogLevelWarn,"Unknown operation in access control policy, denying access");\r
+    request.log(SPRequest::SPWarn,"unknown operation in access control policy, denying access");\r
     return false;\r
 }\r
 \r