Skip to content

Commit

Permalink
[GRASS] fixed test if current user is not owner of source
Browse files Browse the repository at this point in the history
  • Loading branch information
blazek committed Sep 21, 2015
1 parent 992bacc commit fae0654
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 46 deletions.
109 changes: 73 additions & 36 deletions src/providers/grass/qgsgrass.cpp
Expand Up @@ -52,8 +52,9 @@


extern "C" extern "C"
{ {
#ifndef _MSC_VER #ifndef Q_OS_WIN
#include <unistd.h> #include <unistd.h>
#include <sys/types.h>
#endif #endif
#include <grass/version.h> #include <grass/version.h>
#include <grass/gprojects.h> #include <grass/gprojects.h>
Expand Down Expand Up @@ -707,6 +708,8 @@ QString QgsGrass::mTmp;


QMutex QgsGrass::sMutex; QMutex QgsGrass::sMutex;


bool QgsGrass::mMute = false;

int QgsGrass::error_routine( char *msg, int fatal ) int QgsGrass::error_routine( char *msg, int fatal )
{ {
return error_routine(( const char* ) msg, fatal ); return error_routine(( const char* ) msg, fatal );
Expand Down Expand Up @@ -760,6 +763,22 @@ QString QgsGrass::errorMessage( void )
return error_message; return error_message;
} }


bool QgsGrass::isOwner( const QString& gisdbase, const QString& location, const QString& mapset )
{
QString mapsetPath = gisdbase + "/" + location + "/" + mapset;

// G_mapset_permissions() (check_owner() in GRASS 7) on Windows consider all mapsets to be owned by user
// There is more complex G_owner() but that is not used in G_gisinit() (7.1.svn).
// On Windows and on systems where files do not have owners ownerId() returns ((uint) -2).
#ifndef Q_OS_WIN
bool owner = QFileInfo( mapsetPath ).ownerId() == getuid();
#else
bool owner = true;
#endif
QgsDebugMsg( QString( "%1 : owner = %2" ).arg( mapsetPath ).arg( owner ) );
return owner;
}

QString QgsGrass::openMapset( const QString& gisdbase, QString QgsGrass::openMapset( const QString& gisdbase,
const QString& location, const QString& mapset ) const QString& location, const QString& mapset )
{ {
Expand Down Expand Up @@ -1726,8 +1745,7 @@ bool QgsGrass::mapRegion( QgsGrassObject::Type type, QString gisdbase,
map.toUtf8().data(), map.toUtf8().data(),
mapset.toUtf8().data() ) != NULL ) mapset.toUtf8().data() ) != NULL )
{ {
QMessageBox::warning( 0, QObject::tr( "Warning" ), warning( tr( "Cannot read region" ) );
QObject::tr( "Cannot read region" ) );
return false; return false;
} }
#else #else
Expand Down Expand Up @@ -1768,15 +1786,34 @@ QProcess *QgsGrass::startModule( const QString& gisdbase, const QString& locati
throw QgsGrass::Exception( QObject::tr( "Cannot open GISRC file" ) ); throw QgsGrass::Exception( QObject::tr( "Cannot open GISRC file" ) );
} }


QString error = tr( "Cannot start module" ) + "\n" + tr( "command: %1 %2" ).arg( module ).arg( arguments.join( " " ) );

// Modules must be run in a mapset owned by user, because each module calls G_gisinit()
// which checks if G_mapset() is owned by user.
QString ownedMapset = mapset;
if ( ownedMapset.isEmpty() )
{
Q_FOREACH ( QString ms, mapsets( gisdbase, location ) )
{
if ( isOwner( gisdbase, location, ms ) )
{
ownedMapset = ms;
}
}
}
if ( ownedMapset.isEmpty() )
{
throw QgsGrass::Exception( error + "\n" + tr( "Cannot find a mapset owned by current user" ) );
}

