File 03-osc_gnome_keyring.patch of Package osc

diff --git a/osc/conf.py b/osc/conf.py
index f505171..a56a67b 100644
--- a/osc/conf.py
+++ b/osc/conf.py
@@ -74,6 +74,34 @@ GNOME_KEYRING = False
 try:
     import keyring
     GENERIC_KEYRING = True
+    if 'DISPLAY' in os.environ:
+     # Looks like we have desktop session
+     # Continue to the the normal desktop unlock procedures.
+        pass
+    if 'DBUS_SESSION_BUS_ADDERESS' in os.environ:
+     # Make DBUS has launched
+        pass
+    else:
+        raise SystemExit ("""
+The DBUS_SESSION_BUS_ADDRESS environment variable is not set which
+probably means that DBUS is not running.
+
+If you have just installed osc then you need to logout
+and login again, or source /etc/profile.
+""")
+        
+    if 'GNOME_KEYRING_CONTROL' in os.environ:
+     # Make GNOME_KEYRING is started
+        pass
+    else:
+        raise SystemExit ("""
+The GNOME_KEYRING_CONTROL environment variable is not set which
+probably means GNOME KEYRING DAEMON is not running.
+
+If you have just installed osc then you need to logout
+and login again.
+""")
+
 except:
     try:
         import gobject
@@ -83,6 +111,31 @@ except:
     except:
         pass
 
+def _unlock_gnome_keyring(prompt):
+   import secretstorage
+   import subprocess
+
+   # Make the .local directory.  Otherwise initial keyring creation
+   # will fail.
+   if not os.path.exists(os.path.expanduser('~/.local')):
+       os.makedirs(os.path.expanduser('~/.local'), mode=0o700)
+
+   process = subprocess.Popen(['/usr/bin/gnome-keyring-daemon', '--start',
+                              '--components=secrets'],
+                     stdout = subprocess.PIPE,
+                     stderr = subprocess.PIPE)
+   password = getpass.getpass(prompt=prompt)
+   password = (password + '\n').encode('UTF-8')
+   process = subprocess.Popen(['/usr/bin/gnome-keyring-daemon', '--unlock',
+                               '--replace', '--components=secrets'],
+                     stdin  =  subprocess.PIPE,
+                     stdout =  subprocess.PIPE,
+                     stderr =  subprocess.PIPE)
+   stdoutdata,stderrdata = process.communicate(input=password)
+   dbus = secretstorage.dbus_init()
+   collection = secretstorage.get_default_collection(dbus)
+   if collection.is_locked():
+      raise SystemExit('Unable to unlock keyring.')
 
 def _get_processors():
     """
@@ -204,7 +257,7 @@ boolean_opts = ['debug', 'do_package_tracking', 'http_debug', 'post_mortem', 'tr
     'status_mtime_heuristic']
 integer_opts = ['build-jobs']
 
-api_host_options = ['user', 'pass', 'passx', 'aliases', 'http_headers', 'realname', 'email', 'sslcertck', 'cafile', 'capath', 'trusted_prj', 'credentials_mgr_class']
+api_host_options = ['user', 'pass', 'passx', 'aliases', 'http_headers', 'realname', 'email', 'sslcertck', 'cafile', 'capath', 'trusted_prj']
 
 new_conf_template = """
 [general]
@@ -789,7 +842,17 @@ def write_initial_config(conffile, entries, custom_template='', creds_mgr_descri
         creds_mgr = creds_mgr_descriptor.create(cp)
     else:
         creds_mgr = _get_credentials_manager(config['apiurl'], cp)
-    creds_mgr.set_password(config['apiurl'], config['user'], config['pass'])
+    try:
+       creds_mgr.set_password(config['apiurl'], config['user'], config['pass'])
+    except keyring.errors.InitError:
+       print ('Creating a new keyring.')
+       _unlock_gnome_keyring('New keyring password: ')
+       creds_mgr.set_password(config['apiurl'], config['user'], config['pass'])
+    except keyring.errors.KeyringLocked:
+       print ('Unlock keyring.')
+       _unlock_gnome_keyring('Keyring password: ')
+       creds_mgr.set_password(config['apiurl'], config['user'], config['pass'])
+
     write_config(conffile, cp)
 
 
@@ -906,8 +969,12 @@ def get_config(override_conffile=None,
     # override values which we were called with
     # This needs to be done before processing API sections as it might be already used there
     if override_no_keyring:
-        config['use_keyring'] = False
+        print ("Disabling the use of a keyring is not allowed in this environment.")
+        print ("A keyring will still be used.")
+        config['use_keyring'] = True
     if override_no_gnome_keyring:
+        print ("Disabling the use of a gnome keyring is not allowed in this environment.")
+        print ("A keyring will still be used.")
         config['gnome_keyring'] = False
 
     aliases = {}
@@ -922,7 +989,17 @@ def get_config(override_conffile=None,
         user = _extract_user_compat(cp, url, creds_mgr)
         if user is None:
             raise oscerr.ConfigMissingCredentialsError('No user found in section %s' % url, conffile, url)
-        password = creds_mgr.get_password(url, user)
+        try:
+           password = creds_mgr.get_password(url, user)
+        except keyring.errors.InitError:
+           print ('Creating a new keyring.')
+           _unlock_gnome_keyring('New keyring password: ')
+           password = creds_mgr.get_password(url, user)
+        except keyring.errors.KeyringLocked:
+           print ('Unlock keyring.')
+           _unlock_gnome_keyring('Keyring password: ')
+           password = creds_mgr.get_password(url, user)
+
         if password is None:
             raise oscerr.ConfigMissingCredentialsError('No password found in section %s' % url, conffile, url)
 
@@ -1048,10 +1125,18 @@ def interactive_config_setup(conffile, apiurl, initial=True):
 def select_credentials_manager_descr():
     if not credentials.has_keyring_support():
         print('To use keyrings please install python-keyring.')
+    if config['creds_mgr']:
+        creds_mgr = config['creds_mgr']
+    else:
+        creds_mgr = DEFAULTS['creds_mgr']
     creds_mgr_descriptors = credentials.get_credentials_manager_descriptors()
     for i, creds_mgr_descr in enumerate(creds_mgr_descriptors, 1):
-        print('%d) %s (%s)' % (i, creds_mgr_descr.name(), creds_mgr_descr.description()))#
-    i = raw_input('Select credentials manager: ')
+        if creds_mgr is not None:
+            if creds_mgr == creds_mgr_descr.name():
+                return creds_mgr_descr
+        else:
+            print('%d) %s (%s)' % (i, creds_mgr_descr.name(), creds_mgr_descr.description()))#
+    I = raw_input('Select credentials manager: ')
     if not i.isdigit():
         sys.exit('Invalid selection')
     i = int(i) - 1
@@ -1060,3 +1145,4 @@ def select_credentials_manager_descr():
     return creds_mgr_descriptors[i]
 
 # vim: sw=4 et
+
openSUSE Build Service is sponsored by