Skip to content
Permalink
Browse files

Fix WMS auth basic password encoding

and add an unrelated test, since I wrote it.

Fixes #39243
  • Loading branch information
elpaso committed Oct 13, 2020
1 parent 8d3e028 commit 40997ff804467f083c8a4afba021beae9f81ecc7
@@ -42,8 +42,9 @@ bool QgsWmsSettings::parseUri( const QString &uriString )
uri.setEncodedUri( uriString );

// Setup authentication
mAuth.mUserName = uri.username();
mAuth.mPassword = uri.password();
QUrlQuery query{ uriString };
mAuth.mUserName = query.queryItemValue( QStringLiteral( "username" ), QUrl::ComponentFormattingOption::FullyDecoded );
mAuth.mPassword = query.queryItemValue( QStringLiteral( "password" ), QUrl::ComponentFormattingOption::FullyDecoded );

if ( !uri.authConfigId().isEmpty() )
{
@@ -28,6 +28,7 @@ ADD_PYTHON_TEST(PyQgsAttributeForm test_qgsattributeform.py)
ADD_PYTHON_TEST(PyQgsAttributeTableConfig test_qgsattributetableconfig.py)
ADD_PYTHON_TEST(PyQgsAttributeTableModel test_qgsattributetablemodel.py)
ADD_PYTHON_TEST(PyQgsAuthenticationSystem test_qgsauthsystem.py)
ADD_PYTHON_TEST(PyQgsAuthBasicMethod test_qgsauthbasicmethod.py)
ADD_PYTHON_TEST(PyQgsBearingUtils test_qgsbearingutils.py)
ADD_PYTHON_TEST(PyQgsBinaryWidget test_qgsbinarywidget.py)
ADD_PYTHON_TEST(PyQgsBlendModes test_qgsblendmodes.py)
@@ -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()
os.environ['QGIS_AUTH_DB_DIR_PATH'] = AUTHDBDIR


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

qgis_app = start_app()


class TestAuthManager(unittest.TestCase):

@classmethod
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)
auth_config.setName('test_basic_auth_config')
assert (cls.authm.storeAuthenticationConfig(auth_config)[0])
assert auth_config.isValid()
return auth_config

@classmethod
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()
).canonicalFilePath()
db2 = QFileInfo(AUTHDBDIR + '/qgis-auth.db').canonicalFilePath()
msg = 'Auth db temp path does not match db path of manager'
assert db1 == db2, msg

@classmethod
def tearDownClass(cls):
"""Run after all tests"""
pass

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

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

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'))
self.authm.updateNetworkRequest(req, ac.id())
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__':
unittest.main()

0 comments on commit 40997ff

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