QTextStream out( &gisrcFile ); QTextStream out( &gisrcFile );
out << "GISDBASE: " << gisdbase << "\n"; out << "GISDBASE: " << gisdbase << "\n";
out << "LOCATION_NAME: " << location << "\n"; out << "LOCATION_NAME: " << location << "\n";
//out << "MAPSET: PERMANENT\n"; //out << "MAPSET: PERMANENT\n";
out << "MAPSET: " << mapset << "\n"; out << "MAPSET: " << ownedMapset << "\n";
out.flush(); out.flush();
QgsDebugMsg( gisrcFile.fileName() ); QgsDebugMsg( gisrcFile.fileName() );
gisrcFile.close(); gisrcFile.close();

QStringList environment = QProcess::systemEnvironment(); QStringList environment = QProcess::systemEnvironment();
environment.append( "GISRC=" + gisrcFile.fileName() ); environment.append( "GISRC=" + gisrcFile.fileName() );


Expand All @@ -1787,9 +1824,7 @@ QProcess *QgsGrass::startModule( const QString& gisdbase, const QString& locati
process->start( module, arguments ); process->start( module, arguments );
if ( !process->waitForStarted() ) if ( !process->waitForStarted() )
{ {
throw QgsGrass::Exception( QObject::tr( "Cannot start module" ) + "\n" throw QgsGrass::Exception( error );
+ QObject::tr( "command: %1 %2" )
.arg( module ).arg( arguments.join( " " ) ) );
} }
return process; return process;
} }
Expand All @@ -1801,7 +1836,7 @@ QByteArray QgsGrass::runModule( const QString& gisdbase, const QString& locatio
QgsDebugMsg( QString( "gisdbase = %1 location = %2 timeOut = %3" ).arg( gisdbase ).arg( location ).arg( timeOut ) ); QgsDebugMsg( QString( "gisdbase = %1 location = %2 timeOut = %3" ).arg( gisdbase ).arg( location ).arg( timeOut ) );


QTemporaryFile gisrcFile; QTemporaryFile gisrcFile;
QProcess *process = QgsGrass::startModule( gisdbase, location, mapset, moduleName, arguments, gisrcFile, qgisModule ); QProcess *process = startModule( gisdbase, location, mapset, moduleName, arguments, gisrcFile, qgisModule );


if ( !process->waitForFinished( timeOut ) if ( !process->waitForFinished( timeOut )
|| ( process->exitCode() != 0 && process->exitCode() != 255 ) ) || ( process->exitCode() != 0 && process->exitCode() != 255 ) )
Expand Down Expand Up @@ -1864,7 +1899,9 @@ QString QgsGrass::getInfo( const QString& info, const QString& gisdbase,
arguments.append( QString( "cols=%1" ).arg( sampleCols ) ); arguments.append( QString( "cols=%1" ).arg( sampleCols ) );
} }


