3

I am trying to automate a couple of things when a QGIS plugin is activated:

  1. If Layer A is not in the TOC, add it. This requests username and password to access a PostGIS table using the inbuilt credentials dialog.
  2. If Layer A now exists in the TOC, access the same PostGIS table to run a query using the same user credentials.

Apparently as I'm not storing the password, I can't access it to use in connecting to the database (using psycopg). Is there any way around this? I want to avoid having the user type credentials twice, and also I want to avoid storing the credentials permanently. I have tried to reimplement the QgsCredentialDialog class but that adds so much complexity (e.g. when a connection error is thrown).

What other ways can I add a layer using a non-stored username and password, and access the credentials later to query the same database? The easiest option I can think of is to access the inbuilt credentials dialog request, but I'm not sure how to do that.

EDIT

My implementation of this was to create a function which I call at the point my layer has been added. It then sets my plugin class attributes username and password correctly which I can use in my db query.

def get_credentials(self, lyr):
    connInfo = QgsDataSourceURI(lyr.dataProvider().dataSourceUri()).connectionInfo()
    success, username, password = QgsCredentials.instance().get(connInfo, None, None)
    if success:
        # QgsCredentials.instance().put(connInfo, username, password)
        self.username = username
        self.password = password
5

QGIS caches the connection credentials inside QgsCredentials based on the connection info. So for a layer lyr do:

connInfo = QgsDataSourceURI( lyr.dataProvider().dataSourceUri() ).connectionInfo()
(success, user, passwd ) = QgsCredentials.instance().get( connInfo, None, None )
# Put the credentials back (for yourself and the provider), as QGIS removes it when you "get" it
if success:
    QgsCredentials.instance().put( connInfo, user, passwd )
  • 1
    I think your last line should be: QgsCredentials.instance().put( connInfo, user, passwd ) – Cao Minh Tu Nov 28 '13 at 9:36
  • Thanks, that has worked. Haven't implemented it yet but I just tried the code and can get the cached username and password. – James N Nov 28 '13 at 16:49
2

Instead of dealing inside QGIS with the credentials, you could keep them outside. You can use the file .pgpass for this

on linux you would create a file .pgpass in your home folder with the content:

Structure:

[database.hostname]:[port]:[database]:[username]:[password]

Example:

localhost:5432:*:user:pass
  • Thanks Matthias but I don't want to store the credentials anywhere, but I do want them persistent and accessible within a QGIS session. Unless I've missed something, this stores the credentials. – James N Nov 27 '13 at 10:17
  • That's true of course, it just helps not to save credentials inside the project file (and unintentionally passing it on). I will leave the answer for reference. – Matthias Kuhn Nov 27 '13 at 18:46
1

Database, connection parameters and user credential are stored in registry. It's possible to get them with QSettings class:

def getConnections(self):
    s = QSettings() 
    s.beginGroup("PostgreSQL/connections")
    currentConnections = s.childGroups()
    s.endGroup()
    return currentConnections

def setConnection(self,conn):
    s = QSettings()
    s.beginGroup("PostgreSQL/connections/"+conn)
    currentKeys = s.childKeys()
    print "keys: ", currentKeys
    PSQLDatabase=s.value("database", "" )
    PSQLHost=s.value("host", "" )
    PSQLUsername=s.value("username", "" )
    PSQLPassword=s.value("password", "" )
    PSQLPort=s.value("port", "" )
    PSQLService=s.value("service", "" )
    s.endGroup()
    self.db = QSqlDatabase.addDatabase("QPSQL")
    self.db.setHostName(PSQLHost)
    self.db.setDatabaseName(PSQLDatabase)
    self.db.setUserName(PSQLUsername)
    self.db.setPassword(PSQLPassword)
    ok = self.db.open()
    if not ok:
        error = "Database Error: %s" % db.lastError().text()
    else:
        error=""

getConnections returns a list of currently avalaible postgresql connections

setConnection(connection Qstring) opens the specified postgresql connection

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.