-
-
Notifications
You must be signed in to change notification settings - Fork 3k
/
test_authmanager_password_postgres.py
165 lines (138 loc) · 5.62 KB
/
test_authmanager_password_postgres.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# -*- coding: utf-8 -*-
"""
Tests for auth manager Password access to postgres.
This is an integration test for QGIS Desktop Auth Manager postgres provider that
checks if QGIS can use a stored auth manager auth configuration to access
a Password protected postgres.
From build dir, run: ctest -R PyQgsAuthManagerPasswordPostgresTest -V
It uses a docker container as postgres/postgis server with certificates from tests/testdata/auth_system/certs_keys_2048
Use docker-compose -f .ci/travis/linux/docker-compose.travis.yml up postgres to start the server.
TODO:
- Document how to restore the server data
- Document how to use docker inspect to find the IP of the docker postgres server and set a host alias (or some other smart idea to do the same)
.. 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 time
import signal
import stat
import subprocess
import tempfile
from shutil import rmtree
from contextlib import contextmanager
from utilities import unitTestDataPath
from qgis.core import (
QgsApplication,
QgsAuthManager,
QgsAuthMethodConfig,
QgsVectorLayer,
QgsDataSourceUri,
QgsWkbTypes,
)
from qgis.PyQt.QtNetwork import QSslCertificate
from qgis.testing import (
start_app,
unittest,
)
__author__ = 'Alessandro Pasotti'
__date__ = '25/10/2016'
__copyright__ = 'Copyright 2016, The QGIS Project'
qgis_app = start_app()
@contextmanager
def ScopedCertAuthority(username, password, sslrootcert_path=None):
"""
Sets up the certificate authority in the authentication manager
for the lifetime of this class and removes it when the class is deleted.
"""
authm = QgsApplication.authManager()
auth_config = QgsAuthMethodConfig("Basic")
auth_config.setConfig('username', username)
auth_config.setConfig('password', password)
auth_config.setName('test_password_auth_config')
if sslrootcert_path:
sslrootcert = QSslCertificate.fromPath(sslrootcert_path)
assert sslrootcert is not None
authm.storeCertAuthorities(sslrootcert)
authm.rebuildCaCertsCache()
authm.rebuildTrustedCaCertsCache()
authm.rebuildCertTrustCache()
assert (authm.storeAuthenticationConfig(auth_config)[0])
assert auth_config.isValid()
yield auth_config
if sslrootcert_path:
for cert in sslrootcert:
authm.removeCertAuthority(cert)
authm.rebuildCaCertsCache()
authm.rebuildTrustedCaCertsCache()
authm.rebuildCertTrustCache()
class TestAuthManager(unittest.TestCase):
@classmethod
def setUpClass(cls):
"""Run before all tests:
Creates an auth configuration"""
cls.username = 'docker'
cls.password = 'docker'
cls.dbname = 'qgis_test'
cls.hostname = 'postgres'
cls.port = '5432'
authm = QgsApplication.authManager()
assert (authm.setMasterPassword('masterpassword', True))
cls.certsdata_path = os.path.join(unitTestDataPath('auth_system'), 'certs_keys_2048')
cls.sslrootcert_path = os.path.join(cls.certsdata_path, 'qgis_ca.crt')
def setUp(self):
"""Run before each test."""
pass
def tearDown(self):
"""Run after each test."""
pass
@classmethod
def _getPostGISLayer(cls, type_name, layer_name=None, authcfg=None, sslmode=QgsDataSourceUri.SslVerifyFull):
"""
PG layer factory
"""
if layer_name is None:
layer_name = 'pg_' + type_name
uri = QgsDataSourceUri()
uri.setWkbType(QgsWkbTypes.Point)
uri.setConnection(cls.hostname, cls.port, cls.dbname, "", "", sslmode, authcfg)
uri.setKeyColumn('pk')
uri.setSrid('EPSG:4326')
uri.setDataSource('qgis_test', 'someData', "geom", "", "pk")
# Note: do not expand here!
layer = QgsVectorLayer(uri.uri(False), layer_name, 'postgres')
return layer
def testValidAuthAccess(self):
"""
Access the protected layer with valid credentials
"""
with ScopedCertAuthority(self.username, self.password, self.sslrootcert_path) as auth_config:
pg_layer = self._getPostGISLayer('testlayer_èé', authcfg=auth_config.id())
self.assertTrue(pg_layer.isValid())
def testInvalidAuthAccess(self):
"""
Access the protected layer with invalid credentials
"""
with ScopedCertAuthority(self.username, self.password, self.sslrootcert_path) as auth_config:
pg_layer = self._getPostGISLayer('testlayer_èé')
self.assertFalse(pg_layer.isValid())
def testSslRequireNoCaCheck(self):
"""
Access the protected layer with valid credentials and ssl require but without the required cert authority.
This should work.
"""
with ScopedCertAuthority(self.username, self.password) as auth_config:
pg_layer = self._getPostGISLayer('testlayer_èé', authcfg=auth_config.id(), sslmode=QgsDataSourceUri.SslRequire)
self.assertTrue(pg_layer.isValid())
def testSslVerifyFullCaCheck(self):
"""
Access the protected layer with valid credentials and ssl verify full but without the required cert authority.
This should not work.
"""
with ScopedCertAuthority(self.username, self.password) as auth_config:
pg_layer = self._getPostGISLayer('testlayer_èé', authcfg=auth_config.id())
self.assertFalse(pg_layer.isValid())
if __name__ == '__main__':
unittest.main()