pion-net  4.0.9
net/src/HTTPAuth.cpp
00001 // ------------------------------------------------------------------
00002 // pion-net: a C++ framework for building lightweight HTTP interfaces
00003 // ------------------------------------------------------------------
00004 // Copyright (C) 2007-2008 Atomic Labs, Inc.  (http://www.atomiclabs.com)
00005 //
00006 // Distributed under the Boost Software License, Version 1.0.
00007 // See http://www.boost.org/LICENSE_1_0.txt
00008 //
00009 
00010 #include <boost/algorithm/string.hpp>
00011 #include <pion/net/HTTPAuth.hpp>
00012 #include <pion/net/HTTPServer.hpp>
00013 
00014 
00015 namespace pion {    // begin namespace pion
00016 namespace net {     // begin namespace net (Pion Network Library)
00017 
00018 
00019 // HTTPAuth member functions
00020 
00021 void HTTPAuth::addRestrict(const std::string& resource)
00022 {
00023     boost::mutex::scoped_lock resource_lock(m_resource_mutex);
00024     const std::string clean_resource(HTTPServer::stripTrailingSlash(resource));
00025     m_restrict_list.insert(clean_resource);
00026     PION_LOG_INFO(m_logger, "Set authentication restrictions for HTTP resource: " << clean_resource);
00027 }
00028 
00029 void HTTPAuth::addPermit(const std::string& resource)
00030 {
00031     boost::mutex::scoped_lock resource_lock(m_resource_mutex);
00032     const std::string clean_resource(HTTPServer::stripTrailingSlash(resource));
00033     m_white_list.insert(clean_resource);
00034     PION_LOG_INFO(m_logger, "Set authentication permission for HTTP resource: " << clean_resource);
00035 }
00036 
00037 bool HTTPAuth::needAuthentication(const HTTPRequestPtr& http_request) const
00038 {
00039     // if no users are defined, authentication is never required
00040     if (m_user_manager->empty())
00041         return false;
00042     
00043     // strip off trailing slash if the request has one
00044     std::string resource(HTTPServer::stripTrailingSlash(http_request->getResource()));
00045     
00046     boost::mutex::scoped_lock resource_lock(m_resource_mutex);
00047     
00048     // just return false if restricted list is empty
00049     if (m_restrict_list.empty())
00050         return false;
00051 
00052     // try to find resource in restricted list
00053     if (findResource(m_restrict_list, resource)) {
00054         // return true if white list is empty
00055         if (m_white_list.empty())
00056             return true;
00057         // return false if found in white list, or true if not found
00058         return ( ! findResource(m_white_list, resource) );
00059     }
00060     
00061     // resource not found in restricted list
00062     return false;
00063 }
00064 
00065 bool HTTPAuth::findResource(const AuthResourceSet& resource_set,
00066                             const std::string& resource) const
00067 {
00068     AuthResourceSet::const_iterator i = resource_set.upper_bound(resource);
00069     while (i != resource_set.begin()) {
00070         --i;
00071         // check for a match if the first part of the strings match
00072         if (i->empty() || resource.compare(0, i->size(), *i) == 0) {
00073             // only if the resource matches exactly 
00074             // or if resource is followed first with a '/' character
00075             if (resource.size() == i->size() || resource[i->size()]=='/') {
00076                 return true;
00077             }
00078         }
00079     }
00080     return false;
00081 }
00082 
00083   
00084 }   // end namespace net
00085 }   // end namespace pion