diff options
Diffstat (limited to 'ipalib')
-rw-r--r-- | ipalib/frontend.py | 24 | ||||
-rw-r--r-- | ipalib/parameters.py | 20 |
2 files changed, 41 insertions, 3 deletions
diff --git a/ipalib/frontend.py b/ipalib/frontend.py index 565060b5d..3665cc0e7 100644 --- a/ipalib/frontend.py +++ b/ipalib/frontend.py @@ -98,7 +98,7 @@ class Command(plugable.Plugin): """ params = self.args_options_2_params(*args, **options) self.info( - '%s(%s)', self.name, ', '.join(self.__repr_iter(params)) + '%s(%s)', self.name, ', '.join(self._repr_iter(**params)) ) params = self.normalize(**params) params = self.convert(**params) @@ -109,10 +109,28 @@ class Command(plugable.Plugin): self.debug('result from %s(): %r', self.name, result) return result - def __repr_iter(self, params): + def _repr_iter(self, **params): + """ + Iterate through ``repr()`` of *safe* values of args and options. + + This method uses `parameters.Param.safe_value()` to mask passwords when + logging. Logging the exact call is extremely useful, but we obviously + don't want to log the cleartext password. + + For example: + + >>> class my_cmd(Command): + ... takes_args = ('login',) + ... takes_options=(Password('passwd'),) + ... + >>> c = my_cmd() + >>> c.finalize() + >>> list(c._repr_iter(login=u'Okay.', passwd=u'Private!')) + ["u'Okay.'", "passwd=u'********'"] + """ for arg in self.args(): value = params.get(arg.name, None) - yield '%r' % (arg.safe_value(value),) + yield repr(arg.safe_value(value)) for option in self.options(): if option.name not in params: continue diff --git a/ipalib/parameters.py b/ipalib/parameters.py index 6ce0ad80a..fe32c92f6 100644 --- a/ipalib/parameters.py +++ b/ipalib/parameters.py @@ -359,6 +359,26 @@ class Param(ReadOnly): return value def safe_value(self, value): + """ + Return a value safe for logging. + + This is used so that passwords don't get logged. If this is a + `Password` instance and ``value`` is not ``None``, a constant + ``u'********'`` is returned. For example: + + >>> p = Password('my_password') + >>> p.safe_value(u'This is my password') + u'********' + >>> p.safe_value(None) is None + True + + If this is not a `Password` instance, ``value`` is returned unchanged. + For example: + + >>> s = Str('my_str') + >>> s.safe_value(u'Some arbitrary value') + u'Some arbitrary value' + """ if self.password and value is not None: return u'********' return value |