Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add detection of explicit vsi-prefix in URI-address #59586

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

notguiltyspark
Copy link
Contributor

Description

As of now, process of adding vector layer via URI-address with already-present prefix does not detect this prefix, which results in its prepending to the final string, which leads to the error in query.

This PR fixes it, scanning input uri-address beforehand and checking if it can detect prefixes from the usual protocols list.

vsicurl_prefix

@github-actions github-actions bot added this to the 3.42.0 milestone Nov 25, 2024
Copy link

github-actions bot commented Nov 25, 2024

🪟 Windows builds

Download Windows builds of this PR for testing.
Debug symbols for this build are available here.
(Built from commit 7686a6a)

🪟 Windows Qt6 builds

Download Windows Qt6 builds of this PR for testing.
(Built from commit 7686a6a)

{
uri.prepend( QStringLiteral( "http://" ) );
// If no protocol is provided in the URL, default to HTTP
if ( !uri.startsWith( "http://" ) && !uri.startsWith( "https://" ) && !uri.startsWith( "ftp://" ) )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if ( !uri.startsWith( "http://" ) && !uri.startsWith( "https://" ) && !uri.startsWith( "ftp://" ) )
if ( !uri.startsWith( QLatin1String("http://") ) && !uri.startsWith( QLatin1String("https://") ) && !uri.startsWith( QLatin1String("ftp://") ) )

@nyalldawson
Copy link
Collaborator

Can you add some tests for this too please?

@nyalldawson nyalldawson added the Requires Tests! Waiting on the submitter to add unit tests before eligible for merging label Dec 2, 2024
@notguiltyspark notguiltyspark force-pushed the fix_explicit_vsicurl_prefix branch from 7f7b6d5 to 297fb7b Compare December 11, 2024 10:17
@notguiltyspark
Copy link
Contributor Author

Added tests

@notguiltyspark notguiltyspark force-pushed the fix_explicit_vsicurl_prefix branch 3 times, most recently from edfa0ba to 3ca74e5 Compare December 11, 2024 10:52
Comment on lines 56 to 94
cleanupTempDir();

// make QGIS_AUTH_DB_DIR_PATH temp dir for qgis-auth.db and master password file
const QDir tmpDir = QDir::temp();
QVERIFY2( tmpDir.mkpath( mTempDir ), "Couldn't make temp directory" );
qputenv( "QGIS_AUTH_DB_DIR_PATH", mTempDir.toLatin1() );

// init app and auth manager
QgsApplication::init();
QgsApplication::initQgis();
QVERIFY2( !QgsApplication::authManager()->isDisabled(), "Authentication system is DISABLED" );

// verify QGIS_AUTH_DB_DIR_PATH (temp auth db path) worked
Q_NOWARN_DEPRECATED_PUSH
const QString db1( QFileInfo( QgsApplication::authManager()->authenticationDatabasePath() ).canonicalFilePath() );
Q_NOWARN_DEPRECATED_POP
const QString db2( QFileInfo( mTempDir + "/qgis-auth.db" ).canonicalFilePath() );
QCOMPARE( db1, db2 );

// verify master pass can be set manually
// (this also creates a fresh password hash in the new temp database)
QVERIFY2( QgsApplication::authManager()->setMasterPassword( mPass, true ), "Master password could not be set" );
QVERIFY2( QgsApplication::authManager()->masterPasswordIsSet(), "Auth master password not set from passed string" );

// create QGIS_AUTH_PASSWORD_FILE file
const QString passfilepath = mTempDir + "/passfile";
QFile passfile( passfilepath );
if ( passfile.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate ) )
{
QTextStream fout( &passfile );
fout << QString( mPass ) << "\r\n";
passfile.close();
qputenv( "QGIS_AUTH_PASSWORD_FILE", passfilepath.toLatin1() );
}
// qDebug( "QGIS_AUTH_PASSWORD_FILE=%s", qgetenv( "QGIS_AUTH_PASSWORD_FILE" ).constData() );

// re-init app and auth manager
QgsApplication::quit();
// QTest::qSleep( 3000 );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of this is required, there's no tests which are actually taking advantage of the auth db

