使用libsecret我无法进入解锁项目的标签
我正在使用libsecret的一个小程序。这个程序应该能够创建一个Secret.Service ...使用libsecret我无法进入解锁项目的标签
from gi.repository import Secret
service = Secret.Service.get_sync(Secret.ServiceFlags.LOAD_COLLECTIONS)
...从服务获得特定集合...
# 2 is the index of a custom collection I created, not the default one.
collection = service.get_collections()[2]
...然后列出所有项目在该集合内部,只需打印标签即可。
# I'm just printing a single label here for testing, I'd need all of course.
print(collection.get_items()[0].get_label())
一个重要的细节是,Collecction最初可以被锁定,所以我需要包括用于检查这种可能性,并尝试解锁集合代码。
# The unlock method returns a tuple (number_of_objs_unlocked, [list_of_objs])
collection = service.unlock_sync([collection])[1][0]
这是重要的,因为我现在有一个可以做所有的代码,我需要在集合最初解锁。但是,如果该集合最初被锁定,即使解锁后,我也无法从内部的项目中获取标签。我可以做的是断开()服务,再次重新创建服务,获取现在解锁的集合,这样我就可以读取每个项目上的标签。另一个有趣的细节是,在标签读取一次之后,我不再需要服务重新连接来访问它们。这看起来很不雅,所以我开始寻找不同的解决方案。
我意识到集合继承自Gio.DBusProxy,并且此类从它访问的对象中缓存数据。所以我假设这是我的问题,我没有更新缓存。这很奇怪,因为文档声明Gio.DBusProxy应该能够检测到原始对象的变化,但这并没有发生。
现在我不知道如何更新该类上的缓存。我看了一些海马(使用libsecret的另一个应用程序)vala代码,我无法完全解读,我无法编码vala,但是提到了Object.emit()方法,我是仍然不知道如何使用该方法来实现我的目标。从文档(https://lazka.github.io/pgi-docs/Secret-1/#)中,我发现了另一个有前途的方法Object.notify(),它似乎能够发送启用缓存更新的更改通知,但我还无法正确使用它。
我也张贴了关于这个在gnome-钥匙圈邮件列表...
https://mail.gnome.org/archives/gnome-keyring-list/2015-November/msg00000.html
...没有答案,到目前为止,发现提到这个问题上gnome.org一个Bugzilla报告...
https://bugzilla.gnome.org/show_bug.cgi?id=747359
...无解至今(7个月)两种。
所以,如果有人可以对这个问题有所了解,那就太好了。否则一些不雅的代码将不幸地发现它进入我的小程序。
编辑-0:
下面是一些代码复制的问题Python3。 这段代码创建一个集合'test_col',其中一个项目'test_item',并锁定集合。注意libsecret会提示你输入你想为这个新的集合口令:
#!/usr/bin/env python3
from gi import require_version
require_version('Secret', '1')
from gi.repository import Secret
# Create schema
args = ['com.idlecore.test.schema']
args += [Secret.SchemaFlags.NONE]
args += [{'service': Secret.SchemaAttributeType.STRING,
'username': Secret.SchemaAttributeType.STRING}]
schema = Secret.Schema.new(*args)
# Create 'test_col' collection
flags = Secret.CollectionCreateFlags.COLLECTION_CREATE_NONE
collection = Secret.Collection.create_sync(None, 'test_col', None, flags, None)
# Create item 'test_item' inside collection 'test_col'
attributes = {'service': 'stackoverflow', 'username': 'xor'}
password = 'password123'
value = Secret.Value(password, len(password), 'text/plain')
flags = Secret.ItemCreateFlags.NONE
Secret.Item.create_sync(collection, schema, attributes,
'test_item', value, flags, None)
# Lock collection
service = collection.get_service()
service.lock_sync([collection])
然后,我们需要重新启动GNOME的钥匙圈守护,你可以退出并回到或使用命令行:
gnome-keyrin-daemon --replace
这将设置你的钥匙圈,所以我们可以尝试打开一个初始锁定的集合。我们可以用这段代码来做到这一点。请注意,您将再次收到您之前设置的密码:
#!/usr/bin/env python3
from gi import require_version
require_version('Secret', '1')
from gi.repository import Secret
# Get the service
service = Secret.Service.get_sync(Secret.ServiceFlags.LOAD_COLLECTIONS)
# Find the correct collection
for c in service.get_collections():
if c.get_label() == 'test_col':
collection = c
break
# Unlock the collection and show the item label, note that it's empty.
collection = service.unlock_sync([collection])[1][0]
print('Item Label:', collection.get_items()[0].get_label())
# Do the same thing again, and it works.
# It's necessary to disconnect the service to clear the cache,
# Otherwise we keep getting the same empty label.
service.disconnect()
# Get the service
service = Secret.Service.get_sync(Secret.ServiceFlags.LOAD_COLLECTIONS)
# Find the correct collection
for c in service.get_collections():
if c.get_label() == 'test_col':
collection = c
break
# No need to unlock again, just show the item label
print('Item Label:', collection.get_items()[0].get_label())
此代码尝试读取两次项目标签。一种正常的方式,失败后,您应该看到一个空字符串,然后使用解决方法,断开服务并重新连接。
我一直在做这个
print(collection.get_locked())
if collection.get_locked():
service.unlock_sync(collection)
,如果它要工作,虽然,因为我从来没有打,我有一些已被锁定的情况下,我不知道。如果你有一段示例代码,我可以创造一个集合的锁定实例,然后也许我可以帮
我碰到这个问题就来了,而试图更新脚本我用它来获取我的笔记本电脑从我的桌面密码,反之亦然。
线索是the documentation for Secret.ServiceFlags
-there两种:
OPEN_SESSION= 2
建立会话为秘密的传递,同时初始化Secret.Service
LOAD_COLLECTIONS= 4
个负载集合在初始化Secret.Service
我想了Service
是都负荷收藏和允许来自这些集合的秘密(包括商品标签)的转移,我们需要同时使用标志。
下面的代码(类似于your mailing list post,但没有一个临时的集合设置为调试)似乎工作。它给了我一个项目的标签:
from gi.repository import Secret
service = Secret.Service.get_sync(Secret.ServiceFlags.OPEN_SESSION |
Secret.ServiceFlags.LOAD_COLLECTIONS)
collections = service.get_collections()
unlocked_collection = service.unlock_sync([collections[0]], None)[1][0]
unlocked_collection.get_items()[0].get_label()
我得到和以前一样的行为。我会注意到,这种行为只发生在第一次解锁。要正确测试此,我首先需要重启GNOME的钥匙圈守护与“GNOME的钥匙圈守护--replace”。 – xor
我编辑了我的原始帖子,在底部包含一些可帮助复制问题的python3文件。 – xor