CMS 3D CMS Logo

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