pion  5.0.6
src/http_auth.cpp
00001 // ---------------------------------------------------------------------
00002 // pion:  a Boost C++ framework for building lightweight HTTP interfaces
00003 // ---------------------------------------------------------------------
00004 // Copyright (C) 2007-2014 Splunk Inc.  (https://github.com/splunk/pion)
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/http/auth.hpp>
00012 #include <pion/http/server.hpp>
00013 
00014 
00015 namespace pion {    // begin namespace pion
00016 namespace http {    // begin namespace http
00017 
00018 
00019 // auth member functions
00020 
00021 void auth::add_restrict(const std::string& resource)
00022 {
00023     boost::mutex::scoped_lock resource_lock(m_resource_mutex);
00024     const std::string clean_resource(http::server::strip_trailing_slash(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 auth::add_permit(const std::string& resource)
00030 {
00031     boost::mutex::scoped_lock resource_lock(m_resource_mutex);
00032     const std::string clean_resource(http::server::strip_trailing_slash(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 auth::need_authentication(const http::request_ptr& http_request_ptr) 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(http::server::strip_trailing_slash(http_request_ptr->get_resource()));
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 (find_resource(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 ( ! find_resource(m_white_list, resource) );
00059     }
00060     
00061     // resource not found in restricted list
00062     return false;
00063 }
00064 
00065 bool auth::find_resource(const resource_set_type& resource_set,
00066                             const std::string& resource) const
00067 {
00068     resource_set_type::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 http
00085 }   // end namespace pion