mirror of
https://github.com/borgbase/vorta
synced 2025-01-03 05:36:19 +00:00
Resolve conflight with pytest-xdist and pyobjc.
This commit is contained in:
parent
a2e9bf2886
commit
014f957c56
2 changed files with 54 additions and 39 deletions
|
@ -1,61 +1,76 @@
|
|||
# flake8: noqa
|
||||
|
||||
"""
|
||||
A dirty objc implementation to access the macOS Keychain. Because the
|
||||
keyring implementation was causing trouble when used together with other
|
||||
objc modules.
|
||||
|
||||
From https://gist.github.com/apettinen/5dc7bf1f6a07d148b2075725db6b1950
|
||||
Adapted from https://gist.github.com/apettinen/5dc7bf1f6a07d148b2075725db6b1950
|
||||
"""
|
||||
|
||||
import keyring
|
||||
import objc
|
||||
from ctypes import c_char
|
||||
from Foundation import NSBundle
|
||||
Security = NSBundle.bundleWithIdentifier_('com.apple.security')
|
||||
|
||||
S_functions = [
|
||||
('SecKeychainGetTypeID', b'I'),
|
||||
('SecKeychainItemGetTypeID', b'I'),
|
||||
('SecKeychainAddGenericPassword', b'i^{OpaqueSecKeychainRef=}I*I*I*o^^{OpaqueSecKeychainItemRef}'),
|
||||
('SecKeychainOpen', b'i*o^^{OpaqueSecKeychainRef}'),
|
||||
('SecKeychainFindGenericPassword', b'i@I*I*o^Io^^{OpaquePassBuff}o^^{OpaqueSecKeychainItemRef}'),
|
||||
]
|
||||
|
||||
objc.loadBundleFunctions(Security, globals(), S_functions)
|
||||
|
||||
SecKeychainRef = objc.registerCFSignature(
|
||||
'SecKeychainRef', b'^{OpaqueSecKeychainRef=}', SecKeychainGetTypeID()) # noqa: F821
|
||||
SecKeychainItemRef = objc.registerCFSignature(
|
||||
'SecKeychainItemRef', b'^{OpaqueSecKeychainItemRef=}', SecKeychainItemGetTypeID()) # noqa: F821
|
||||
PassBuffRef = objc.createOpaquePointerType(
|
||||
"PassBuffRef", b"^{OpaquePassBuff=}", None)
|
||||
from keyring.backend import KeyringBackend
|
||||
|
||||
|
||||
def resolve_password(password_length, password_buffer):
|
||||
return (c_char * password_length).from_address(password_buffer.__pointer__)[:].decode('utf-8')
|
||||
|
||||
|
||||
# Get the login keychain
|
||||
result, login_keychain = SecKeychainOpen(b'login.keychain', None) # noqa: F821
|
||||
|
||||
|
||||
class VortaDarwinKeyring(keyring.backend.KeyringBackend):
|
||||
class VortaDarwinKeyring(KeyringBackend):
|
||||
"""Homemade macOS Keychain Service"""
|
||||
|
||||
login_keychain = None
|
||||
|
||||
def _set_keychain(self):
|
||||
"""
|
||||
Lazy import to avoid conflict with pytest-xdist.
|
||||
"""
|
||||
import objc
|
||||
from Foundation import NSBundle
|
||||
Security = NSBundle.bundleWithIdentifier_('com.apple.security')
|
||||
|
||||
S_functions = [
|
||||
('SecKeychainGetTypeID', b'I'),
|
||||
('SecKeychainItemGetTypeID', b'I'),
|
||||
('SecKeychainAddGenericPassword', b'i^{OpaqueSecKeychainRef=}I*I*I*o^^{OpaqueSecKeychainItemRef}'),
|
||||
('SecKeychainOpen', b'i*o^^{OpaqueSecKeychainRef}'),
|
||||
('SecKeychainFindGenericPassword', b'i@I*I*o^Io^^{OpaquePassBuff}o^^{OpaqueSecKeychainItemRef}'),
|
||||
]
|
||||
|
||||
objc.loadBundleFunctions(Security, globals(), S_functions)
|
||||
|
||||
SecKeychainRef = objc.registerCFSignature('SecKeychainRef', b'^{OpaqueSecKeychainRef=}', SecKeychainGetTypeID())
|
||||
SecKeychainItemRef = objc.registerCFSignature('SecKeychainItemRef', b'^{OpaqueSecKeychainItemRef=}', SecKeychainItemGetTypeID())
|
||||
PassBuffRef = objc.createOpaquePointerType('PassBuffRef', b'^{OpaquePassBuff=}', None)
|
||||
|
||||
# Get the login keychain
|
||||
result, login_keychain = SecKeychainOpen(b'login.keychain', None)
|
||||
self.login_keychain = login_keychain
|
||||
|
||||
@classmethod
|
||||
def priority(cls):
|
||||
return 5
|
||||
|
||||
def set_password(self, service, repo_url, password):
|
||||
result, keychain_item = SecKeychainAddGenericPassword( # noqa: F821
|
||||
login_keychain, len(service), service, len(repo_url), repo_url, len(password), password, None)
|
||||
if not self.login_keychain: self._set_keychain()
|
||||
|
||||
SecKeychainAddGenericPassword(
|
||||
self.login_keychain,
|
||||
len(service), service.encode(),
|
||||
len(repo_url), repo_url.encode(),
|
||||
len(password), password.encode(),
|
||||
None)
|
||||
|
||||
def get_password(self, service, repo_url):
|
||||
result, password_length, password_buffer, keychain_item = SecKeychainFindGenericPassword( # noqa: F821
|
||||
login_keychain, len(service), service.encode(), len(repo_url), repo_url.encode(), None, None, None)
|
||||
if not self.login_keychain: self._set_keychain()
|
||||
|
||||
result, password_length, password_buffer, keychain_item = SecKeychainFindGenericPassword(
|
||||
self.login_keychain, len(service), service.encode(), len(repo_url), repo_url.encode(), None, None, None)
|
||||
password = None
|
||||
if (result == 0) and (password_length != 0):
|
||||
# We apparently were able to find a password
|
||||
password = resolve_password(password_length, password_buffer)
|
||||
password = _resolve_password(password_length, password_buffer)
|
||||
return password
|
||||
|
||||
def delete_password(self, service, repo_url):
|
||||
pass
|
||||
|
||||
|
||||
def _resolve_password(password_length, password_buffer):
|
||||
from ctypes import c_char
|
||||
return (c_char * password_length).from_address(password_buffer.__pointer__)[:].decode('utf-8')
|
||||
|
|
|
@ -7,9 +7,9 @@ def get_updater():
|
|||
if sys.platform == 'darwin' and getattr(sys, 'frozen', False):
|
||||
# Use sparkle framework on macOS.
|
||||
# Examples: https://programtalk.com/python-examples/objc.loadBundle/
|
||||
from objc import loadBundle
|
||||
import objc
|
||||
bundle_path = os.path.join(os.path.dirname(sys.executable), os.pardir, 'Frameworks', 'Sparkle.framework')
|
||||
loadBundle('Sparkle', globals(), bundle_path)
|
||||
objc.loadBundle('Sparkle', globals(), bundle_path)
|
||||
sparkle = SUUpdater.sharedUpdater() # noqa: F821
|
||||
if SettingsModel.get(key='updates_include_beta').value:
|
||||
sparkle.SharedUpdater.FeedURL = 'https://borgbase.github.io/vorta/appcast-pre.xml'
|
||||
|
|
Loading…
Reference in a new issue