Skip to content

Commit

Permalink
Unified the Windows.get_password and .get_credential logic through a …
Browse files Browse the repository at this point in the history
…new _resolve_credential method.
  • Loading branch information
jaraco committed Oct 26, 2024
1 parent f33fcfb commit 5e4b99e
Showing 1 changed file with 15 additions and 20 deletions.
35 changes: 15 additions & 20 deletions keyring/backends/Windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,20 @@ def _compound_name(username, service):
return f'{username}@{service}'

def get_password(self, service, username):
res = self._resolve_credential(service, username)
return res and res.value

def _resolve_credential(
self, service: str, username: str | None
) -> DecodingCredential | None:
# first attempt to get the password under the service name
res = self._get_password(service)
if not res or res['UserName'] != username:
res = self._read_credential(service)
if not res or username and res['UserName'] != username:
# It wasn't found so attempt to get it with the compound name
res = self._get_password(self._compound_name(username, service))
if not res:
return None
return res.value
res = self._read_credential(self._compound_name(username, service))
return res

def _get_password(self, target):
def _read_credential(self, target):
try:
res = win32cred.CredRead(
Type=win32cred.CRED_TYPE_GENERIC, TargetName=target
Expand All @@ -115,7 +119,7 @@ def _get_password(self, target):
return DecodingCredential(res)

def set_password(self, service, username, password):
existing_pw = self._get_password(service)
existing_pw = self._read_credential(service)
if existing_pw:
# resave the existing password using a compound target
existing_username = existing_pw['UserName']
Expand All @@ -142,7 +146,7 @@ def delete_password(self, service, username):
compound = self._compound_name(username, service)
deleted = False
for target in service, compound:
existing_pw = self._get_password(target)
existing_pw = self._read_credential(target)
if existing_pw and existing_pw['UserName'] == username:
deleted = True
self._delete_password(target)
Expand All @@ -158,14 +162,5 @@ def _delete_password(self, target):
raise

def get_credential(self, service, username):
res = None
# get the credentials associated with the provided username
if username:
res = self._get_password(self._compound_name(username, service))
# get a credential matching service and username if provided
if not res:
cred = self._get_password(service)
res = cred if username is None or username == cred["UserName"] else None
if not res:
return None
return SimpleCredential(res['UserName'], res.value)
res = self._resolve_credential(service, username)
return res and SimpleCredential(res['UserName'], res.value)

0 comments on commit 5e4b99e

Please sign in to comment.