Skip to content
Browse files

Merge pull request #39347 from elpaso/bugfix-gh39243-wms-auth-basic-d…


Fix WMS auth basic password encoding
  • Loading branch information
elpaso committed Oct 14, 2020
2 parents 02d7afa + c8f90c1 commit 2659c411a6ea6fb8a7cb4298f829ab115da1be19
@@ -638,7 +638,7 @@ void QgsDataSourceUri::setEncodedUri( const QByteArray &uri )
url.setQuery( QString::fromLatin1( uri ) );
const QUrlQuery query( url );

const auto constQueryItems = query.queryItems();
const auto constQueryItems = query.queryItems( QUrl::ComponentFormattingOption::FullyDecoded );
for ( const QPair<QString, QString> &item : constQueryItems )
if ( item.first == QLatin1String( "username" ) )
@@ -290,6 +290,15 @@ void TestQgsDataSourceUri::checkAuthParams()
QVERIFY( uri.param( QStringLiteral( "authcfg" ) ).isEmpty() );
QVERIFY( uri.authConfigId().isEmpty() );

// issue GH #39243
QgsDataSourceUri uri4;
uri4.setEncodedUri( QStringLiteral( "dpiMode=7&url=http://localhost:8000/ows/?MAP%3D/home/bug.qgs&username=username&password=pa%25%25word" ) );

QCOMPARE( uri4.param( QStringLiteral( "username" ) ), QStringLiteral( "username" ) );
QCOMPARE( uri4.username(), QStringLiteral( "username" ) );
QCOMPARE( uri4.param( QStringLiteral( "password" ) ), QStringLiteral( "pa%%word" ) );
QCOMPARE( uri4.password(), QStringLiteral( "pa%%word" ) );


@@ -28,6 +28,7 @@ ADD_PYTHON_TEST(PyQgsAttributeForm
@@ -0,0 +1,97 @@
# -*- coding: utf-8 -*-
Tests for Basic Auth
From build dir, run: ctest -R PyQgsAuthBasicMethod -V
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

import os
import tempfile
import base64

from qgis.core import QgsApplication, QgsAuthManager, QgsAuthMethodConfig, QgsNetworkAccessManager
from qgis.PyQt.QtCore import QFileInfo, QUrl
from qgis.testing import start_app, unittest
from qgis.PyQt.QtNetwork import QNetworkRequest

AUTHDBDIR = tempfile.mkdtemp()

__author__ = 'Alessandro Pasotti'
__date__ = '13/10/2020'
__copyright__ = 'Copyright 2020, The QGIS Project'

qgis_app = start_app()

class TestAuthManager(unittest.TestCase):

def setUpAuth(cls, username, password):
"""Run before all tests and set up authentication"""
assert (cls.authm.setMasterPassword('masterpassword', True))
# Client side
auth_config = QgsAuthMethodConfig("Basic")
auth_config.setConfig('username', username)
auth_config.setConfig('password', password)
assert (cls.authm.storeAuthenticationConfig(auth_config)[0])
assert auth_config.isValid()
return auth_config

def setUpClass(cls):
"""Run before all tests"""
cls.authm = QgsApplication.authManager()
assert not cls.authm.isDisabled(), cls.authm.disabledMessage()

cls.mpass = 'pass' # master password

db1 = QFileInfo(cls.authm.authenticationDatabasePath()
db2 = QFileInfo(AUTHDBDIR + '/qgis-auth.db').canonicalFilePath()
msg = 'Auth db temp path does not match db path of manager'
assert db1 == db2, msg

def tearDownClass(cls):
"""Run after all tests"""

def setUp(self):
"""Run before each test."""

def tearDown(self):
"""Run after each test."""

def _get_decoded_credentials(self, username, password):
"""Extracts and decode credentials from request Authorization header"""

ac = self.setUpAuth(username, password)
req = QNetworkRequest(QUrl('http://none'))
auth = bytes(req.rawHeader(b'Authorization'))[6:]
# Note that RFC7617 states clearly: User-ids containing colons cannot be encoded in user-pass strings
u, p = base64.decodestring(auth).split(b':')
return u.decode('utf8'), p.decode('utf8')

def testHeaderEncoding(self):
"""Test credentials encoding"""

for creds in (
('username', 'password'),
('username', r'pa%%word'),
self.assertEqual(self._get_decoded_credentials(*creds), creds)

if __name__ == '__main__':

0 comments on commit 2659c41

Please sign in to comment.
You can’t perform that action at this time.