LCOV - code coverage report
Current view: top level - core/auth - qgsauthmethodregistry.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 24 161 14.9 %
Date: 2021-03-26 12:19:53 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :     qgsauthmethodregistry.cpp
       3                 :            :     ---------------------
       4                 :            :     begin                : September 1, 2015
       5                 :            :     copyright            : (C) 2015 by Boundless Spatial, Inc. USA
       6                 :            :     author               : Larry Shaffer
       7                 :            :     email                : lshaffer at boundlessgeo dot com
       8                 :            :  ***************************************************************************
       9                 :            :  *                                                                         *
      10                 :            :  *   This program is free software; you can redistribute it and/or modify  *
      11                 :            :  *   it under the terms of the GNU General Public License as published by  *
      12                 :            :  *   the Free Software Foundation; either version 2 of the License, or     *
      13                 :            :  *   (at your option) any later version.                                   *
      14                 :            :  *                                                                         *
      15                 :            :  ***************************************************************************/
      16                 :            : 
      17                 :            : #include "qgsauthmethodregistry.h"
      18                 :            : 
      19                 :            : #include <QString>
      20                 :            : #include <QDir>
      21                 :            : #include <QLibrary>
      22                 :            : 
      23                 :            : #include "qgis.h"
      24                 :            : #include "qgsauthconfig.h"
      25                 :            : #include "qgsauthmethod.h"
      26                 :            : #include "qgslogger.h"
      27                 :            : #include "qgsmessageoutput.h"
      28                 :            : #include "qgsmessagelog.h"
      29                 :            : #include "qgsauthmethodmetadata.h"
      30                 :            : 
      31                 :            : 
      32                 :            : // typedefs for auth method plugin functions of interest
      33                 :            : typedef QString methodkey_t();
      34                 :            : typedef QString description_t();
      35                 :            : typedef bool    isauthmethod_t();
      36                 :            : 
      37                 :            : 
      38                 :          3 : QgsAuthMethodRegistry *QgsAuthMethodRegistry::instance( const QString &pluginPath )
      39                 :            : {
      40                 :          3 :   static QgsAuthMethodRegistry *sInstance( new QgsAuthMethodRegistry( pluginPath ) );
      41                 :          3 :   return sInstance;
      42                 :          0 : }
      43                 :            : 
      44                 :          3 : QgsAuthMethodRegistry::QgsAuthMethodRegistry( const QString &pluginPath )
      45                 :          3 : {
      46                 :            :   // At startup, examine the libs in the qgis/lib dir and store those that
      47                 :            :   // are an auth method shared lib
      48                 :            :   // check all libs in the current plugin directory and get name and descriptions
      49                 :            : #if 0
      50                 :            :   char **argv = qApp->argv();
      51                 :            :   QString appDir = argv[0];
      52                 :            :   int bin = appDir.findRev( "/bin", -1, false );
      53                 :            :   QString baseDir = appDir.left( bin );
      54                 :            :   QString mLibraryDirectory = baseDir + "/lib";
      55                 :            : #endif
      56                 :          3 :   mLibraryDirectory.setPath( pluginPath );
      57                 :          3 :   mLibraryDirectory.setSorting( QDir::Name | QDir::IgnoreCase );
      58                 :          3 :   mLibraryDirectory.setFilter( QDir::Files | QDir::NoSymLinks );
      59                 :            : 
      60                 :            : #if defined(Q_OS_WIN) || defined(__CYGWIN__)
      61                 :            :   mLibraryDirectory.setNameFilters( QStringList( "*authmethod.dll" ) );
      62                 :            : #else
      63                 :          6 :   mLibraryDirectory.setNameFilters( QStringList( QStringLiteral( "*authmethod.so" ) ) );
      64                 :            : #endif
      65                 :            : 
      66                 :          3 :   QgsDebugMsgLevel( QStringLiteral( "Checking for auth method plugins in: %1" ).arg( mLibraryDirectory.path() ), 2 );
      67                 :            : 
      68                 :          3 :   if ( mLibraryDirectory.count() == 0 )
      69                 :            :   {
      70                 :          3 :     QString msg = QObject::tr( "No QGIS auth method plugins found in:\n%1\n" ).arg( mLibraryDirectory.path() );
      71                 :          3 :     msg += QObject::tr( "No authentication methods can be used. Check your QGIS installation" );
      72                 :            : 
      73                 :          3 :     QgsMessageOutput *output = QgsMessageOutput::createMessageOutput();
      74                 :          3 :     output->setTitle( QObject::tr( "No Authentication Methods" ) );
      75                 :          3 :     output->setMessage( msg, QgsMessageOutput::MessageText );
      76                 :          3 :     output->showMessage();
      77                 :            :     return;
      78                 :          3 :   }
      79                 :            : 
      80                 :            :   // auth method file regex pattern, only files matching the pattern are loaded if the variable is defined
      81                 :          0 :   QString filePattern = getenv( "QGIS_AUTHMETHOD_FILE" );
      82                 :          0 :   QRegExp fileRegexp;
      83                 :          0 :   if ( !filePattern.isEmpty() )
      84                 :            :   {
      85                 :          0 :     fileRegexp.setPattern( filePattern );
      86                 :          0 :   }
      87                 :            : 
      88                 :          0 :   QListIterator<QFileInfo> it( mLibraryDirectory.entryInfoList() );
      89                 :          0 :   while ( it.hasNext() )
      90                 :            :   {
      91                 :          0 :     QFileInfo fi( it.next() );
      92                 :            : 
      93                 :          0 :     if ( !fileRegexp.isEmpty() )
      94                 :            :     {
      95                 :          0 :       if ( fileRegexp.indexIn( fi.fileName() ) == -1 )
      96                 :            :       {
      97                 :          0 :         QgsDebugMsg( "auth method " + fi.fileName() + " skipped because doesn't match pattern " + filePattern );
      98                 :          0 :         continue;
      99                 :            :       }
     100                 :          0 :     }
     101                 :            : 
     102                 :          0 :     QLibrary myLib( fi.filePath() );
     103                 :          0 :     if ( !myLib.load() )
     104                 :            :     {
     105                 :          0 :       QgsDebugMsg( QStringLiteral( "Checking %1: ...invalid (lib not loadable): %2" ).arg( myLib.fileName(), myLib.errorString() ) );
     106                 :          0 :       continue;
     107                 :            :     }
     108                 :            : 
     109                 :            :     // get the description and the key for the auth method plugin
     110                 :          0 :     isauthmethod_t *isAuthMethod = reinterpret_cast< isauthmethod_t * >( cast_to_fptr( myLib.resolve( "isAuthMethod" ) ) );
     111                 :          0 :     if ( !isAuthMethod )
     112                 :            :     {
     113                 :          0 :       QgsDebugMsg( QStringLiteral( "Checking %1: ...invalid (no isAuthMethod method)" ).arg( myLib.fileName() ) );
     114                 :          0 :       continue;
     115                 :            :     }
     116                 :            : 
     117                 :            :     // check to see if this is an auth method plugin
     118                 :          0 :     if ( !isAuthMethod() )
     119                 :            :     {
     120                 :          0 :       QgsDebugMsg( QStringLiteral( "Checking %1: ...invalid (not an auth method)" ).arg( myLib.fileName() ) );
     121                 :          0 :       continue;
     122                 :            :     }
     123                 :            : 
     124                 :            :     // looks like an auth method plugin. get the key and description
     125                 :          0 :     description_t *pDesc = reinterpret_cast< description_t * >( cast_to_fptr( myLib.resolve( "description" ) ) );
     126                 :          0 :     if ( !pDesc )
     127                 :            :     {
     128                 :          0 :       QgsDebugMsg( QStringLiteral( "Checking %1: ...invalid (no description method)" ).arg( myLib.fileName() ) );
     129                 :          0 :       continue;
     130                 :            :     }
     131                 :            : 
     132                 :          0 :     methodkey_t *pKey = reinterpret_cast< methodkey_t * >( cast_to_fptr( myLib.resolve( "authMethodKey" ) ) );
     133                 :          0 :     if ( !pKey )
     134                 :            :     {
     135                 :          0 :       QgsDebugMsg( QStringLiteral( "Checking %1: ...invalid (no authMethodKey method)" ).arg( myLib.fileName() ) );
     136                 :          0 :       continue;
     137                 :            :     }
     138                 :            : 
     139                 :            :     // add this auth method to the method map
     140                 :          0 :     mAuthMethods[pKey()] = new QgsAuthMethodMetadata( pKey(), pDesc(), myLib.fileName() );
     141                 :            : 
     142                 :          0 :   }
     143                 :          3 : }
     144                 :            : 
     145                 :            : // typedef for the unload auth method function
     146                 :            : typedef void cleanupAuthMethod_t();
     147                 :            : 
     148                 :          0 : QgsAuthMethodRegistry::~QgsAuthMethodRegistry()
     149                 :          0 : {
     150                 :          0 :   AuthMethods::const_iterator it = mAuthMethods.begin();
     151                 :            : 
     152                 :          0 :   while ( it != mAuthMethods.end() )
     153                 :            :   {
     154                 :          0 :     QgsDebugMsgLevel( QStringLiteral( "cleanup: %1" ).arg( it->first ), 5 );
     155                 :          0 :     QString lib = it->second->library();
     156                 :          0 :     QLibrary myLib( lib );
     157                 :          0 :     if ( myLib.isLoaded() )
     158                 :            :     {
     159                 :          0 :       cleanupAuthMethod_t *cleanupFunc = reinterpret_cast< cleanupAuthMethod_t * >( cast_to_fptr( myLib.resolve( "cleanupAuthMethod" ) ) );
     160                 :          0 :       if ( cleanupFunc )
     161                 :          0 :         cleanupFunc();
     162                 :          0 :     }
     163                 :            :     // clear cached QgsAuthMethodMetadata *
     164                 :          0 :     delete it->second;
     165                 :          0 :     ++it;
     166                 :          0 :   }
     167                 :          0 : }
     168                 :            : 
     169                 :            : 
     170                 :            : /**
     171                 :            :  * Convenience function for finding any existing auth methods that match "authMethodKey"
     172                 :            : 
     173                 :            :   Necessary because [] map operator will create a QgsProviderMetadata
     174                 :            :   instance.  Also you cannot use the map [] operator in const members for that
     175                 :            :   very reason.  So there needs to be a convenient way to find an auth method
     176                 :            :   without accidentally adding a null meta data item to the metadata map.
     177                 :            : */
     178                 :          0 : static QgsAuthMethodMetadata *findMetadata_( QgsAuthMethodRegistry::AuthMethods const &metaData,
     179                 :            :     QString const &authMethodKey )
     180                 :            : {
     181                 :            :   QgsAuthMethodRegistry::AuthMethods::const_iterator i =
     182                 :          0 :     metaData.find( authMethodKey );
     183                 :            : 
     184                 :          0 :   if ( i != metaData.end() )
     185                 :            :   {
     186                 :          0 :     return i->second;
     187                 :            :   }
     188                 :            : 
     189                 :          0 :   return nullptr;
     190                 :          0 : } // findMetadata_
     191                 :            : 
     192                 :            : 
     193                 :          0 : QString QgsAuthMethodRegistry::library( const QString &authMethodKey ) const
     194                 :            : {
     195                 :          0 :   QgsAuthMethodMetadata *md = findMetadata_( mAuthMethods, authMethodKey );
     196                 :            : 
     197                 :          0 :   if ( md )
     198                 :            :   {
     199                 :          0 :     return md->library();
     200                 :            :   }
     201                 :            : 
     202                 :          0 :   return QString();
     203                 :          0 : }
     204                 :            : 
     205                 :          0 : QString QgsAuthMethodRegistry::pluginList( bool asHtml ) const
     206                 :            : {
     207                 :          0 :   AuthMethods::const_iterator it = mAuthMethods.begin();
     208                 :            : 
     209                 :          0 :   if ( mAuthMethods.empty() )
     210                 :            :   {
     211                 :          0 :     return QObject::tr( "No authentication method plugins are available." );
     212                 :            :   }
     213                 :            : 
     214                 :          0 :   QString list;
     215                 :            : 
     216                 :          0 :   if ( asHtml )
     217                 :            :   {
     218                 :          0 :     list += QLatin1String( "<ol>" );
     219                 :          0 :   }
     220                 :            : 
     221                 :          0 :   while ( it != mAuthMethods.end() )
     222                 :            :   {
     223                 :          0 :     if ( asHtml )
     224                 :            :     {
     225                 :          0 :       list += QLatin1String( "<li>" );
     226                 :          0 :     }
     227                 :            : 
     228                 :          0 :     list += it->second->description();
     229                 :            : 
     230                 :          0 :     if ( asHtml )
     231                 :            :     {
     232                 :          0 :       list += QLatin1String( "<br></li>" );
     233                 :          0 :     }
     234                 :            :     else
     235                 :            :     {
     236                 :          0 :       list += '\n';
     237                 :            :     }
     238                 :            : 
     239                 :          0 :     ++it;
     240                 :            :   }
     241                 :            : 
     242                 :          0 :   if ( asHtml )
     243                 :            :   {
     244                 :          0 :     list += QLatin1String( "</ol>" );
     245                 :          0 :   }
     246                 :            : 
     247                 :          0 :   return list;
     248                 :          0 : }
     249                 :            : 
     250                 :          0 : QDir QgsAuthMethodRegistry::libraryDirectory() const
     251                 :            : {
     252                 :          0 :   return mLibraryDirectory;
     253                 :            : }
     254                 :            : 
     255                 :          0 : void QgsAuthMethodRegistry::setLibraryDirectory( const QDir &path )
     256                 :            : {
     257                 :          0 :   mLibraryDirectory = path;
     258                 :          0 : }
     259                 :            : 
     260                 :            : 
     261                 :            : // typedef for the QgsDataProvider class factory
     262                 :            : typedef QgsAuthMethod *classFactoryFunction_t();
     263                 :            : 
     264                 :          0 : std::unique_ptr<QgsAuthMethod> QgsAuthMethodRegistry::authMethod( const QString &authMethodKey )
     265                 :            : {
     266                 :            :   // load the plugin
     267                 :          0 :   QString lib = library( authMethodKey );
     268                 :            : 
     269                 :            : #ifdef TESTAUTHMETHODLIB
     270                 :            :   const char *cLib = lib.toUtf8();
     271                 :            : 
     272                 :            :   // test code to help debug auth method plugin loading problems
     273                 :            :   //  void *handle = dlopen(cLib, RTLD_LAZY);
     274                 :            :   void *handle = dlopen( cOgrLib, RTLD_LAZY | RTLD_GLOBAL );
     275                 :            :   if ( !handle )
     276                 :            :   {
     277                 :            :     QgsLogger::warning( "Error in dlopen" );
     278                 :            :   }
     279                 :            :   else
     280                 :            :   {
     281                 :            :     QgsDebugMsg( QStringLiteral( "dlopen succeeded" ) );
     282                 :            :     dlclose( handle );
     283                 :            :   }
     284                 :            : 
     285                 :            : #endif
     286                 :            :   // load the auth method
     287                 :          0 :   QLibrary myLib( lib );
     288                 :            : 
     289                 :          0 :   QgsDebugMsgLevel( "Auth method library name is " + myLib.fileName(), 2 );
     290                 :          0 :   if ( !myLib.load() )
     291                 :            :   {
     292                 :          0 :     QgsMessageLog::logMessage( QObject::tr( "Failed to load %1: %2" ).arg( lib, myLib.errorString() ) );
     293                 :          0 :     return nullptr;
     294                 :            :   }
     295                 :            : 
     296                 :          0 :   classFactoryFunction_t *classFactory = reinterpret_cast< classFactoryFunction_t * >( cast_to_fptr( myLib.resolve( "classFactory" ) ) );
     297                 :          0 :   if ( !classFactory )
     298                 :            :   {
     299                 :          0 :     QgsDebugMsg( QStringLiteral( "Failed to load %1: no classFactory method" ).arg( lib ) );
     300                 :          0 :     return nullptr;
     301                 :            :   }
     302                 :            : 
     303                 :          0 :   std::unique_ptr< QgsAuthMethod > authMethod( classFactory() );
     304                 :          0 :   if ( !authMethod )
     305                 :            :   {
     306                 :          0 :     QgsMessageLog::logMessage( QObject::tr( "Unable to instantiate the auth method plugin %1" ).arg( lib ) );
     307                 :          0 :     myLib.unload();
     308                 :          0 :     return nullptr;
     309                 :            :   }
     310                 :            : 
     311                 :          0 :   QgsDebugMsgLevel( QStringLiteral( "Instantiated the auth method plugin: %1" ).arg( authMethod->key() ), 2 );
     312                 :          0 :   return authMethod;
     313                 :          0 : }
     314                 :            : 
     315                 :            : typedef QWidget *editFactoryFunction_t( QWidget *parent );
     316                 :            : 
     317                 :          0 : QWidget *QgsAuthMethodRegistry::editWidget( const QString &authMethodKey, QWidget *parent )
     318                 :            : {
     319                 :          0 :   editFactoryFunction_t *editFactory =
     320                 :          0 :     reinterpret_cast< editFactoryFunction_t * >( cast_to_fptr( function( authMethodKey, QStringLiteral( "editWidget" ) ) ) );
     321                 :            : 
     322                 :          0 :   if ( !editFactory )
     323                 :          0 :     return nullptr;
     324                 :            : 
     325                 :          0 :   return editFactory( parent );
     326                 :          0 : }
     327                 :            : 
     328                 :          0 : QFunctionPointer QgsAuthMethodRegistry::function( QString const &authMethodKey,
     329                 :            :     QString const &functionName )
     330                 :            : {
     331                 :          0 :   QLibrary myLib( library( authMethodKey ) );
     332                 :            : 
     333                 :          0 :   QgsDebugMsgLevel( "Library name is " + myLib.fileName(), 2 );
     334                 :            : 
     335                 :          0 :   if ( myLib.load() )
     336                 :            :   {
     337                 :          0 :     return myLib.resolve( functionName.toLatin1().data() );
     338                 :            :   }
     339                 :            :   else
     340                 :            :   {
     341                 :          0 :     QgsDebugMsg( "Cannot load library: " + myLib.errorString() );
     342                 :          0 :     return nullptr;
     343                 :            :   }
     344                 :          0 : }
     345                 :            : 
     346                 :          0 : std::unique_ptr<QLibrary> QgsAuthMethodRegistry::authMethodLibrary( const QString &authMethodKey ) const
     347                 :            : {
     348                 :          0 :   std::unique_ptr< QLibrary > myLib( new QLibrary( library( authMethodKey ) ) );
     349                 :            : 
     350                 :          0 :   QgsDebugMsgLevel( "Library name is " + myLib->fileName(), 2 );
     351                 :            : 
     352                 :          0 :   if ( myLib->load() )
     353                 :          0 :     return myLib;
     354                 :            : 
     355                 :          0 :   QgsDebugMsg( "Cannot load library: " + myLib->errorString() );
     356                 :          0 :   return nullptr;
     357                 :          0 : }
     358                 :            : 
     359                 :          3 : QStringList QgsAuthMethodRegistry::authMethodList() const
     360                 :            : {
     361                 :          3 :   QStringList lst;
     362                 :          3 :   for ( AuthMethods::const_iterator it = mAuthMethods.begin(); it != mAuthMethods.end(); ++it )
     363                 :            :   {
     364                 :          0 :     lst.append( it->first );
     365                 :          0 :   }
     366                 :          3 :   return lst;
     367                 :          3 : }
     368                 :            : 
     369                 :          0 : const QgsAuthMethodMetadata *QgsAuthMethodRegistry::authMethodMetadata( const QString &authMethodKey ) const
     370                 :            : {
     371                 :          0 :   return findMetadata_( mAuthMethods, authMethodKey );
     372                 :            : }

Generated by: LCOV version 1.14