CMS 3D CMS Logo

XMLAuthenticationService.cc
Go to the documentation of this file.
4 #include "RelationalAccess/AuthenticationCredentials.h"
5 #include "CoralCommon/Cipher.h"
6 #include "RelationalAccess/AuthenticationServiceException.h"
7 #include "CoralKernel/IPropertyManager.h"
8 #include "CoralKernel/Property.h"
9 #include "CoralKernel/Context.h"
12 #include "xercesc/parsers/XercesDOMParser.hpp"
13 #include "xercesc/framework/MemBufInputSource.hpp"
14 #include "xercesc/dom/DOM.hpp"
15 #include "xercesc/sax/HandlerBase.hpp"
16 #include "xercesc/util/XMLString.hpp"
17 #include "xercesc/util/PlatformUtils.hpp"
19 
20 #include <memory>
21 #include <cstdlib>
22 #include <fstream>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <boost/filesystem.hpp>
26 #include <boost/version.hpp>
27 #include <boost/bind.hpp>
28 //#include <iostream>
29 #include "CoralBase/MessageStream.h"
30 
31 constexpr char XML_AUTHENTICATION_FILE[] = "authentication.xml";
32 
34  const std::string& connectionName ):
35  m_serviceName( serviceName ),
36  m_connectionName( connectionName ),
37  m_default( new coral::AuthenticationCredentials( serviceName ) ),
38  m_data()
39 {}
40 
42 {
43  delete m_default;
44  for ( std::map< std::string, coral::AuthenticationCredentials* >::iterator iData = m_data.begin();
45  iData != m_data.end(); ++iData )
46  delete iData->second;
47 }
48 
49 void
51  const std::string& value )
52 {
53  m_default->registerItem( item, value );
54 }
55 
56 void
58  const std::string& value,
59  const std::string& role )
60 {
61  std::map< std::string, coral::AuthenticationCredentials* >::iterator iRole = m_data.find( role );
62  if ( iRole == m_data.end() ) {
63  iRole = m_data.insert( std::make_pair( role, new coral::AuthenticationCredentials( m_serviceName ) ) ).first;
64  }
65  iRole->second->registerItem( item, value );
66 }
67 
68 const coral::IAuthenticationCredentials&
70 {
71  return *m_default;
72 }
73 
74 const coral::IAuthenticationCredentials&
76 {
85  return *m_default;
86 }
87 
89  : coral::Service( key ),
90  m_isInitialized( false ),
91  m_inputFileName( "" ),
92  m_data(),
93  m_mutexLock(),
94  m_callbackID(0)
95 {
96  boost::function1<void, std::string> cb(boost::bind(&cond::XMLAuthenticationService::XMLAuthenticationService::setAuthenticationPath, this, _1));
97 
98  coral::Property* pm = dynamic_cast<coral::Property*>(coral::Context::instance().PropertyManager().property(auth::COND_AUTH_PATH_PROPERTY));
99  if(pm){
100  setAuthenticationPath( pm->get() );
101  m_callbackID = pm->registerCallback(cb);
102  }
103 }
104 
106 {
107  for ( std::map< std::string, cond::XMLAuthenticationService::DataSourceEntry* >::iterator iConnection = m_data.begin();
108  iConnection != m_data.end(); ++iConnection ) delete iConnection->second;
109 }
110 
111 void
113 {
114  boost::filesystem::path boostAuthPath( inputPath );
115  if(boost::filesystem::is_directory(boostAuthPath)){
117  }
118 
119  m_inputFileName = boostAuthPath.string();
120  reset();
121 }
122 
123 bool
125 {
126  coral::MessageStream log("cond::XMLAuthenticationService::processFile");
127  //std::cout<< "Processing file \""<< inputFileName<<"\"" <<std::endl;
128  bool result = true;
129 
131  std::string cont("");
132  try{
133  inputFile.read(inputFileName);
134  cont = inputFile.content();
135  } catch (const cond::Exception& exc){
136  log << coral::Error << "File \"" << inputFileName << "\" not found."<<std::string(exc.what())<<coral::MessageStream::endmsg;
137  return false;
138  }
139 
140  // check the
141  boost::filesystem::path filePath( inputFileName );
142 #if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 47
143  std::string name = filePath.filename().string();
144 #else
145  std::string name = filePath.leaf();
146 #endif
147 
168  xercesc::MemBufInputSource* memBufInputSource = nullptr;
169 
170  try
171  {
172  xercesc::XercesDOMParser parser;
173  parser.setValidationScheme( xercesc::XercesDOMParser::Val_Always );
174  parser.setDoNamespaces( true );
175 
176  xercesc::HandlerBase errorHandler;
177  parser.setErrorHandler( &errorHandler );
178 
179 
180  const char* bufferId="InMemoryDocument";
181  const char* buffer = cont.c_str();
182 
183  memBufInputSource = new xercesc::MemBufInputSource( (const XMLByte*)buffer,strlen(buffer),bufferId,false );
184 
185  parser.parse(*memBufInputSource);
186 
187  xercesc::DOMDocument* document = parser.getDocument();
188 
189  XMLCh tempStr[20];
190  xercesc::XMLString::transcode( "connection", tempStr, 19);
191 
192  xercesc::DOMNodeList* connectionList = document->getElementsByTagName( tempStr );
193 
194  if ( connectionList )
195  {
196  XMLSize_t numberOfConnections = connectionList->getLength();
197 
198  for ( XMLSize_t iConnection = 0; iConnection < numberOfConnections; ++iConnection )
199  {
200  xercesc::DOMNode* connectionNode = connectionList->item( iConnection );
201 
202  if ( connectionNode )
203  {
204  char* connectionName = xercesc::XMLString::transcode( connectionNode->getAttributes()->item( 0 )->getNodeValue() );
205  std::string sConnectionName = connectionName;
206  xercesc::XMLString::release( &connectionName );
207 
208  // Locate the credential
210  std::map< std::string, cond::XMLAuthenticationService::DataSourceEntry* >::iterator iConnection = m_data.find( sConnectionName );
211  if ( iConnection != m_data.end() ) {
212  credential = iConnection->second;
213  // Issue a warning here.
214  //coral::MessageStream log( this, this->name(),seal::Msg::Verbose );
215  log<<coral::Debug<<"Credential parameters for connection string \""
216  << sConnectionName
217  << "\" have already been defined. Only new elements are appended, while existing will be ignored."
218  << coral::MessageStream::endmsg;
219  } else {
220  credential = new cond::XMLAuthenticationService::DataSourceEntry( this->name(), sConnectionName );
221  m_data.insert( std::make_pair( sConnectionName, credential ) );
222  }
223 
224  xercesc::DOMNodeList* parameterList = connectionNode->getChildNodes();
225 
226  if ( parameterList )
227  {
228  XMLSize_t numberOfParameters = parameterList->getLength();
229 
230  for ( XMLSize_t iParameter = 0; iParameter < numberOfParameters; ++iParameter )
231  {
232  xercesc::DOMNode* parameterNode = parameterList->item( iParameter );
233 
234  if ( parameterNode && parameterNode->getNodeType() == xercesc::DOMNode::ELEMENT_NODE )
235  {
236  char* nodeName = xercesc::XMLString::transcode( parameterNode->getNodeName() );
237  std::string sNodeName = nodeName;
238  xercesc::XMLString::release( &nodeName );
239 
240  if ( sNodeName == "parameter" ) { // The default parameters
241  char* parameterName = xercesc::XMLString::transcode( parameterNode->getAttributes()->item( 0 )->getNodeValue() );
242  std::string sParameterName = parameterName;
243  xercesc::XMLString::release( &parameterName );
244  char* parameterValue = xercesc::XMLString::transcode( parameterNode->getAttributes()->item( 1 )->getNodeValue() );
245  std::string sParameterValue = parameterValue;
246  xercesc::XMLString::release( &parameterValue );
247 
248  credential->appendCredentialItem( sParameterName, sParameterValue );
249  }
250  else if ( sNodeName == "role" ) { // A role
251  char* roleName = xercesc::XMLString::transcode( parameterNode->getAttributes()->item( 0 )->getNodeValue() );
252  std::string sRoleName = roleName;
253  xercesc::XMLString::release( &roleName );
254 
255  // Retrieve the parameters for the role
256  xercesc::DOMNodeList* roleParameterList = parameterNode->getChildNodes();
257 
258 
259  if ( roleParameterList )
260  {
261  XMLSize_t numberOfRoleParameters = roleParameterList->getLength();
262 
263  for ( XMLSize_t iRoleParameter = 0; iRoleParameter < numberOfRoleParameters; ++iRoleParameter )
264  {
265  xercesc::DOMNode* roleParameterNode = roleParameterList->item( iRoleParameter );
266  if ( roleParameterNode && roleParameterNode->getNodeType() == xercesc::DOMNode::ELEMENT_NODE )
267  {
268  char* roleNodeName = xercesc::XMLString::transcode( roleParameterNode->getNodeName() );
269  std::string sRoleNodeName = roleNodeName;
270  xercesc::XMLString::release( &roleNodeName );
271 
272  if ( sRoleNodeName == "parameter" ) {
273  char* roleParameterName = xercesc::XMLString::transcode( roleParameterNode->getAttributes()->item( 0 )->getNodeValue() );
274  std::string sRoleParameterName = roleParameterName;
275  xercesc::XMLString::release( &roleParameterName );
276  char* roleParameterValue = xercesc::XMLString::transcode( roleParameterNode->getAttributes()->item( 1 )->getNodeValue() );
277  std::string sRoleParameterValue = roleParameterValue;
278  xercesc::XMLString::release( &roleParameterValue );
279 
280  credential->appendCredentialItemForRole( sRoleParameterName, sRoleParameterValue, sRoleName );
281  }
282  }
283  }
284  }
285  }
286  }
287  }
288  }
289  }
290  }
291  }
292 
293  parser.reset();
294  }
295  catch ( const xercesc::XMLException& toCatch )
296  {
297  char* message = xercesc::XMLString::transcode( toCatch.getMessage() );
298  //coral::MessageStream log( this, this->name(),coral::Msg::Verbose );
299  //log << coral::Msg::Error << message << coral::flush;
300  log<<coral::Error<<std::string(message)<<coral::MessageStream::endmsg;
301  xercesc::XMLString::release( &message );
302  result = false;
303  }
304  catch ( const xercesc::DOMException& toCatch )
305  {
306  char* message = xercesc::XMLString::transcode( toCatch.msg );
307  //seal::MessageStream log( this, this->name(),seal::Msg::Verbose );
308  //log << seal::Msg::Error << message << seal::flush;
309  log<<coral::Error<<std::string(message)<<coral::MessageStream::endmsg;
310  xercesc::XMLString::release( &message );
311  result = false;
312  }
313  catch ( const xercesc::SAXException& toCatch )
314  {
315  char* message = xercesc::XMLString::transcode( toCatch.getMessage() );
316  //seal::MessageStream log( this, this->name(),seal::Msg::Verbose );
317  //log << seal::Msg::Error << message << seal::flush;
318  log<<coral::Error<<std::string(message)<<coral::MessageStream::endmsg;
319  xercesc::XMLString::release( &message );
320  result = false;
321  }
322  catch (...){
323  //seal::MessageStream log( this, this->name(),seal::Msg::Verbose );
324  //log << seal::Msg::Error << "Unexpected Exception parsing file \"" << inputFileName << "\"" << seal::flush;
325  log<<coral::Error<<"Unexpected Exception parsing file \"" << inputFileName << "\"" <<coral::MessageStream::endmsg;
326  result = false;
327  }
328  if(memBufInputSource) delete memBufInputSource;
329  return result;
330 }
331 
332 
333 bool
335 {
336  coral::MessageStream log("cond::XMLAuthenticationService::initialize");
337  std::set< std::string > inputFileNames = this->verifyFileName();
338  if ( inputFileNames.empty() )
339  {
340  //seal::MessageStream log( this, this->name(),seal::Msg::Verbose );
341  //std::cout<< "Could not open \"" << m_inputFileName << "\" for reading" << std::endl;
342  log<<coral::Debug<<"Could not open \"" << m_inputFileName << "\" for reading" <<coral::MessageStream::endmsg;
343  return false;
344  }
345 
346  try
347  {
349  }
350  catch ( const xercesc::XMLException& toCatch )
351  {
352  char* message = xercesc::XMLString::transcode( toCatch.getMessage() );
353  //seal::MessageStream log( this, this->name(),seal::Msg::Verbose );
354  //log << seal::Msg::Error << message << seal::flush;
355  log<<coral::Error<<std::string(message)<<coral::MessageStream::endmsg;
356  xercesc::XMLString::release( &message );
357  return false;
358  }
359 
360  bool result = false;
361  for ( std::set< std::string >::const_reverse_iterator iFileName = inputFileNames.rbegin();
362  iFileName != inputFileNames.rend(); ++iFileName ) {
363  if ( this->processFile( *iFileName ) ) {
364  result = true;
365  }
366  }
367 
369 
371  if(!m_isInitialized) reset();
372  return result;
373 }
374 
376  for ( std::map< std::string, cond::XMLAuthenticationService::DataSourceEntry* >::iterator iConnection = m_data.begin();
377  iConnection != m_data.end(); ++iConnection ) delete iConnection->second;
378  m_data.clear();
379  m_isInitialized = false;
380 }
381 
382 
383 
384 const coral::IAuthenticationCredentials&
386 {
387  boost::mutex::scoped_lock lock(m_mutexLock);
388  if ( ! m_isInitialized ) {
390  }
391  std::map< std::string, cond::XMLAuthenticationService::DataSourceEntry* >::const_iterator iConnection = m_data.find( connectionString );
392  if ( iConnection == m_data.end() )
393  throw coral::UnknownConnectionException( this->name(), connectionString );
394  return iConnection->second->credentials();
395 }
396 
397 
398 const coral::IAuthenticationCredentials&
400  const std::string& role ) const
401 {
402  boost::mutex::scoped_lock lock(m_mutexLock);
403  if ( ! m_isInitialized ) {
405  }
406  std::map< std::string, cond::XMLAuthenticationService::DataSourceEntry* >::const_iterator iConnection = m_data.find( connectionString );
407  if ( iConnection == m_data.end() )
408  throw coral::UnknownConnectionException( this->name(), connectionString );
409  return iConnection->second->credentials( role );
410 }
411 
412 
413 std::set< std::string >
415 {
416  coral::MessageStream log("cond::XMLAuthenticationService::verifyFileName");
417  std::set< std::string > fileNames;
418 
419  // Try the file name as is...
421  if ( boost::filesystem::exists( m_inputFileName ) ) {
422  if(boost::filesystem::is_directory( m_inputFileName )){
423  //seal::MessageStream log( this, this->name(),seal::Msg::Verbose );
424  log <<coral::Error << "Provided path \"" << m_inputFileName << "\" is a directory." <<coral::MessageStream::endmsg;
425  return fileNames;
426  }
427  boost::filesystem::path& fullPath = filePath.normalize();
428  fileNames.insert( fullPath.string() );
429  if(filePath.is_complete()) return fileNames;
430  }
431 
432  // Try to find other files in the path variable
433  const char* thePathVariable = ::getenv( "CORAL_AUTH_PATH" );
434  if ( ! thePathVariable ) return fileNames;
435  log<<coral::Debug<< "File \"" << m_inputFileName << "\" not found in the current directory. Trying in the search path." <<coral::MessageStream::endmsg;
436 
437  std::string searchPath(thePathVariable);
438  //std::cout<<"searchPath "<<searchPath<<std::endl;
439  if(boost::filesystem::exists(searchPath)){
440  if(!boost::filesystem::is_directory( searchPath )){
441  log<<coral::Debug<<"Search path \"" << searchPath << "\" is not a directory."<<coral::MessageStream::endmsg;
442  return fileNames;
443  }
444  boost::filesystem::path fullPath( searchPath );
445  fullPath /= filePath;
446  fileNames.insert( fullPath.string() );
447  } else {
448  log<<coral::Debug<<"Search path \"" << searchPath << "\" does not exist."<<coral::MessageStream::endmsg;
449  return fileNames;
450  }
451 
452  return fileNames;
453 }
454 
455 DEFINE_CORALSERVICE(cond::XMLAuthenticationService::XMLAuthenticationService,"COND/Services/XMLAuthenticationService");
std::map< std::string, coral::AuthenticationCredentials * > m_data
The structure with the authentication data for the various roles.
edm::ErrorSummaryEntry Error
void appendCredentialItemForRole(const std::string &item, const std::string &value, const std::string &role)
Base exception class for the object to relational access.
Definition: Exception.h:11
bool initialize()
Service framework related initialization.
static PFTauRenderPlugin instance
void xercesTerminate()
Definition: Xerces.cc:23
static constexpr const char *const COND_AUTH_PATH_PROPERTY
Definition: Auth.h:27
char const * what() const override
Definition: Exception.cc:103
void xercesInitialize()
Definition: Xerces.cc:18
static const std::string serviceName
bool m_isInitialized
Flag indicating whether the service has been initialized.
#define DEFINE_CORALSERVICE(type, name)
std::set< std::string > verifyFileName()
Verifies the existence of the authentication files.
coral::AuthenticationCredentials * m_default
The input file with the data.
char XML_AUTHENTICATION_FILE[]
bool read(const std::string &fileName)
Definition: FileUtils.cc:6
XMLAuthenticationService(const std::string &name)
Standard Constructor.
void setAuthenticationPath(const std::string &inputPath)
Sets the input file name.
const coral::IAuthenticationCredentials & credentials(const std::string &connectionString) const override
Definition: Binary.h:9
Definition: value.py:1
std::map< std::string, DataSourceEntry * > m_data
The structure with the authentication data.
const std::string & content() const
Definition: FileUtils.h:31
bool processFile(const std::string &inputFileName)
Parses an xml file.
void appendCredentialItem(const std::string &item, const std::string &value)
const coral::IAuthenticationCredentials & credentials() const
std::string m_inputFileName
The input file with the data.
const bool Debug
#define constexpr