Skip to content

Commit

Permalink
Merge pull request #2674 from boundlessgeo/postgis-pki-pr
Browse files Browse the repository at this point in the history
[FEATURE] Postgres provider PKI authentication (plus fixes #13841)
  • Loading branch information
dakcarto committed Jan 15, 2016
2 parents 275eb94 + 2a12f01 commit 5f3ca88
Show file tree
Hide file tree
Showing 26 changed files with 479 additions and 80 deletions.
1 change: 1 addition & 0 deletions python/core/auth/qgsauthcertutils.sip
Expand Up @@ -82,6 +82,7 @@ class QgsAuthCertUtils
const QString &bundlepass = QString(),
bool reencrypt = true );

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

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

Expand Down
4 changes: 2 additions & 2 deletions python/plugins/db_manager/db_plugins/connector.py
Expand Up @@ -38,10 +38,10 @@ def __del__(self):
self.connection = None

def uri(self):
return QgsDataSourceURI(self._uri.uri())
return QgsDataSourceURI(self._uri.uri(False))

def publicUri(self):
publicUri = QgsDataSourceURI.removePassword(self._uri.uri())
publicUri = QgsDataSourceURI.removePassword(self._uri.uri(False))
return QgsDataSourceURI(publicUri)

def hasSpatialSupport(self):
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/db_manager/db_plugins/oracle/connector.py
Expand Up @@ -125,7 +125,7 @@ def __init__(self, uri, connName):
self._checkGeometryColumnsTable()

def _connectionInfo(self):
return unicode(self._uri.connectionInfo())
return unicode(self._uri.connectionInfo(True))

def _checkSpatial(self):
"""Check whether Oracle Spatial is present in catalog."""
Expand Down
8 changes: 4 additions & 4 deletions python/plugins/db_manager/db_plugins/oracle/plugin.py
Expand Up @@ -129,7 +129,7 @@ def connect(self, parent=None):
max_attempts = 3
for i in range(max_attempts):
(ok, username, password) = QgsCredentials.instance().get(
uri.connectionInfo(), username, password, err)
uri.connectionInfo(False), username, password, err)

if not ok:
return False
Expand All @@ -145,7 +145,7 @@ def connect(self, parent=None):
continue

QgsCredentials.instance().put(
uri.connectionInfo(), username, password)
uri.connectionInfo(False), username, password)

return True

