[Freeipa-devel] [PATCH] 353 Added initial vault implementation.
Endi Sukma Dewata
edewata at redhat.com
Wed Nov 5 00:24:26 UTC 2014
Thanks for the review. I have some questions below. I'll post a new
patch after the issues are addressed.
On 11/4/2014 11:36 AM, Petr Viktorin wrote:
> The new schema can go to 60basev3.ldif, no need for a new file.
Fixed. Also removed nsContainer as suggested by Simo.
> ipalib/plugins/user.py: Make the try: block as small as possible; maybe
> something like this:
>
> try:
> vaultcontainer_id = ...
> except errors.NotFound:
> pass
> else:
> (vaultcontainer_name, vaultcontainer_parent_id) = ...
> self.api.Command.vaultcontainer_del(...)
Actually the command that generates the NotFound exception is the last
command. The first two commands are preparing the parameters. I moved
them before the try-block.
> ipapython/dn.py: This change is not needed. If you have a sequence of
> RNDs you can do `DN(*seq)`.
This is actually needed to construct a parent DN from an existing DN:
parent_dn = DN(dn[1:])
Note that the parameter is an array of RDNs, not a sequence of RDNs. I
don't see an existing mechanism to get a parent DN from a DN. Without
this change it would generate an error:
ValueError: tuple or list must be 2-valued, not
"[ipapython.dn.RDN('cn=admin'), ipapython.dn.RDN('cn=users'),
ipapython.dn.RDN('cn=vaults'), ipapython.dn.RDN('dc=idm'),
ipapython.dn.RDN('dc=lab'), ipapython.dn.RDN('dc=bos'),
ipapython.dn.RDN('dc=redhat'), ipapython.dn.RDN('dc=com')]"
> ipalib/plugins/vault.py:
> Do not use star imports in new code; remove the line
> from ipalib.plugins.baseldap import *
> and use e.g. `baseldap.LDAPObject` instead of just `LDAPObject`.
> Hopefully the only star-imported used are the base classes?
I found 20 star imports in the existing plugins :/
All existing plugins are actually using LDAPObject directly, not
baseldap.LDAPObject. Is there a concern doing that? I fixed the code to
do the same thing.
> To make translators' jobs easier, split the help text in __doc__ into
> strings that can be translated individually.
> Replace every blank line by:
> """) + _("""
Fixed.
> The pattern and pattern_errmsg for the 'cn' param don't match. Which one
> is right? Shouldn't a similar check be there for parent?
This is actually copied verbatim from user's uid. Could you give some
sample values that show the problem?
I think ideally there should be a similar check for parent, but I
haven't figured out the proper pattern yet. I think we can do this as a
later enhancement. Or maybe we should remove the validation for cn for now.
> vaultcontainer.get_dn: Why put '/' at the end of container_id, if the
> empty string is ignored later anyway?
I'm still considering some options for container ID:
a) use a slash at the end for all containers (e.g. /users/)
b) don't use a trailing slash, except for root container (/)
I think option (a) is more consistent, container ID always ends with
slash, although in cases like this it can be redundant. This is how the
code is currently written. We can make an exception for
vaultcontainer.get_dn() though.
Option (b) will require more careful coding in many places (e.g.
concatenations) because it needs to handle a special case for root
container.
Maybe a better way is to use an array of names internally and the slash
is only used during input/output. The problem is when calling another
command the array has to be converted into string and parsed back into
array, so it may even introduce more redundancies. I don't see a way to
pass an object parameter to a command. Any suggestion?
> Nitpick: In vaultcontainer.get_dn, prefer the if statement over the
> if-else expressions; it's a bit longer but more readable.
Fixed.
> In vaultcontainer.get_id, what's the purpose of the len() check? Did you
> want dn.endswith() instead?
Yes, but my assumption is the DN will always be within the namespace
because it's only used internally, and using len() will be faster than
endswith(). The error case will never happen, but I was just making sure
there won't be an infinite loop. Maybe instead of calling the method
recursively I should just use a loop? That will avoid repetitive
validations.
> I sugggest writing doctests for the id manipulation methods (get_id,
> get_private_id, ...) – it's not always obvious what exactly they do.
Do you mean sample code in docs? Is it still necessary if we have some
test code?
> According to the design doc, container IDs shouldn't end in '/'. If you
> did that I think the manipulation would be simpler, and it could be
> shared with the vault equivalents.
Yeah, as mentioned above I'm still considering several options. The
design may need to be adjusted.
> vaultcontainer_add: You should use ldap backend directly. Calling
> Commands is costly, most of the call is spent doing validation of what
> here is already validated. You should add a function to recursively
> create vault container using just the ldap client, and call that here
> and in vault_add.
Hmm.. I'm not sure if we should write a code that will duplicate
everything done by the LDAPCreate class. Shouldn't server-side
command-to-command invocation be relatively faster?
The recursion is mainly used to create the user's private container.
Note that the private container is not created by default. We only
provide /users top-level container. When a user creates a private vault
the command will automatically create the /users/<username> private
container on the user's behalf. This will only happen once for each
user. In most other cases the parent would already exist.
Another option is to require the user or the admin to create the private
container manually, but that would be less user-friendly.
Another option is to check the parent container using direct LDAP
search, but still do the add using vaultcontainer_add. What do you think?
> You can delete a container with children; is that expected?
This seems to be LDAPDelete's built-in functionality. Is there an option
to disallow non-empty subtree removal?
For vault purposes, when a user is removed from IPA the server will
remove the user's entire private container, so the feature would
actually be useful here. But probably in general we should warn the user
if they are deleting a non-empty container. If there's an option in
LDAPDelete we can let the user specify that option if necessary.
> vault_add should complain if it does not get exactly one of data/text/in.
Actually, no. The primary way to archive data is via vault_archive. The
vault_add is for creating a vault, but optionally you can specify the
initial data to be archived. If nothing is specified it will archive an
empty string. Note that for symmetric vault the encrypted empty string
can be used to enforce that the same password will be used on on
subsequent archival operations.
I'm trying to change vault_archive to raise an error if it's missing the
input data and change vault_add to archive empty string if nothing is
specified, but it doesn't work since the framework seems to be
converting the empty string into None, so vault_archive can't tell if
it's archiving an empty string or missing the input data. Any suggestion?
> What's the difference between vault_add and vault_archive? I don't see
> vault_archive in the design.
Yes, that's due to a recent 'standard vault' addition. I have not added
vault_archive yet to the design. The vault_archive is used to archive a
generic blob of data. The vaultsecret_archive will later be used to add
secrets into a JSON structure which will then be archived using the
vault_archive.
> It seems '/' is equivalent to '-' as far as KRA is concerned; should we
> disallow '-' in container/vault names?
I think so, but as I mentioned earlier I haven't look very far on
attribute validations.
The slashes in vault ID is converted into dashes in KRA's client key ID.
KRA actually accepts slashes, but the slashes will not look pretty in
REST URL because they will be URL-encoded (in case it's needed for
troubleshooting KRA via browser) so I changed them to dashes.
> You can specify an absolute id by starting it with a slash, but only in
> --parent and not in the name itself. I think this should be possible in
> the name too.
Right, but I'm not sure how it will work with the IPA framework. The
first command parameter is the cn (vault name). If we specify a vault ID
(with slashes) there it will be entered into cn. Should we parse the ID
and insert the vault name and parent ID back into keys and options
variables? Which value will eventually be stored into cn in LDAP?
> You can't include slashes in the name, so you always need to specify the
> prefix with --parent. I don't think there's a technical reason for this
> limitation.
See the above explanation. What does primary_key actually mean in
hierarchical structure like vault? Since cn is only unique locally, is
cn a primary key? Can a virtual attribute be a primary key?
> There are no tests.
Right, I'll take a look at how to write tests. Is there a way to run
tests without running the full build?
--
Endi S. Dewata
More information about the Freeipa-devel
mailing list