Suggested change
cleanupTempDir();
// make QGIS_AUTH_DB_DIR_PATH temp dir for qgis-auth.db and master password file
const QDir tmpDir = QDir::temp();
QVERIFY2( tmpDir.mkpath( mTempDir ), "Couldn't make temp directory" );
qputenv( "QGIS_AUTH_DB_DIR_PATH", mTempDir.toLatin1() );
// init app and auth manager
QgsApplication::init();
QgsApplication::initQgis();
QVERIFY2( !QgsApplication::authManager()->isDisabled(), "Authentication system is DISABLED" );
// verify QGIS_AUTH_DB_DIR_PATH (temp auth db path) worked
Q_NOWARN_DEPRECATED_PUSH
const QString db1( QFileInfo( QgsApplication::authManager()->authenticationDatabasePath() ).canonicalFilePath() );
Q_NOWARN_DEPRECATED_POP
const QString db2( QFileInfo( mTempDir + "/qgis-auth.db" ).canonicalFilePath() );
QCOMPARE( db1, db2 );
// verify master pass can be set manually
// (this also creates a fresh password hash in the new temp database)
QVERIFY2( QgsApplication::authManager()->setMasterPassword( mPass, true ), "Master password could not be set" );
QVERIFY2( QgsApplication::authManager()->masterPasswordIsSet(), "Auth master password not set from passed string" );
// create QGIS_AUTH_PASSWORD_FILE file
const QString passfilepath = mTempDir + "/passfile";
QFile passfile( passfilepath );
if ( passfile.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate ) )
{
QTextStream fout( &passfile );
fout << QString( mPass ) << "\r\n";
passfile.close();
qputenv( "QGIS_AUTH_PASSWORD_FILE", passfilepath.toLatin1() );
}
// qDebug( "QGIS_AUTH_PASSWORD_FILE=%s", qgetenv( "QGIS_AUTH_PASSWORD_FILE" ).constData() );
// re-init app and auth manager
QgsApplication::quit();
// QTest::qSleep( 3000 );

Copy link
Contributor Author

@notguiltyspark notguiltyspark Dec 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of this is required, there's no tests which are actually taking advantage of the auth db

If we set flag expandAuthConfig and set some config-string to configId we enter this block in QgsGdalGuiUtils::createProtocolURI:


// Update URI with authentication information
if ( !configId.isEmpty() )
{
  if ( expandAuthConfig )
  { 
    QStringList connectionItems;
    connectionItems << uri;
    if ( QgsApplication::authManager()->updateDataSourceUriItems( connectionItems, configId, QStringLiteral( "ogr" ) ) )
    {
      uri = connectionItems.join( QString() );
    }
  }
  else
  {
    uri += QStringLiteral( " authcfg='%1'" ).arg( configId );
  }
}

So there seems to be a possibility or combination of circumstances in which we need authentication manager?

If so - these tests are prerequisites/preparations to initializing and using it, if i understand correctly, since it is not self-contained (i.e. couchDB test was failing until authentication manager was initialized correctly with authentication method and master setting of masterpassword due to incorrect auth-db creation and reading).

If not - i will remove them according to your suggestions, just making sure that i understand correctly

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm referring to the fact that none of the tests introduced here actually require the auth configuration. Theres '// Test with configId and expandAuthConfig = false', but that isn't requiring the auth.

Then there's QgsGdalGuiUtils::createProtocolURI( QLatin1String( "CouchDB" ), QLatin1String( "mydb" ), QLatin1String( "ab34567" ), QString(), QString(), true );, but that's not actually doing any replacement either.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, i updated tests according to suggestions

Comment on lines 97 to 102
QVERIFY2( !QgsApplication::authManager()->isDisabled(), "Authentication system is DISABLED" );

// verify QGIS_AUTH_PASSWORD_FILE worked, when compared against hash in db
QVERIFY2( QgsApplication::authManager()->masterPasswordIsSet(), "Auth master password not set from QGIS_AUTH_PASSWORD_FILE" );

// all tests should now have a valid qgis-auth.db and stored/set master password
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
QVERIFY2( !QgsApplication::authManager()->isDisabled(), "Authentication system is DISABLED" );
// verify QGIS_AUTH_PASSWORD_FILE worked, when compared against hash in db
QVERIFY2( QgsApplication::authManager()->masterPasswordIsSet(), "Auth master password not set from QGIS_AUTH_PASSWORD_FILE" );
// all tests should now have a valid qgis-auth.db and stored/set master password

Comment on lines 107 to 112
QList<QgsAuthMethodConfig> lAuthConfigs = registerAuthConfigs();
for ( auto &authcfg : lAuthConfigs )
{
QgsApplication::instance()->authManager()->storeAuthenticationConfig( authcfg, true );
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
QList<QgsAuthMethodConfig> lAuthConfigs = registerAuthConfigs();
for ( auto &authcfg : lAuthConfigs )
{
QgsApplication::instance()->authManager()->storeAuthenticationConfig( authcfg, true );
}

Comment on lines 294 to 331
cleanupTempDir();
}

void TestQgsGdalGuiUtils::cleanupTempDir()
{
QString mTempDir = QDir::tempPath() + "/auth";

QDir tmpDir = QDir( mTempDir );
if ( tmpDir.exists() )
{
for ( const QString &tf : tmpDir.entryList( QDir::NoDotAndDotDot | QDir::Files ) )
{
QVERIFY2( tmpDir.remove( mTempDir + '/' + tf ), qPrintable( "Could not remove " + mTempDir + '/' + tf ) );
}
QVERIFY2( tmpDir.rmdir( mTempDir ), qPrintable( "Could not remove directory " + mTempDir ) );
}
}