Expand Down Expand Up @@ -207,7 +207,7 @@ def toSqlLayer(self, sql, geomCol, uniqueCol,
if avoidSelectById:
uri.disableSelectAtId(True)
provider = self.dbplugin().providerName()
vlayer = QgsVectorLayer(uri.uri(), layerName, provider)
vlayer = QgsVectorLayer(uri.uri(False), layerName, provider)

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

return vlayer

Expand Down
8 changes: 4 additions & 4 deletions python/plugins/db_manager/db_plugins/plugin.py
Expand Up @@ -279,8 +279,8 @@ def toSqlLayer(self, sql, geomCol, uniqueCol, layerName="QueryLayer", layerType=
uri.disableSelectAtId(True)
provider = self.dbplugin().providerName()
if layerType == QgsMapLayer.RasterLayer:
return QgsRasterLayer(uri.uri(), layerName, provider)
return QgsVectorLayer(uri.uri(), layerName, provider)
return QgsRasterLayer(uri.uri(False), layerName, provider)
return QgsVectorLayer(uri.uri(False), layerName, provider)

def registerAllActions(self, mainWindow):
self.registerDatabaseActions(mainWindow)
Expand Down Expand Up @@ -668,13 +668,13 @@ def uri(self):

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

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

provider = self.database().dbplugin().providerName()
uri = self.uri().uri()
uri = self.uri().uri(False)
if self.type == Table.RasterType:
return QgsRasterLayer(uri, self.name, provider)
return QgsVectorLayer(uri, self.name, provider)
Expand Down
48 changes: 43 additions & 5 deletions python/plugins/db_manager/db_plugins/postgis/connector.py
Expand Up @@ -23,7 +23,7 @@
"""

from PyQt4.QtCore import QRegExp
from qgis.core import QgsCredentials
from qgis.core import QgsCredentials, QgsDataSourceURI

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

expandedConnInfo = self._connectionInfo()
try:
self.connection = psycopg2.connect(self._connectionInfo().encode('utf-8'))
self.connection = psycopg2.connect(expandedConnInfo.encode('utf-8'))
except self.connection_error_types() as e:
err = unicode(e)
uri = self.uri()
conninfo = uri.connectionInfo()
conninfo = uri.connectionInfo(False)

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

newExpandedConnInfo = uri.connectionInfo(True)
try:
self.connection = psycopg2.connect(uri.connectionInfo().encode('utf-8'))
self.connection = psycopg2.connect(newExpandedConnInfo.encode('utf-8'))
QgsCredentials.instance().put(conninfo, username, password)
except self.connection_error_types() as e:
if i == 2:
raise ConnectionError(e)

err = unicode(e)
finally:
# remove certs (if any) of the expanded connectionInfo
expandedUri = QgsDataSourceURI(newExpandedConnInfo)

sslCertFile = expandedUri.param("sslcert")
if sslCertFile:
sslCertFile = sslCertFile.replace("'", "")
os.remove(sslCertFile)

sslKeyFile = expandedUri.param("sslkey")
if sslKeyFile:
sslKeyFile = sslKeyFile.replace("'", "")
os.remove(sslKeyFile)

sslCAFile = expandedUri.param("sslrootcert")
if sslCAFile:
sslCAFile = sslCAFile.replace("'", "")
os.remove(sslCAFile)
finally:
# remove certs (if any) of the expanded connectionInfo
expandedUri = QgsDataSourceURI(expandedConnInfo)

sslCertFile = expandedUri.param("sslcert")
if sslCertFile:
sslCertFile = sslCertFile.replace("'", "")
os.remove(sslCertFile)

sslKeyFile = expandedUri.param("sslkey")
if sslKeyFile:
sslKeyFile = sslKeyFile.replace("'", "")
os.remove(sslKeyFile)

sslCAFile = expandedUri.param("sslrootcert")
if sslCAFile:
sslCAFile = sslCAFile.replace("'", "")
os.remove(sslCAFile)

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

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

def _connectionInfo(self):
return unicode(self.uri().connectionInfo())
return unicode(self.uri().connectionInfo(True))

def _checkSpatial(self):
""" check whether postgis_version is present in catalog """
Expand Down
10 changes: 5 additions & 5 deletions python/plugins/db_manager/db_plugins/postgis/plugin.py
Expand Up @@ -79,18 +79,18 @@ def connect(self, parent=None):

uri = QgsDataSourceURI()

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

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

settings.endGroup()

if service:
uri.setConnection(service, database, username, password, sslmode)
uri.setConnection(service, database, username, password, sslmode, authcfg)
else:
uri.setConnection(host, port, database, username, password, sslmode)
uri.setConnection(host, port, database, username, password, sslmode, authcfg)

uri.setUseEstimatedMetadata(useEstimatedMetadata)

Expand Down Expand Up @@ -292,7 +292,7 @@ def toMapLayer(self):
if not rl.isValid():
err = rl.error().summary()
uri = QgsDataSourceURI(self.database().uri())
conninfo = uri.connectionInfo()
conninfo = uri.connectionInfo(False)
username = uri.username()
password = uri.password()

Expand Down
Expand Up @@ -113,7 +113,7 @@ def run(item, action, mainwindow):
uri.setDataSource(toponame, 'face', 'mbr', '', 'face_id')
uri.setSrid(toposrid)
uri.setWkbType(QGis.WKBPolygon)
layer = QgsVectorLayer(uri.uri(), u'%s.face_mbr' % toponame, provider)
layer = QgsVectorLayer(uri.uri(False), u'%s.face_mbr' % toponame, provider)
layer.loadNamedStyle(os.path.join(template_dir, 'face_mbr.qml'))
registry.addMapLayers([layer])
legend.moveLayer(layer, group)
Expand All @@ -127,7 +127,7 @@ def run(item, action, mainwindow):
uri.setDataSource('', u'(%s\n)' % sql, 'geom', '', 'face_id')
uri.setSrid(toposrid)
uri.setWkbType(QGis.WKBPolygon)
layer = QgsVectorLayer(uri.uri(), u'%s.face' % toponame, provider)
layer = QgsVectorLayer(uri.uri(False), u'%s.face' % toponame, provider)
layer.setExtent(face_extent)
layer.loadNamedStyle(os.path.join(template_dir, 'face.qml'))
registry.addMapLayers([layer])
Expand All @@ -141,7 +141,7 @@ def run(item, action, mainwindow):
uri.setDataSource('', u'(%s)' % sql, 'geom', '', 'face_id')
uri.setSrid(toposrid)
uri.setWkbType(QGis.WKBPoint)
layer = QgsVectorLayer(uri.uri(), u'%s.face_seed' % toponame, provider)
layer = QgsVectorLayer(uri.uri(False), u'%s.face_seed' % toponame, provider)
layer.setExtent(face_extent)
layer.loadNamedStyle(os.path.join(template_dir, 'face_seed.qml'))
registry.addMapLayers([layer])
Expand All @@ -158,7 +158,7 @@ def run(item, action, mainwindow):
uri.setDataSource(toponame, 'node', 'geom', '', 'node_id')
uri.setSrid(toposrid)
uri.setWkbType(QGis.WKBPoint)
layer = QgsVectorLayer(uri.uri(), u'%s.node' % toponame, provider)
layer = QgsVectorLayer(uri.uri(False), u'%s.node' % toponame, provider)
layer.loadNamedStyle(os.path.join(template_dir, 'node.qml'))
registry.addMapLayers([layer])
legend.moveLayer(layer, group)
Expand All @@ -170,7 +170,7 @@ def run(item, action, mainwindow):
uri.setDataSource(toponame, 'node', 'geom', '', 'node_id')
uri.setSrid(toposrid)
uri.setWkbType(QGis.WKBPoint)
layer = QgsVectorLayer(uri.uri(), u'%s.node_id' % toponame, provider)
layer = QgsVectorLayer(uri.uri(False), u'%s.node_id' % toponame, provider)
layer.setExtent(node_extent)
layer.loadNamedStyle(os.path.join(template_dir, 'node_label.qml'))
registry.addMapLayers([layer])
Expand All @@ -185,7 +185,7 @@ def run(item, action, mainwindow):
uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
uri.setSrid(toposrid)
uri.setWkbType(QGis.WKBLineString)
layer = QgsVectorLayer(uri.uri(), u'%s.edge' % toponame, provider)
layer = QgsVectorLayer(uri.uri(False), u'%s.edge' % toponame, provider)
registry.addMapLayers([layer])
legend.moveLayer(layer, group)
legend.setLayerVisible(layer, False)
Expand All @@ -196,7 +196,7 @@ def run(item, action, mainwindow):
uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
uri.setSrid(toposrid)
uri.setWkbType(QGis.WKBLineString)
layer = QgsVectorLayer(uri.uri(), u'%s.directed_edge' % toponame, provider)
layer = QgsVectorLayer(uri.uri(False), u'%s.directed_edge' % toponame, provider)
layer.setExtent(edge_extent)
layer.loadNamedStyle(os.path.join(template_dir, 'edge.qml'))
registry.addMapLayers([layer])
Expand All @@ -208,7 +208,7 @@ def run(item, action, mainwindow):
uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
uri.setSrid(toposrid)
uri.setWkbType(QGis.WKBLineString)
layer = QgsVectorLayer(uri.uri(), u'%s.edge_id' % toponame, provider)
layer = QgsVectorLayer(uri.uri(False), u'%s.edge_id' % toponame, provider)
layer.setExtent(edge_extent)
layer.loadNamedStyle(os.path.join(template_dir, 'edge_label.qml'))
registry.addMapLayers([layer])
Expand All @@ -220,7 +220,7 @@ def run(item, action, mainwindow):
uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
uri.setSrid(toposrid)
uri.setWkbType(QGis.WKBLineString)
layer = QgsVectorLayer(uri.uri(), u'%s.face_left' % toponame, provider)
layer = QgsVectorLayer(uri.uri(False), u'%s.face_left' % toponame, provider)
layer.setExtent(edge_extent)
layer.loadNamedStyle(os.path.join(template_dir, 'face_left.qml'))
registry.addMapLayers([layer])
Expand All @@ -232,7 +232,7 @@ def run(item, action, mainwindow):
uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
uri.setSrid(toposrid)
uri.setWkbType(QGis.WKBLineString)
layer = QgsVectorLayer(uri.uri(), u'%s.face_right' % toponame, provider)
layer = QgsVectorLayer(uri.uri(False), u'%s.face_right' % toponame, provider)
layer.setExtent(edge_extent)
layer.loadNamedStyle(os.path.join(template_dir, 'face_right.qml'))
registry.addMapLayers([layer])
Expand All @@ -244,7 +244,7 @@ def run(item, action, mainwindow):
uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
uri.setSrid(toposrid)
uri.setWkbType(QGis.WKBLineString)
layer = QgsVectorLayer(uri.uri(), u'%s.next_left' % toponame, provider)
layer = QgsVectorLayer(uri.uri(False), u'%s.next_left' % toponame, provider)
layer.setExtent(edge_extent)
layer.loadNamedStyle(os.path.join(template_dir, 'next_left.qml'))
registry.addMapLayers([layer])
Expand All @@ -256,7 +256,7 @@ def run(item, action, mainwindow):
uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
uri.setSrid(toposrid)
uri.setWkbType(QGis.WKBLineString)
layer = QgsVectorLayer(uri.uri(), u'%s.next_right' % toponame, provider)
layer = QgsVectorLayer(uri.uri(False), u'%s.next_right' % toponame, provider)
layer.setExtent(edge_extent)
layer.loadNamedStyle(os.path.join(template_dir, 'next_right.qml'))
registry.addMapLayers([layer])
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/db_manager/layer_preview.py
Expand Up @@ -105,7 +105,7 @@ def _loadTablePreview(self, table, limit=False):
uri.setDataSource("", u"(SELECT * FROM %s LIMIT 1000)" % table.quotedName(), table.geomColumn, "",
uniqueField.name)
provider = table.database().dbplugin().providerName()
vl = QgsVectorLayer(uri.uri(), table.name, provider)
vl = QgsVectorLayer(uri.uri(False), table.name, provider)
else:
vl = table.toMapLayer()

Expand Down

0 comments on commit 5f3ca88

Please sign in to comment.