dotfiles/mail/offlineimap/offlineimap.py

152 lines
4.8 KiB
Python

'''
offlineimap.py
This provides a handful of functions for retrieving secrets from GNOME Keyring
using the libsecret API. See the documentation for each function
'''
from gi import require_version
require_version('Secret', '1')
from gi.repository import Secret
def get_pw_from_desc(pw_desc) :
'''
This function returns the password for an item in the default keyring
which contains the description provided.
Use this function if you created a password using the dialogue in Seahorse
'''
# Get service
service = Secret.Service.get_sync(Secret.ServiceFlags.LOAD_COLLECTIONS)
# Get default keyring
keyring = Secret.Collection.for_alias_sync(service, "default", \
Secret.CollectionFlags.NONE, None)
# Get keyring items
items = keyring.get_items()
# Load secrets
Secret.Item.load_secrets_sync(items)
# Loop through items, find the matching one and return its password
password = None
for item in items :
if item.get_label() == pw_desc :
password = item.get_secret().get_text()
break
# Close connection
service.disconnect()
return password
def get_pw_from_attrs(*attr_val_pairs) :
'''
This function returns the password for an item in the default keyring
which contains all of the attribute value pairs provided as arguments.
Use this function if you created a password using the secret-tool command
or another such program that interfaces with libsecret
'''
# Check the list of attr-val pairs is present and contains an even number
# of elements
if attr_val_pairs == () :
raise TypeError("get_pw_from_attrs() at least 1 attribute-value pair " \
"must be supplied")
if len(attr_val_pairs) % 2 != 0 :
raise TypeError("get_pw_from_attrs() incomplete attribute-value " \
"pair was supplied")
# Get service
service = Secret.Service.get_sync(Secret.ServiceFlags.LOAD_COLLECTIONS)
# Get default keyring
keyring = Secret.Collection.for_alias_sync(service, "default", \
Secret.CollectionFlags.NONE, None)
# Get keyring items
items = keyring.get_items()
# Load secrets
Secret.Item.load_secrets_sync(items)
# Loop through items, find the one which contains all supplied attr_val
# pairs and return its password
password = None
for item in items :
attrs = item.get_attributes()
match = True
for x in range(0, len(attr_val_pairs), 2) :
key = attr_val_pairs[x]
value = attr_val_pairs[x + 1]
try :
if attrs[key] != value :
match = False
break
except KeyError :
match = False
break
if match :
password = item.get_secret().get_text()
break
# Close connection
service.disconnect()
return password
def get_val_from_attrs(attr, *attr_val_pairs) :
'''
This function returns the value for a given attribute. The first item
found that contains that attribute will be the one that is used. To ensure
that the correct item is chosen, any number of attribute-value pairs can
be optionally supplied as arguments and only the item which contains all
of those attr-val pairs (along with the main attr) will be used.
Use this function if you created a password using the secret-tool command
or another such program that interfaces with libsecret
'''
# Check the list of attr-val pairs contains an even number of elements
# if it exists
if attr_val_pairs != () :
if len(attr_val_pairs) % 2 != 0 :
raise TypeError("get_val_from_attrs() incomplete attribute-value " \
"pair was supplied")
# Get service
service = Secret.Service.get_sync(Secret.ServiceFlags.LOAD_COLLECTIONS)
# Get default keyring
keyring = Secret.Collection.for_alias_sync(service, "default", \
Secret.CollectionFlags.NONE, None)
# Get keyring items
items = keyring.get_items()
# Loop through items, find the one which contains the supplied attribute
# (plus any attr_val pairs if specified) and return that attribute's
# value
attr_value = None
for item in items :
attrs = item.get_attributes()
try :
attrs[attr]
except KeyError :
continue
match = True
for x in range(0, len(attr_val_pairs), 2) :
key = attr_val_pairs[x]
value = attr_val_pairs[x + 1]
try :
if attrs[key] != value :
match = False
break
except KeyError :
match = False
break
if match :
attr_value = attrs[attr]
break
# Close connection
service.disconnect()
return attr_value