QList<QgsAuthMethodConfig> TestQgsGdalGuiUtils::registerAuthConfigs()
{
QList<QgsAuthMethodConfig> configs;

// Basic
QgsAuthMethodConfig b_config;
b_config.setName( QStringLiteral( "Basic" ) );
b_config.setMethod( QStringLiteral( "Basic" ) );
b_config.setUri( QStringLiteral( "http://example.com" ) );
b_config.setConfig( QStringLiteral( "username" ), QStringLiteral( "username" ) );
b_config.setConfig( QStringLiteral( "password" ), QStringLiteral( "password" ) );
b_config.setConfig( QStringLiteral( "realm" ), QStringLiteral( "Realm" ) );
b_config.setId( QStringLiteral( "ab34567" ) );
if ( !b_config.isValid() )
{
return configs;
}

configs << b_config;
return configs;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
cleanupTempDir();
}
void TestQgsGdalGuiUtils::cleanupTempDir()
{
QString mTempDir = QDir::tempPath() + "/auth";
QDir tmpDir = QDir( mTempDir );
if ( tmpDir.exists() )
{
for ( const QString &tf : tmpDir.entryList( QDir::NoDotAndDotDot | QDir::Files ) )
{
QVERIFY2( tmpDir.remove( mTempDir + '/' + tf ), qPrintable( "Could not remove " + mTempDir + '/' + tf ) );
}
QVERIFY2( tmpDir.rmdir( mTempDir ), qPrintable( "Could not remove directory " + mTempDir ) );
}
}
QList<QgsAuthMethodConfig> TestQgsGdalGuiUtils::registerAuthConfigs()
{
QList<QgsAuthMethodConfig> configs;
// Basic
QgsAuthMethodConfig b_config;
b_config.setName( QStringLiteral( "Basic" ) );
b_config.setMethod( QStringLiteral( "Basic" ) );
b_config.setUri( QStringLiteral( "http://example.com" ) );
b_config.setConfig( QStringLiteral( "username" ), QStringLiteral( "username" ) );
b_config.setConfig( QStringLiteral( "password" ), QStringLiteral( "password" ) );
b_config.setConfig( QStringLiteral( "realm" ), QStringLiteral( "Realm" ) );
b_config.setId( QStringLiteral( "ab34567" ) );
if ( !b_config.isValid() )
{
return configs;
}
configs << b_config;
return configs;

Copy link

The QGIS project highly values your contribution and would love to see this work merged! Unfortunately this PR has not had any activity in the last 14 days and is being automatically marked as "stale". If you think this pull request should be merged, please check

  • that all unit tests are passing

  • that all comments by reviewers have been addressed

  • that there is enough information for reviewers, in particular

    • link to any issues which this pull request fixes

    • add a description of workflows which this pull request fixes

    • add screenshots if applicable

  • that you have written unit tests where possible
    In case you should have any uncertainty, please leave a comment and we will be happy to help you proceed with this pull request.
    If there is no further activity on this pull request, it will be closed in a week.

@github-actions github-actions bot added the stale Uh oh! Seems this work is abandoned, and the PR is about to close. label Dec 30, 2024
@notguiltyspark notguiltyspark force-pushed the fix_explicit_vsicurl_prefix branch from 3ca74e5 to 5ac18f0 Compare January 1, 2025 21:29
@github-actions github-actions bot removed the stale Uh oh! Seems this work is abandoned, and the PR is about to close. label Jan 1, 2025
Copy link

The QGIS project highly values your contribution and would love to see this work merged! Unfortunately this PR has not had any activity in the last 14 days and is being automatically marked as "stale". If you think this pull request should be merged, please check

  • that all unit tests are passing

  • that all comments by reviewers have been addressed

  • that there is enough information for reviewers, in particular

    • link to any issues which this pull request fixes

    • add a description of workflows which this pull request fixes

    • add screenshots if applicable

  • that you have written unit tests where possible
    In case you should have any uncertainty, please leave a comment and we will be happy to help you proceed with this pull request.
    If there is no further activity on this pull request, it will be closed in a week.

@github-actions github-actions bot added the stale Uh oh! Seems this work is abandoned, and the PR is about to close. label Jan 16, 2025
@notguiltyspark notguiltyspark force-pushed the fix_explicit_vsicurl_prefix branch from 5ac18f0 to 5da878b Compare January 19, 2025 19:30
@github-actions github-actions bot removed the stale Uh oh! Seems this work is abandoned, and the PR is about to close. label Jan 19, 2025
@notguiltyspark notguiltyspark force-pushed the fix_explicit_vsicurl_prefix branch from 5da878b to f4c58c3 Compare January 19, 2025 19:40
@notguiltyspark notguiltyspark force-pushed the fix_explicit_vsicurl_prefix branch from f4c58c3 to 7686a6a Compare January 19, 2025 21:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Requires Tests! Waiting on the submitter to add unit tests before eligible for merging
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants