Skip to content

Commit 5f3ca88

Browse files
committed
Merge pull request #2674 from boundlessgeo/postgis-pki-pr
[FEATURE] Postgres provider PKI authentication (plus fixes #13841)
2 parents 275eb94 + 2a12f01 commit 5f3ca88

26 files changed

+479
-80
lines changed

python/core/auth/qgsauthcertutils.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class QgsAuthCertUtils
8282
const QString &bundlepass = QString(),
8383
bool reencrypt = true );
8484

85+
static QString pemTextToTempFile( const QString &name, const QByteArray &pemtext );
8586

8687
static QString getCaSourceName( QgsAuthCertUtils::CaCertSource source , bool single = false );
8788

python/plugins/db_manager/db_plugins/connector.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ def __del__(self):
3838
self.connection = None
3939

4040
def uri(self):
41-
return QgsDataSourceURI(self._uri.uri())
41+
return QgsDataSourceURI(self._uri.uri(False))
4242

4343
def publicUri(self):
44-
publicUri = QgsDataSourceURI.removePassword(self._uri.uri())
44+
publicUri = QgsDataSourceURI.removePassword(self._uri.uri(False))
4545
return QgsDataSourceURI(publicUri)
4646

4747
def hasSpatialSupport(self):

python/plugins/db_manager/db_plugins/oracle/connector.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def __init__(self, uri, connName):
125125
self._checkGeometryColumnsTable()
126126

127127
def _connectionInfo(self):
128-
return unicode(self._uri.connectionInfo())
128+
return unicode(self._uri.connectionInfo(True))
129129

130130
def _checkSpatial(self):
131131
"""Check whether Oracle Spatial is present in catalog."""

python/plugins/db_manager/db_plugins/oracle/plugin.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ def connect(self, parent=None):
129129
max_attempts = 3
130130
for i in range(max_attempts):
131131
(ok, username, password) = QgsCredentials.instance().get(
132-
uri.connectionInfo(), username, password, err)
132+
uri.connectionInfo(False), username, password, err)
133133

134134
if not ok:
135135
return False
@@ -145,7 +145,7 @@ def connect(self, parent=None):
145145
continue
146146

147147
QgsCredentials.instance().put(
148-
uri.connectionInfo(), username, password)
148+
uri.connectionInfo(False), username, password)
149149

150150
return True
151151

@@ -207,7 +207,7 @@ def toSqlLayer(self, sql, geomCol, uniqueCol,
207207
if avoidSelectById:
208208
uri.disableSelectAtId(True)
209209
provider = self.dbplugin().providerName()
210-
vlayer = QgsVectorLayer(uri.uri(), layerName, provider)
210+
vlayer = QgsVectorLayer(uri.uri(False), layerName, provider)
211211

212212
# handling undetermined geometry type
213213
if not vlayer.isValid():
@@ -217,7 +217,7 @@ def toSqlLayer(self, sql, geomCol, uniqueCol,
217217
uri.setWkbType(wkbType)
218218
if srid:
219219
uri.setSrid(unicode(srid))
220-
vlayer = QgsVectorLayer(uri.uri(), layerName, provider)
220+
vlayer = QgsVectorLayer(uri.uri(False), layerName, provider)
221221

222222
return vlayer
223223

python/plugins/db_manager/db_plugins/plugin.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,8 @@ def toSqlLayer(self, sql, geomCol, uniqueCol, layerName="QueryLayer", layerType=
279279
uri.disableSelectAtId(True)
280280
provider = self.dbplugin().providerName()
281281
if layerType == QgsMapLayer.RasterLayer:
282-
return QgsRasterLayer(uri.uri(), layerName, provider)
283-
return QgsVectorLayer(uri.uri(), layerName, provider)
282+
return QgsRasterLayer(uri.uri(False), layerName, provider)
283+
return QgsVectorLayer(uri.uri(False), layerName, provider)
284284

285285
def registerAllActions(self, mainWindow):
286286
self.registerDatabaseActions(mainWindow)
@@ -668,13 +668,13 @@ def uri(self):
668668

669669
def mimeUri(self):
670670
layerType = "raster" if self.type == Table.RasterType else "vector"
671-
return u"%s:%s:%s:%s" % (layerType, self.database().dbplugin().providerName(), self.name, self.uri().uri())
671+
return u"%s:%s:%s:%s" % (layerType, self.database().dbplugin().providerName(), self.name, self.uri().uri(False))
672672

673673
def toMapLayer(self):
674674
from qgis.core import QgsVectorLayer, QgsRasterLayer
675675

676676
provider = self.database().dbplugin().providerName()
677-
uri = self.uri().uri()
677+
uri = self.uri().uri(False)
678678
if self.type == Table.RasterType:
679679
return QgsRasterLayer(uri, self.name, provider)
680680
return QgsVectorLayer(uri, self.name, provider)

python/plugins/db_manager/db_plugins/postgis/connector.py

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"""
2424

2525
from PyQt4.QtCore import QRegExp
26-
from qgis.core import QgsCredentials
26+
from qgis.core import QgsCredentials, QgsDataSourceURI
2727

2828
from ..connector import DBConnector
2929
from ..plugin import ConnectionError, DbError, Table
@@ -51,12 +51,13 @@ def __init__(self, uri):
5151
username = uri.username() or os.environ.get('PGUSER') or os.environ.get('USER')
5252
password = uri.password() or os.environ.get('PGPASSWORD')
5353

54+
expandedConnInfo = self._connectionInfo()
5455
try:
55-
self.connection = psycopg2.connect(self._connectionInfo().encode('utf-8'))
56+
self.connection = psycopg2.connect(expandedConnInfo.encode('utf-8'))
5657
except self.connection_error_types() as e:
5758
err = unicode(e)
5859
uri = self.uri()
59-
conninfo = uri.connectionInfo()
60+
conninfo = uri.connectionInfo(False)
6061

6162
for i in range(3):
6263
(ok, username, password) = QgsCredentials.instance().get(conninfo, username, password, err)
@@ -69,14 +70,51 @@ def __init__(self, uri):
6970
if password:
7071
uri.setPassword(password)
7172

73+
newExpandedConnInfo = uri.connectionInfo(True)
7274
try:
73-
self.connection = psycopg2.connect(uri.connectionInfo().encode('utf-8'))
75+
self.connection = psycopg2.connect(newExpandedConnInfo.encode('utf-8'))
7476
QgsCredentials.instance().put(conninfo, username, password)
7577
except self.connection_error_types() as e:
7678
if i == 2:
7779
raise ConnectionError(e)
7880

7981
err = unicode(e)
82+
finally:
83+
# remove certs (if any) of the expanded connectionInfo
84+
expandedUri = QgsDataSourceURI(newExpandedConnInfo)
85+
86+
sslCertFile = expandedUri.param("sslcert")
87+
if sslCertFile:
88+
sslCertFile = sslCertFile.replace("'", "")
89+
os.remove(sslCertFile)
90+
91+
sslKeyFile = expandedUri.param("sslkey")
92+
if sslKeyFile:
93+
sslKeyFile = sslKeyFile.replace("'", "")
94+
os.remove(sslKeyFile)
95+
96+
sslCAFile = expandedUri.param("sslrootcert")
97+
if sslCAFile:
98+
sslCAFile = sslCAFile.replace("'", "")
99+
os.remove(sslCAFile)
100+
finally:
101+
# remove certs (if any) of the expanded connectionInfo
102+
expandedUri = QgsDataSourceURI(expandedConnInfo)
103+
104+
sslCertFile = expandedUri.param("sslcert")
105+
if sslCertFile:
106+
sslCertFile = sslCertFile.replace("'", "")
107+
os.remove(sslCertFile)
108+
109+
sslKeyFile = expandedUri.param("sslkey")
110+
if sslKeyFile:
111+
sslKeyFile = sslKeyFile.replace("'", "")
112+
os.remove(sslKeyFile)
113+
114+
sslCAFile = expandedUri.param("sslrootcert")
115+
if sslCAFile:
116+
sslCAFile = sslCAFile.replace("'", "")
117+
os.remove(sslCAFile)
80118

81119
self.connection.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
82120

@@ -90,7 +128,7 @@ def __init__(self, uri):
90128
self._checkRasterColumnsTable()
91129

92130
def _connectionInfo(self):
93-
return unicode(self.uri().connectionInfo())
131+
return unicode(self.uri().connectionInfo(True))
94132

95133
def _checkSpatial(self):
96134
""" check whether postgis_version is present in catalog """

python/plugins/db_manager/db_plugins/postgis/plugin.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,18 @@ def connect(self, parent=None):
7979

8080
uri = QgsDataSourceURI()
8181

82-
settingsList = ["service", "host", "port", "database", "username", "password"]
83-
service, host, port, database, username, password = map(lambda x: settings.value(x, "", type=str), settingsList)
82+
settingsList = ["service", "host", "port", "database", "username", "password", "authcfg"]
83+
service, host, port, database, username, password, authcfg = map(lambda x: settings.value(x, "", type=str), settingsList)
8484

8585
useEstimatedMetadata = settings.value("estimatedMetadata", False, type=bool)
8686
sslmode = settings.value("sslmode", QgsDataSourceURI.SSLprefer, type=int)
8787

8888
settings.endGroup()
8989

9090
if service:
91-
uri.setConnection(service, database, username, password, sslmode)
91+
uri.setConnection(service, database, username, password, sslmode, authcfg)
9292
else:
93-
uri.setConnection(host, port, database, username, password, sslmode)
93+
uri.setConnection(host, port, database, username, password, sslmode, authcfg)
9494

9595
uri.setUseEstimatedMetadata(useEstimatedMetadata)
9696

@@ -292,7 +292,7 @@ def toMapLayer(self):
292292
if not rl.isValid():
293293
err = rl.error().summary()
294294
uri = QgsDataSourceURI(self.database().uri())
295-
conninfo = uri.connectionInfo()
295+
conninfo = uri.connectionInfo(False)
296296
username = uri.username()
297297
password = uri.password()
298298

python/plugins/db_manager/db_plugins/postgis/plugins/qgis_topoview/__init__.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def run(item, action, mainwindow):
113113
uri.setDataSource(toponame, 'face', 'mbr', '', 'face_id')
114114
uri.setSrid(toposrid)
115115
uri.setWkbType(QGis.WKBPolygon)
116-
layer = QgsVectorLayer(uri.uri(), u'%s.face_mbr' % toponame, provider)
116+
layer = QgsVectorLayer(uri.uri(False), u'%s.face_mbr' % toponame, provider)
117117
layer.loadNamedStyle(os.path.join(template_dir, 'face_mbr.qml'))
118118
registry.addMapLayers([layer])
119119
legend.moveLayer(layer, group)
@@ -127,7 +127,7 @@ def run(item, action, mainwindow):
127127
uri.setDataSource('', u'(%s\n)' % sql, 'geom', '', 'face_id')
128128
uri.setSrid(toposrid)
129129
uri.setWkbType(QGis.WKBPolygon)
130-
layer = QgsVectorLayer(uri.uri(), u'%s.face' % toponame, provider)
130+
layer = QgsVectorLayer(uri.uri(False), u'%s.face' % toponame, provider)
131131
layer.setExtent(face_extent)
132132
layer.loadNamedStyle(os.path.join(template_dir, 'face.qml'))
133133
registry.addMapLayers([layer])
@@ -141,7 +141,7 @@ def run(item, action, mainwindow):
141141
uri.setDataSource('', u'(%s)' % sql, 'geom', '', 'face_id')
142142
uri.setSrid(toposrid)
143143
uri.setWkbType(QGis.WKBPoint)
144-
layer = QgsVectorLayer(uri.uri(), u'%s.face_seed' % toponame, provider)
144+
layer = QgsVectorLayer(uri.uri(False), u'%s.face_seed' % toponame, provider)
145145
layer.setExtent(face_extent)
146146
layer.loadNamedStyle(os.path.join(template_dir, 'face_seed.qml'))
147147
registry.addMapLayers([layer])
@@ -158,7 +158,7 @@ def run(item, action, mainwindow):
158158
uri.setDataSource(toponame, 'node', 'geom', '', 'node_id')
159159
uri.setSrid(toposrid)
160160
uri.setWkbType(QGis.WKBPoint)
161-
layer = QgsVectorLayer(uri.uri(), u'%s.node' % toponame, provider)
161+
layer = QgsVectorLayer(uri.uri(False), u'%s.node' % toponame, provider)
162162
layer.loadNamedStyle(os.path.join(template_dir, 'node.qml'))
163163
registry.addMapLayers([layer])
164164
legend.moveLayer(layer, group)
@@ -170,7 +170,7 @@ def run(item, action, mainwindow):
170170
uri.setDataSource(toponame, 'node', 'geom', '', 'node_id')
171171
uri.setSrid(toposrid)
172172
uri.setWkbType(QGis.WKBPoint)
173-
layer = QgsVectorLayer(uri.uri(), u'%s.node_id' % toponame, provider)
173+
layer = QgsVectorLayer(uri.uri(False), u'%s.node_id' % toponame, provider)
174174
layer.setExtent(node_extent)
175175
layer.loadNamedStyle(os.path.join(template_dir, 'node_label.qml'))
176176
registry.addMapLayers([layer])
@@ -185,7 +185,7 @@ def run(item, action, mainwindow):
185185
uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
186186
uri.setSrid(toposrid)
187187
uri.setWkbType(QGis.WKBLineString)
188-
layer = QgsVectorLayer(uri.uri(), u'%s.edge' % toponame, provider)
188+
layer = QgsVectorLayer(uri.uri(False), u'%s.edge' % toponame, provider)
189189
registry.addMapLayers([layer])
190190
legend.moveLayer(layer, group)
191191
legend.setLayerVisible(layer, False)
@@ -196,7 +196,7 @@ def run(item, action, mainwindow):
196196
uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
197197
uri.setSrid(toposrid)
198198
uri.setWkbType(QGis.WKBLineString)
199-
layer = QgsVectorLayer(uri.uri(), u'%s.directed_edge' % toponame, provider)
199+
layer = QgsVectorLayer(uri.uri(False), u'%s.directed_edge' % toponame, provider)
200200
layer.setExtent(edge_extent)
201201
layer.loadNamedStyle(os.path.join(template_dir, 'edge.qml'))
202202
registry.addMapLayers([layer])
@@ -208,7 +208,7 @@ def run(item, action, mainwindow):
208208
uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
209209
uri.setSrid(toposrid)
210210
uri.setWkbType(QGis.WKBLineString)
211-
layer = QgsVectorLayer(uri.uri(), u'%s.edge_id' % toponame, provider)
211+
layer = QgsVectorLayer(uri.uri(False), u'%s.edge_id' % toponame, provider)
212212
layer.setExtent(edge_extent)
213213
layer.loadNamedStyle(os.path.join(template_dir, 'edge_label.qml'))
214214
registry.addMapLayers([layer])
@@ -220,7 +220,7 @@ def run(item, action, mainwindow):
220220
uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
221221
uri.setSrid(toposrid)
222222
uri.setWkbType(QGis.WKBLineString)
223-
layer = QgsVectorLayer(uri.uri(), u'%s.face_left' % toponame, provider)
223+
layer = QgsVectorLayer(uri.uri(False), u'%s.face_left' % toponame, provider)
224224
layer.setExtent(edge_extent)
225225
layer.loadNamedStyle(os.path.join(template_dir, 'face_left.qml'))
226226
registry.addMapLayers([layer])
@@ -232,7 +232,7 @@ def run(item, action, mainwindow):
232232
uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
233233
uri.setSrid(toposrid)
234234
uri.setWkbType(QGis.WKBLineString)
235-
layer = QgsVectorLayer(uri.uri(), u'%s.face_right' % toponame, provider)
235+
layer = QgsVectorLayer(uri.uri(False), u'%s.face_right' % toponame, provider)
236236
layer.setExtent(edge_extent)
237237
layer.loadNamedStyle(os.path.join(template_dir, 'face_right.qml'))
238238
registry.addMapLayers([layer])
@@ -244,7 +244,7 @@ def run(item, action, mainwindow):
244244
uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
245245
uri.setSrid(toposrid)
246246
uri.setWkbType(QGis.WKBLineString)
247-
layer = QgsVectorLayer(uri.uri(), u'%s.next_left' % toponame, provider)
247+
layer = QgsVectorLayer(uri.uri(False), u'%s.next_left' % toponame, provider)
248248
layer.setExtent(edge_extent)
249249
layer.loadNamedStyle(os.path.join(template_dir, 'next_left.qml'))
250250
registry.addMapLayers([layer])
@@ -256,7 +256,7 @@ def run(item, action, mainwindow):
256256
uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
257257
uri.setSrid(toposrid)
258258
uri.setWkbType(QGis.WKBLineString)
259-
layer = QgsVectorLayer(uri.uri(), u'%s.next_right' % toponame, provider)
259+
layer = QgsVectorLayer(uri.uri(False), u'%s.next_right' % toponame, provider)
260260
layer.setExtent(edge_extent)
261261
layer.loadNamedStyle(os.path.join(template_dir, 'next_right.qml'))
262262
registry.addMapLayers([layer])

python/plugins/db_manager/layer_preview.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def _loadTablePreview(self, table, limit=False):
105105
uri.setDataSource("", u"(SELECT * FROM %s LIMIT 1000)" % table.quotedName(), table.geomColumn, "",
106106
uniqueField.name)
107107
provider = table.database().dbplugin().providerName()
108-
vl = QgsVectorLayer(uri.uri(), table.name, provider)
108+
vl = QgsVectorLayer(uri.uri(False), table.name, provider)
109109
else:
110110
vl = table.toMapLayer()
111111

0 commit comments

Comments
 (0)