Skip to content

Commit 8be62cb

Browse files
committed
Support 'store' argument in Credentials.add
Previously, there was not way to access `add_cred_from` from the high-level API. Now, `Credentials.add` accepts the `store` method. Closes #14
1 parent 458ef1b commit 8be62cb

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

gssapi/creds.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,8 @@ def inquire_by_mech(self, mech, name=True, init_lifetime=True,
276276
res.usage)
277277

278278
def add(self, desired_name, desired_mech, usage='both',
279-
init_lifetime=None, accept_lifetime=None, impersonator=None):
279+
init_lifetime=None, accept_lifetime=None, impersonator=None,
280+
store=None):
280281
"""Acquire more credentials to add to the current set
281282
282283
This method works like :meth:`acquire`, except that it adds the
@@ -289,6 +290,17 @@ def add(self, desired_name, desired_mech, usage='both',
289290
impersonate the given name using the impersonator credentials.
290291
This requires the Services4User extension.
291292
293+
If the `store` argument is used, the credentials will be acquired
294+
from the given credential store (if supported). Otherwise, the
295+
credentials are acquired from the default store.
296+
297+
The credential store information is a dictionary containing
298+
mechanisms-specific keys and values pointing to a credential store
299+
or stores.
300+
301+
Note that the `store` argument is not compatible with the
302+
`impersonator` argument.
303+
292304
Args:
293305
desired_name (Name): the name associated with the
294306
credentials
@@ -302,13 +314,30 @@ def add(self, desired_name, desired_mech, usage='both',
302314
credentials, or None for indefinite
303315
impersonator (Credentials): the credentials to use to impersonate
304316
the given name, or None to not acquire normally
317+
store (dict): the credential store information pointing to the
318+
credential store from which to acquire the credentials,
319+
or None for the default store
305320
306321
Returns:
307322
Credentials: the credentials set containing the current credentials
308323
and the newly acquired ones.
309324
"""
310325

311-
if impersonator is not None:
326+
if store is not None and impersonator is not None:
327+
raise ValueError('You cannot use both the `impersonator` and '
328+
'`store` arguments at the same time')
329+
330+
if store is not None:
331+
if rcred_cred_store is None:
332+
raise NotImplementedError("Your GSSAPI implementation does "
333+
"not have support for manipulating "
334+
"credential stores")
335+
336+
res = rcred_cred_store.add_cred_from(store, self, desired_name,
337+
desired_mech, usage,
338+
init_lifetime,
339+
accept_lifetime)
340+
elif impersonator is not None:
312341
if rcred_s4u is None:
313342
raise NotImplementedError("Your GSSAPI implementation does "
314343
"not have support for S4U")

gssapi/tests/test_high_level.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ def true_false_perms(*all_elems_tuple):
115115
class CredsTestCase(_GSSAPIKerberosTestCase):
116116
def setUp(self):
117117
super(CredsTestCase, self).setUp()
118+
119+
svc_princ = SERVICE_PRINCIPAL.decode("UTF-8")
120+
self.realm.kinit(svc_princ, flags=['-k'])
121+
118122
self.name = gssnames.Name(SERVICE_PRINCIPAL,
119123
gb.NameType.kerberos_principal)
120124

@@ -233,6 +237,10 @@ def test_inquire_by_mech(self, str_name, kwargs):
233237
def test_add(self):
234238
self.skipTest("Not Yet Implemented")
235239

240+
# NB(directxman12): we don't test add_cred_from because it really requires
241+
# multiple mechanism support, which would mean something
242+
# like requiring NTLM libraries
243+
236244
@_extension_test('cred_imp_ext', 'credentials import-export')
237245
def test_export(self):
238246
creds = gsscreds.Credentials(desired_name=self.name)

0 commit comments

Comments
 (0)