xi-keyring

simple and extensible alternative for gnome-keyring
git clone https://git.ce9e.org/xi-keyring.git

commit
da6b828060bd429f95bfeab8ccbe8b708f9f51df
parent
9b32cb44697f20a29d8bfb1375daab7d57352b68
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2026-05-24 10:27
breaking: stop storing and checking app_id

Diffstat

M xikeyring/dbus.py 2 --
M xikeyring/keyring.py 23 ++++++++---------------

2 files changed, 8 insertions, 17 deletions


diff --git a/xikeyring/dbus.py b/xikeyring/dbus.py

@@ -380,8 +380,6 @@ class DBusService(BaseDBusService):
  380   380             conn, handle, 'org.freedesktop.impl.portal.Request'
  381   381         )
  382   382         try:
  383    -1             if self.get_app_id(conn, sender):
  384    -1                 raise AccessDeniedError
  385   383             attrs = {
  386   384                 'application': 'org.freedesktop.portal.Secret',
  387   385                 'app_id': app_id,

diff --git a/xikeyring/keyring.py b/xikeyring/keyring.py

@@ -24,7 +24,6 @@ class NotFoundError(Exception):
   24    24 class Item:
   25    25     secret: bytes
   26    26     attributes: dict[str, str]
   27    -1     app_id: str
   28    27 
   29    28 
   30    29 def write_bytes(path: Path, data: bytes) -> int:
@@ -95,8 +94,8 @@ class Keyring:
   95    94         decrypted = Fernet(self.key.value).decrypt(encrypted)
   96    95         raw = json.loads(decrypted)
   97    96         return {
   98    -1             id: Item(base64.urlsafe_b64decode(secret), attributes, app_id)
   99    -1             for id, secret, attributes, app_id in raw
   -1    97             id: Item(base64.urlsafe_b64decode(secret), attributes)
   -1    98             for id, secret, attributes in raw
  100    99         }
  101   100 
  102   101     def _write(self, items: dict[int, Item]):
@@ -105,7 +104,6 @@ class Keyring:
  105   104                 id,
  106   105                 base64.urlsafe_b64encode(item.secret).decode(),
  107   106                 item.attributes,
  108    -1                 item.app_id,
  109   107             )
  110   108             for id, item in items.items()
  111   109         ]
@@ -121,22 +119,17 @@ class Keyring:
  121   119         if not self.prompt.confirm('Allow changes to your keyring?'):
  122   120             raise AccessDeniedError
  123   121 
  124    -1     def get(self, items: dict[int, Item], app_id: str, id: int) -> Item:
   -1   122     def get(self, items: dict[int, Item], id: int) -> Item:
  125   123         try:
  126    -1             item = items[id]
   -1   124             return items[id]
  127   125         except KeyError as e:
  128   126             raise NotFoundError from e
  129    -1         if item.app_id != app_id:
  130    -1             raise NotFoundError
  131    -1         return item
  132   127 
  133   128     def search_items(self, app_id: str, query: dict[str, str] = {}) -> list[int]:
  134   129         items = self._read()
  135   130         return [
  136   131             id for id, item in items.items()
  137    -1             if item.app_id == app_id and all(
  138    -1                 item.attributes.get(key) == value for key, value in query.items()
  139    -1             )
   -1   132             if all(item.attributes.get(k) == v for k, v in query.items())
  140   133         ]
  141   134 
  142   135     def get_attributes(self, app_id: str, id: int) -> dict[str, str]:
@@ -145,7 +138,7 @@ class Keyring:
  145   138 
  146   139     def get_secret(self, app_id: str, id: int) -> bytes:
  147   140         items = self._read()
  148    -1         item = self.get(items, app_id, id)
   -1   141         item = self.get(items, id)
  149   142         self.confirm_access()
  150   143         return item.secret
  151   144 
@@ -158,14 +151,14 @@ class Keyring:
  158   151 
  159   152     def update_attributes(self, app_id: str, id: int, attributes: dict[str, str]) -> None:
  160   153         items = self._read()
  161    -1         item = self.get(items, app_id, id)
   -1   154         item = self.get(items, id)
  162   155         self.confirm_change()
  163   156         item.attributes = attributes
  164   157         self._write(items)
  165   158 
  166   159     def update_secret(self, app_id: str, id: int, secret: bytes) -> None:
  167   160         items = self._read()
  168    -1         item = self.get(items, app_id, id)
   -1   161         item = self.get(items, id)
  169   162         self.confirm_change()
  170   163         item.secret = secret
  171   164         self._write(items)