使用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': '*', '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) 

,如果它要工作,虽然,因为我从来没有打,我有一些已被锁定的情况下,我不知道。如果你有一段示例代码,我可以创造一个集合的锁定实例,然后也许我可以帮

+0

我编辑了我的原始帖子,在底部包含一些可帮助复制问题的python3文件。 – xor

我碰到这个问题就来了,而试图更新脚本我用它来获取我的笔记本电脑从我的桌面密码,反之亦然。

线索是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() 
+0

我得到和以前一样的行为。我会注意到,这种行为只发生在第一次解锁。要正确测试此,我首先需要重启GNOME的钥匙圈守护与“GNOME的钥匙圈守护--replace”。 – xor