QByteArray data = QgsGrass::runModule( gisdbase, location, mapset, cmd, arguments, timeOut ); //QByteArray data = runModule( gisdbase, location, mapset, cmd, arguments, timeOut );
// Run module with empty mapset so that it tries to find a mapset owned by user
QByteArray data = runModule( gisdbase, location, "", cmd, arguments, timeOut );
QgsDebugMsg( data ); QgsDebugMsg( data );
return QString( data ); return QString( data );
} }
Expand All @@ -1876,7 +1913,7 @@ QgsCoordinateReferenceSystem QgsGrass::crs( const QString& gisdbase, const QStri
QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem(); QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem();
try try
{ {
QString wkt = QgsGrass::getInfo( "proj", gisdbase, location ); QString wkt = getInfo( "proj", gisdbase, location );
QgsDebugMsg( "wkt: " + wkt ); QgsDebugMsg( "wkt: " + wkt );
crs.createFromWkt( wkt ); crs.createFromWkt( wkt );
QgsDebugMsg( "crs.toWkt: " + crs.toWkt() ); QgsDebugMsg( "crs.toWkt: " + crs.toWkt() );
Expand All @@ -1885,8 +1922,7 @@ QgsCoordinateReferenceSystem QgsGrass::crs( const QString& gisdbase, const QStri
{ {
if ( interactive ) if ( interactive )
{ {
QMessageBox::warning( 0, QObject::tr( "Warning" ), warning( tr( "Cannot get projection " ) + "\n" + e.what() );
QObject::tr( "Cannot get projection " ) + "\n" + e.what() );
} }
} }


Expand Down Expand Up @@ -1940,7 +1976,7 @@ QgsRectangle QgsGrass::extent( const QString& gisdbase, const QString& location,


try try
{ {
QString str = QgsGrass::getInfo( "window", gisdbase, location, mapset, map, type ); QString str = getInfo( "window", gisdbase, location, mapset, map, type );
QStringList list = str.split( "," ); QStringList list = str.split( "," );
if ( list.size() != 4 ) if ( list.size() != 4 )
{ {
Expand All @@ -1952,8 +1988,7 @@ QgsRectangle QgsGrass::extent( const QString& gisdbase, const QString& location,
{ {
if ( interactive ) if ( interactive )
{ {
QMessageBox::warning( 0, QObject::tr( "Warning" ), warning( tr( "Cannot get raster extent" ) + "\n" + e.what() );
QObject::tr( "Cannot get raster extent" ) + "\n" + e.what() );
} }
} }
return QgsRectangle( 0, 0, 0, 0 ); return QgsRectangle( 0, 0, 0, 0 );
Expand All @@ -1968,7 +2003,7 @@ void QgsGrass::size( const QString& gisdbase, const QString& location,
*rows = 0; *rows = 0;
try try
{ {
QString str = QgsGrass::getInfo( "size", gisdbase, location, mapset, map, QgsGrassObject::Raster ); QString str = getInfo( "size", gisdbase, location, mapset, map, QgsGrassObject::Raster );
QStringList list = str.split( "," ); QStringList list = str.split( "," );
if ( list.size() != 2 ) if ( list.size() != 2 )
{ {
Expand All @@ -1979,8 +2014,7 @@ void QgsGrass::size( const QString& gisdbase, const QString& location,
} }
catch ( QgsGrass::Exception &e ) catch ( QgsGrass::Exception &e )
{ {
QMessageBox::warning( 0, QObject::tr( "Warning" ), warning( tr( "Cannot get raster extent" ) + "\n" + e.what() );
QObject::tr( "Cannot get raster extent" ) + "\n" + e.what() );
} }


QgsDebugMsg( QString( "raster size = %1 %2" ).arg( *cols ).arg( *rows ) ); QgsDebugMsg( QString( "raster size = %1 %2" ).arg( *cols ).arg( *rows ) );
Expand All @@ -1999,7 +2033,7 @@ QHash<QString, QString> QgsGrass::info( const QString& gisdbase, const QString&


try try
{ {
QString str = QgsGrass::getInfo( info, gisdbase, location, mapset, map, type, 0, 0, extent, sampleRows, sampleCols, timeOut ); QString str = getInfo( info, gisdbase, location, mapset, map, type, 0, 0, extent, sampleRows, sampleCols, timeOut );
QgsDebugMsg( str ); QgsDebugMsg( str );
QStringList list = str.split( "\n" ); QStringList list = str.split( "\n" );
for ( int i = 0; i < list.size(); i++ ) for ( int i = 0; i < list.size(); i++ )
Expand All @@ -2018,8 +2052,7 @@ QHash<QString, QString> QgsGrass::info( const QString& gisdbase, const QString&
{ {
if ( interactive ) if ( interactive )
{ {
QMessageBox::warning( 0, QObject::tr( "Warning" ), warning( tr( "Cannot get map info" ) + "\n" + e.what() );
QObject::tr( "Cannot get map info" ) + "\n" + e.what() );
} }
} }
return inf; return inf;
Expand All @@ -2032,7 +2065,7 @@ QList<QgsGrass::Color> QgsGrass::colors( QString gisdbase, QString location, QSt


try try
{ {
QString str = QgsGrass::getInfo( "colors", gisdbase, location, mapset, map, QgsGrassObject::Raster ); QString str = getInfo( "colors", gisdbase, location, mapset, map, QgsGrassObject::Raster );
QgsDebugMsg( str ); QgsDebugMsg( str );
QStringList list = str.split( "\n" ); QStringList list = str.split( "\n" );
for ( int i = 0; i < list.size(); i++ ) for ( int i = 0; i < list.size(); i++ )
Expand All @@ -2049,8 +2082,7 @@ QList<QgsGrass::Color> QgsGrass::colors( QString gisdbase, QString location, QSt
} }
catch ( QgsGrass::Exception &e ) catch ( QgsGrass::Exception &e )
{ {
QMessageBox::warning( 0, QObject::tr( "Warning" ), warning( tr( "Cannot get colors" ) + "\n" + e.what() );
QObject::tr( "Cannot get colors" ) + "\n" + e.what() );
} }
return ct; return ct;
} }
Expand All @@ -2063,7 +2095,7 @@ QMap<QString, QString> QgsGrass::query( QString gisdbase, QString location, QStr
// TODO: multiple values (more rows) // TODO: multiple values (more rows)
try try
{ {
QString str = QgsGrass::getInfo( "query", gisdbase, location, mapset, map, type, x, y ); QString str = getInfo( "query", gisdbase, location, mapset, map, type, x, y );
QStringList list = str.trimmed().split( ":" ); QStringList list = str.trimmed().split( ":" );
if ( list.size() == 2 ) if ( list.size() == 2 )
{ {
Expand All @@ -2072,8 +2104,7 @@ QMap<QString, QString> QgsGrass::query( QString gisdbase, QString location, QStr
} }
catch ( QgsGrass::Exception &e ) catch ( QgsGrass::Exception &e )
{ {
QMessageBox::warning( 0, QObject::tr( "Warning" ), warning( tr( "Cannot query raster " ) + "\n" + e.what() );
QObject::tr( "Cannot query raster " ) + "\n" + e.what() );
} }
return result; return result;
} }
Expand All @@ -2088,7 +2119,7 @@ void QgsGrass::renameObject( const QgsGrassObject & object, const QString& newNa


int timeout = -1; // What timeout to use? It can take long time on network or database int timeout = -1; // What timeout to use? It can take long time on network or database
// throws QgsGrass::Exception // throws QgsGrass::Exception
QgsGrass::runModule( object.gisdbase(), object.location(), object.mapset(), cmd, arguments, timeout, false ); runModule( object.gisdbase(), object.location(), object.mapset(), cmd, arguments, timeout, false );
} }


void QgsGrass::copyObject( const QgsGrassObject & srcObject, const QgsGrassObject & destObject ) void QgsGrass::copyObject( const QgsGrassObject & srcObject, const QgsGrassObject & destObject )
Expand All @@ -2109,7 +2140,7 @@ void QgsGrass::copyObject( const QgsGrassObject & srcObject, const QgsGrassObjec
int timeout = -1; // What timeout to use? It can take long time on network or database int timeout = -1; // What timeout to use? It can take long time on network or database
// throws QgsGrass::Exception // throws QgsGrass::Exception
// TODO: g.copy does not seem to return error code if fails (6.4.3RC1) // TODO: g.copy does not seem to return error code if fails (6.4.3RC1)
QgsGrass::runModule( destObject.gisdbase(), destObject.location(), destObject.mapset(), cmd, arguments, timeout, false ); runModule( destObject.gisdbase(), destObject.location(), destObject.mapset(), cmd, arguments, timeout, false );
} }


bool QgsGrass::deleteObject( const QgsGrassObject & object ) bool QgsGrass::deleteObject( const QgsGrassObject & object )
Expand Down Expand Up @@ -2138,13 +2169,11 @@ bool QgsGrass::deleteObject( const QgsGrassObject & object )


try try
{ {
QgsGrass::runModule( object.gisdbase(), object.location(), object.mapset(), cmd, arguments, 5000, false ); runModule( object.gisdbase(), object.location(), object.mapset(), cmd, arguments, 5000, false );
} }
catch ( QgsGrass::Exception &e ) catch ( QgsGrass::Exception &e )
{ {
QMessageBox::warning( 0, QObject::tr( "Warning" ), warning( tr( "Cannot delete" ) + " " + object.elementName() + " " + object.name() + ": " + e.what() );
QObject::tr( "Cannot delete" ) + " " + object.elementName()
+ " " + object.name() + ": " + e.what() );
return false; return false;
} }
return true; return true;
Expand Down Expand Up @@ -2523,12 +2552,20 @@ void QgsGrass::setModulesDebug( bool debug )


void QgsGrass::warning( const QString &message ) void QgsGrass::warning( const QString &message )
{ {
QMessageBox::warning( 0, QObject::tr( "Warning" ), message ); if ( !mMute )
{
QMessageBox::warning( 0, QObject::tr( "Warning" ), message );
}
else
{
error_message = message;
QgsDebugMsg( message );
}
} }


void QgsGrass::warning( QgsGrass::Exception &e ) void QgsGrass::warning( QgsGrass::Exception &e )
{ {
QMessageBox::warning( 0, QObject::tr( "Warning" ), e.what() ); warning( e.what() );
} }


struct Map_info *QgsGrass::vectNewMapStruct() struct Map_info *QgsGrass::vectNewMapStruct()
Expand Down
16 changes: 14 additions & 2 deletions src/providers/grass/qgsgrass.h
Expand Up @@ -222,6 +222,9 @@ class GRASS_LIB_EXPORT QgsGrass : public QObject
//! Get last error message //! Get last error message
static QString errorMessage( void ); static QString errorMessage( void );


/** Test is current user is owner of mapset */
static bool isOwner( const QString& gisdbase, const QString& location, const QString& mapset );

/** Open existing GRASS mapset. /** Open existing GRASS mapset.
* Emits signal mapsetChanged(). * Emits signal mapsetChanged().
* \return Empty string or error message * \return Empty string or error message
Expand Down Expand Up @@ -355,8 +358,11 @@ class GRASS_LIB_EXPORT QgsGrass : public QObject
// ! Get current gisrc path // ! Get current gisrc path
static QString gisrcFilePath(); static QString gisrcFilePath();


// ! Start a GRASS module in any gisdbase/location/mapset /** Start a GRASS module in any gisdbase/location/mapset.
// @param qgisModule append GRASS major version (for modules built in qgis) * @param mapset if empty a first mapset owned by user will be used, if no mapset is owned
* by user, exception is thrown.
* @param qgisModule append GRASS major version (for modules built in qgis)
* @throws QgsGrass::Exception */
static QProcess *startModule( const QString& gisdbase, const QString& location, static QProcess *startModule( const QString& gisdbase, const QString& location,
const QString& mapset, const QString& moduleName, const QString& mapset, const QString& moduleName,
const QStringList& arguments, QTemporaryFile &gisrcFile, const QStringList& arguments, QTemporaryFile &gisrcFile,
Expand Down Expand Up @@ -528,6 +534,10 @@ class GRASS_LIB_EXPORT QgsGrass : public QObject
/** Show warning dialog with exception message */ /** Show warning dialog with exception message */
static void warning( QgsGrass::Exception &e ); static void warning( QgsGrass::Exception &e );


/** Set mute mode, if set, warning() does not open dialog but prints only
* debug message and sets the error which returns errorMessage() */
static void setMute() { mMute = true; }

/** Allocate struct Map_info. Call to this function may result in G_fatal_error /** Allocate struct Map_info. Call to this function may result in G_fatal_error
* and must be surrounded by G_TRY/G_CATCH. */ * and must be surrounded by G_TRY/G_CATCH. */
static struct Map_info * vectNewMapStruct(); static struct Map_info * vectNewMapStruct();
Expand Down Expand Up @@ -588,6 +598,8 @@ class GRASS_LIB_EXPORT QgsGrass : public QObject
static QString mTmp; static QString mTmp;
// Mutex for common locking when calling GRASS functions which are mostly non thread safe // Mutex for common locking when calling GRASS functions which are mostly non thread safe
static QMutex sMutex; static QMutex sMutex;
// Mute mode, do not show warning dialogs.
static bool mMute;
}; };


#endif // QGSGRASS_H #endif // QGSGRASS_H

0 comments on commit fae0654

Please sign in to comment.