[Freeipa-devel] [PATCH] Password vault

Endi Sukma Dewata edewata at redhat.com
Tue Mar 17 04:59:31 UTC 2015


On 3/13/2015 2:27 AM, Endi Sukma Dewata wrote:
> On 3/11/2015 9:12 PM, Endi Sukma Dewata wrote:
>> Thanks for the review. New patch attached to be applied on top of all
>> previous patches. Please see comments below.
>
> New patch #362-1 attached replacing #362. It fixed some issues in
> handle_not_found().

New patch #363 attached. It adds supports for vault & vaultcontainer ID 
parameter.

-- 
Endi S. Dewata
-------------- next part --------------
>From e1d2a3a62e6d16c1c9b19f4cb19b900427ea5e1f Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata at redhat.com>
Date: Thu, 12 Mar 2015 09:21:02 -0400
Subject: [PATCH] Vault ID improvements.

The vault plugin has been modified to accept a single vault ID
in addition to separate name and parent ID attributes. The vault
container has also been modified in the same way. New test cases
have been added to verify this functionality.

https://fedorahosted.org/freeipa/ticket/3872
---
 ipalib/plugins/vault.py                            | 143 +++++++++++++++++--
 ipalib/plugins/vaultcontainer.py                   | 137 +++++++++++++++++--
 ipalib/plugins/vaultsecret.py                      |  10 +-
 ipatests/test_xmlrpc/test_vault_plugin.py          | 151 +++++++++++++++++++++
 ipatests/test_xmlrpc/test_vaultcontainer_plugin.py |  90 ++++++------
 ipatests/test_xmlrpc/test_vaultsecret_plugin.py    | 115 ++++++++++++++++
 6 files changed, 565 insertions(+), 81 deletions(-)

diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
index d47067758186601365e5924f5d13c7ab51ba66e5..38693d0710e000695cae21fb4db5dfb4c85b5c74 100644
--- a/ipalib/plugins/vault.py
+++ b/ipalib/plugins/vault.py
@@ -61,7 +61,7 @@ EXAMPLES:
    ipa vault-find
 """) + _("""
  List shared vaults:
-   ipa vault-find --container-id /shared
+   ipa vault-find /shared
 """) + _("""
  Add a standard vault:
    ipa vault-add MyVault
@@ -171,8 +171,8 @@ class vault(LDAPObject):
             cli_name='vault_name',
             label=_('Vault name'),
             primary_key=True,
-            pattern='^[a-zA-Z0-9_.-]+$',
-            pattern_errmsg='may only include letters, numbers, _, ., and -',
+            pattern='^[a-zA-Z0-9_.-/]+$',
+            pattern_errmsg='may only include letters, numbers, _, ., -, and /',
             maxlength=255,
         ),
         Str('vault_id?',
@@ -217,7 +217,7 @@ class vault(LDAPObject):
 
         # get vault ID from parameters
         name = keys[-1]
-        container_id = self.api.Object.vaultcontainer.normalize_id(options.get('container_id'))
+        container_id = self.api.Object.vaultcontainer.absolute_id(options.get('container_id'))
         vault_id = container_id + name
 
         dn = self.base_dn
@@ -250,6 +250,81 @@ class vault(LDAPObject):
 
         return id
 
+    def split_id(self, id):
+        """
+        Splits a vault ID into (vault name, container ID) tuple.
+        """
+
+        if not id:
+            return (None, None)
+
+        # split ID into container ID and vault name
+        parts = id.rsplit(u'/', 1)
+
+        if len(parts) == 2:
+            vault_name = parts[1]
+            container_id = u'%s/' % parts[0]
+
+        else:
+            vault_name = parts[0]
+            container_id = None
+
+        if not vault_name:
+            vault_name = None
+
+        return (vault_name, container_id)
+
+    def merge_id(self, vault_name, container_id):
+        """
+        Merges a vault name and a container ID into a vault ID.
+        """
+
+        if not vault_name:
+            id = container_id
+
+        elif vault_name.startswith('/') or not container_id:
+            id = vault_name
+
+        else:
+            id = container_id + vault_name
+
+        return id
+
+    def normalize_params(self, *args, **options):
+        """
+        Normalizes the vault ID in the parameters.
+        """
+
+        vault_id = self.parse_params(*args, **options)
+        (vault_name, container_id) = self.split_id(vault_id)
+        return self.update_params(vault_name, container_id, *args, **options)
+
+    def parse_params(self, *args, **options):
+        """
+        Extracts the vault name and container ID in the parameters.
+        """
+
+        # get vault name and container ID from parameters
+        vault_name = args[0]
+        if type(vault_name) is tuple:
+            vault_name = vault_name[0]
+        container_id = self.api.Object.vaultcontainer.normalize_id(options.get('container_id'))
+
+        return self.merge_id(vault_name, container_id)
+
+    def update_params(self, new_vault_name, new_container_id, *args, **options):
+        """
+        Stores vault name and container ID back into the parameters.
+        """
+
+        args_list = list(args)
+        args_list[0] = new_vault_name
+        args = tuple(args_list)
+
+        options['container_id'] = new_container_id
+
+        return (args, options)
+
     def get_kra_id(self, id):
         """
         Generates a client key ID to store/retrieve data in KRA.
@@ -363,10 +438,14 @@ class vault_add(LDAPCreate):
 
     msg_summary = _('Added vault "%(value)s"')
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vault_add, self).params_2_args_options(**params)
+        return self.obj.normalize_params(*args, **options)
+
     def forward(self, *args, **options):
 
         vault_name = args[0]
-        container_id = self.api.Object.vaultcontainer.normalize_id(options.get('container_id'))
+        container_id = self.api.Object.vaultcontainer.absolute_id(options.get('container_id'))
 
         vault_type = options.get('ipavaulttype')
         data = options.get('data')
@@ -549,7 +628,7 @@ class vault_add(LDAPCreate):
     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
         assert isinstance(dn, DN)
 
-        container_id = self.api.Object.vaultcontainer.normalize_id(options.get('container_id'))
+        container_id = self.api.Object.vaultcontainer.absolute_id(options.get('container_id'))
 
         # set owner
         principal = getattr(context, 'principal')
@@ -576,7 +655,7 @@ class vault_add(LDAPCreate):
 
     def handle_not_found(self, *args, **options):
 
-        container_id = self.api.Object.vaultcontainer.normalize_id(options.get('container_id'))
+        container_id = self.api.Object.vaultcontainer.absolute_id(options.get('container_id'))
 
         raise errors.NotFound(
             reason=self.obj.parent_not_found_msg % {
@@ -598,6 +677,10 @@ class vault_del(LDAPDelete):
 
     msg_summary = _('Deleted vault "%(value)s"')
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vault_del, self).params_2_args_options(**params)
+        return self.obj.normalize_params(*args, **options)
+
     def post_callback(self, ldap, dn, *keys, **options):
         assert isinstance(dn, DN)
 
@@ -638,10 +721,16 @@ class vault_find(LDAPSearch):
         '%(count)d vault matched', '%(count)d vaults matched', 0
     )
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vault_find, self).params_2_args_options(**params)
+        container_id = self.obj.parse_params(*args, **options)
+        container_id = self.api.Object.vaultcontainer.normalize_id(container_id)
+        return self.obj.update_params(None, container_id, *args, **options)
+
     def pre_callback(self, ldap, filter, attrs_list, base_dn, scope, *keys, **options):
         assert isinstance(base_dn, DN)
 
-        container_id = self.api.Object.vaultcontainer.normalize_id(options.get('container_id'))
+        container_id = self.api.Object.vaultcontainer.absolute_id(options.get('container_id'))
         (name, parent_id) = self.api.Object.vaultcontainer.split_id(container_id)
         base_dn = self.api.Object.vaultcontainer.get_dn(name, parent_id=parent_id)
 
@@ -657,7 +746,7 @@ class vault_find(LDAPSearch):
 
     def handle_not_found(self, *args, **options):
 
-        container_id = self.api.Object.vaultcontainer.normalize_id(options.get('container_id'))
+        container_id = self.api.Object.vaultcontainer.absolute_id(options.get('container_id'))
 
         # vault container is user's private container, ignore
         if container_id == self.api.Object.vaultcontainer.get_private_id():
@@ -684,6 +773,10 @@ class vault_mod(LDAPUpdate):
 
     msg_summary = _('Modified vault "%(value)s"')
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vault_mod, self).params_2_args_options(**params)
+        return self.obj.normalize_params(*args, **options)
+
     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
         assert isinstance(dn, DN)
 
@@ -703,6 +796,10 @@ class vault_show(LDAPRetrieve):
         ),
     )
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vault_show, self).params_2_args_options(**params)
+        return self.obj.normalize_params(*args, **options)
+
     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
         assert isinstance(dn, DN)
 
@@ -804,10 +901,14 @@ class vault_archive(LDAPRetrieve):
 
     msg_summary = _('Archived data into vault "%(value)s"')
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vault_archive, self).params_2_args_options(**params)
+        return self.obj.normalize_params(*args, **options)
+
     def forward(self, *args, **options):
 
         vault_name = args[0]
-        container_id = self.api.Object.vaultcontainer.normalize_id(options.get('container_id'))
+        container_id = self.api.Object.vaultcontainer.absolute_id(options.get('container_id'))
 
         vault_type = 'standard'
         salt = None
@@ -1118,10 +1219,14 @@ class vault_retrieve(LDAPRetrieve):
 
     msg_summary = _('Retrieved data from vault "%(value)s"')
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vault_retrieve, self).params_2_args_options(**params)
+        return self.obj.normalize_params(*args, **options)
+
     def forward(self, *args, **options):
 
         vault_name = args[0]
-        container_id = self.api.Object.vaultcontainer.normalize_id(options.get('container_id'))
+        container_id = self.api.Object.vaultcontainer.absolute_id(options.get('container_id'))
 
         vault_type = 'standard'
         salt = None
@@ -1396,6 +1501,10 @@ class vault_add_owner(LDAPAddMember):
     member_attributes = ['owner']
     member_count_out = ('%i owner added.', '%i owners added.')
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vault_add_owner, self).params_2_args_options(**params)
+        return self.obj.normalize_params(*args, **options)
+
     def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
         assert isinstance(dn, DN)
 
@@ -1418,6 +1527,10 @@ class vault_remove_owner(LDAPRemoveMember):
     member_attributes = ['owner']
     member_count_out = ('%i owner removed.', '%i owners removed.')
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vault_remove_owner, self).params_2_args_options(**params)
+        return self.obj.normalize_params(*args, **options)
+
     def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
         assert isinstance(dn, DN)
 
@@ -1437,6 +1550,10 @@ class vault_add_member(LDAPAddMember):
         ),
     )
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vault_add_member, self).params_2_args_options(**params)
+        return self.obj.normalize_params(*args, **options)
+
     def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
         assert isinstance(dn, DN)
 
@@ -1456,6 +1573,10 @@ class vault_remove_member(LDAPRemoveMember):
         ),
     )
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vault_remove_member, self).params_2_args_options(**params)
+        return self.obj.normalize_params(*args, **options)
+
     def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
         assert isinstance(dn, DN)
 
diff --git a/ipalib/plugins/vaultcontainer.py b/ipalib/plugins/vaultcontainer.py
index 27cb6fff3479335943bae59340c9afc773dfc004..5e8ee353ba2a625751fbfa9867366d98bdd5aea3 100644
--- a/ipalib/plugins/vaultcontainer.py
+++ b/ipalib/plugins/vaultcontainer.py
@@ -40,7 +40,10 @@ EXAMPLES:
    ipa vaultcontainer-find
 """) + _("""
  List top-level vault containers:
-   ipa vaultcontainer-find --parent-id /
+   ipa vaultcontainer-find /
+""") + _("""
+ List shared vault containers:
+   ipa vaultcontainer-find /shared
 """) + _("""
  Add a vault container:
    ipa vaultcontainer-add MyContainer
@@ -104,8 +107,8 @@ class vaultcontainer(LDAPObject):
             cli_name='container_name',
             label=_('Container name'),
             primary_key=True,
-            pattern='^[a-zA-Z0-9_.-]+$',
-            pattern_errmsg='may only include letters, numbers, _, ., and -',
+            pattern='^[a-zA-Z0-9_.-/]+$',
+            pattern_errmsg='may only include letters, numbers, _, ., -, and /',
             maxlength=255,
         ),
         Str('container_id?',
@@ -128,7 +131,7 @@ class vaultcontainer(LDAPObject):
 
         # get container ID from parameters
         name = keys[-1]
-        parent_id = self.normalize_id(options.get('parent_id'))
+        parent_id = self.absolute_id(options.get('parent_id'))
 
         container_id = parent_id
         if name:
@@ -176,14 +179,21 @@ class vaultcontainer(LDAPObject):
         Normalizes container ID.
         """
 
+        # make sure ID ends with slash
+        if id and not id.endswith(u'/'):
+            return id + u'/'
+
+        return id
+
+    def absolute_id(self, id):
+        """
+        Generate absolute container ID.
+        """
+
         # if ID is empty, return user's private container ID
         if not id:
             return self.get_private_id()
 
-        # make sure ID ends with slash
-        if not id.endswith(u'/'):
-            id += u'/'
-
         # if it's an absolute ID, do nothing
         if id.startswith(u'/'):
             return id
@@ -203,8 +213,68 @@ class vaultcontainer(LDAPObject):
         # split ID into parent ID, container name, and empty string
         parts = id.rsplit(u'/', 2)
 
-        # return container name and parent ID
-        return (parts[1], parts[0] + u'/')
+        if len(parts) == 3:
+            container_name = parts[1]
+            parent_id = u'%s/' % parts[0]
+
+        elif len(parts) == 2:
+            container_name = parts[0]
+            parent_id = None
+
+        if not container_name:
+            container_name = None
+
+        return (container_name, parent_id)
+
+    def merge_id(self, container_name, parent_id):
+        """
+        Merges a container name and a parent ID into a container ID.
+        """
+
+        if not container_name:
+            id = parent_id
+
+        elif container_name.startswith('/') or not parent_id:
+            id = container_name
+
+        else:
+            id = parent_id + container_name
+
+        return self.normalize_id(id)
+
+    def normalize_params(self, *args, **options):
+        """
+        Normalizes the container ID in the parameters.
+        """
+
+        container_id = self.parse_params(*args, **options)
+        (container_name, parent_id) = self.split_id(container_id)
+        return self.update_params(container_name, parent_id, *args, **options)
+
+    def parse_params(self, *args, **options):
+        """
+        Extracts the container name and parent ID in the parameters.
+        """
+
+        container_name = args[0]
+        if type(container_name) is tuple:
+            container_name = container_name[0]
+        parent_id = self.normalize_id(options.get('parent_id'))
+
+        return self.merge_id(container_name, parent_id)
+
+    def update_params(self, new_container_name, new_parent_id, *args, **options):
+        """
+        Stores container name and parent ID back into the parameters.
+        """
+
+        args_list = list(args)
+        args_list[0] = new_container_name
+        args = tuple(args_list)
+
+        options['parent_id'] = new_parent_id
+
+        return (args, options)
 
     def create_entry(self, dn, owner=None):
         """
@@ -249,10 +319,14 @@ class vaultcontainer_add(LDAPCreate):
 
     msg_summary = _('Added vault container "%(value)s"')
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vaultcontainer_add, self).params_2_args_options(**params)
+        return self.obj.normalize_params(*args, **options)
+
     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
         assert isinstance(dn, DN)
 
-        parent_id = self.obj.normalize_id(options.get('parent_id'))
+        parent_id = self.obj.absolute_id(options.get('parent_id'))
 
         # set owner
         principal = getattr(context, 'principal')
@@ -279,7 +353,7 @@ class vaultcontainer_add(LDAPCreate):
 
     def handle_not_found(self, *args, **options):
 
-        parent_id = self.obj.normalize_id(options.get('parent_id'))
+        parent_id = self.obj.absolute_id(options.get('parent_id'))
 
         raise errors.NotFound(
             reason=self.obj.parent_not_found_msg % {
@@ -306,6 +380,10 @@ class vaultcontainer_del(LDAPDelete):
 
     msg_summary = _('Deleted vault container "%(value)s"')
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vaultcontainer_del, self).params_2_args_options(**params)
+        return self.obj.normalize_params(*args, **options)
+
     def pre_callback(self, ldap, dn, *keys, **options):
         assert isinstance(dn, DN)
 
@@ -335,10 +413,16 @@ class vaultcontainer_find(LDAPSearch):
         '%(count)d vault container matched', '%(count)d vault containers matched', 0
     )
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vaultcontainer_find, self).params_2_args_options(**params)
+
+        parent_id = self.obj.parse_params(*args, **options)
+        return self.obj.update_params(None, parent_id, *args, **options)
+
     def pre_callback(self, ldap, filter, attrs_list, base_dn, scope, *keys, **options):
         assert isinstance(base_dn, DN)
 
-        parent_id = self.obj.normalize_id(options.get('parent_id'))
+        parent_id = self.obj.absolute_id(options.get('parent_id'))
         (name, grandparent_id) = self.obj.split_id(parent_id)
         base_dn = self.obj.get_dn(name, parent_id=grandparent_id)
 
@@ -353,7 +437,7 @@ class vaultcontainer_find(LDAPSearch):
 
     def handle_not_found(self, *args, **options):
 
-        parent_id = self.obj.normalize_id(options.get('parent_id'))
+        parent_id = self.obj.absolute_id(options.get('parent_id'))
 
         # parent is user's private container, ignore
         if parent_id == self.obj.get_private_id():
@@ -381,6 +465,10 @@ class vaultcontainer_mod(LDAPUpdate):
 
     msg_summary = _('Modified vault container "%(value)s"')
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vaultcontainer_mod, self).params_2_args_options(**params)
+        return self.obj.normalize_params(*args, **options)
+
     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
         assert isinstance(dn, DN)
 
@@ -400,6 +488,10 @@ class vaultcontainer_show(LDAPRetrieve):
         ),
     )
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vaultcontainer_show, self).params_2_args_options(**params)
+        return self.obj.normalize_params(*args, **options)
+
     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
         assert isinstance(dn, DN)
 
@@ -422,6 +514,10 @@ class vaultcontainer_add_owner(LDAPAddMember):
     member_attributes = ['owner']
     member_count_out = ('%i owner added.', '%i owners added.')
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vaultcontainer_add_owner, self).params_2_args_options(**params)
+        return self.obj.normalize_params(*args, **options)
+
     def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
         assert isinstance(dn, DN)
 
@@ -444,6 +540,10 @@ class vaultcontainer_remove_owner(LDAPRemoveMember):
     member_attributes = ['owner']
     member_count_out = ('%i owner removed.', '%i owners removed.')
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vaultcontainer_remove_owner, self).params_2_args_options(**params)
+        return self.obj.normalize_params(*args, **options)
+
     def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
         assert isinstance(dn, DN)
 
@@ -463,6 +563,10 @@ class vaultcontainer_add_member(LDAPAddMember):
         ),
     )
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vaultcontainer_add_member, self).params_2_args_options(**params)
+        return self.obj.normalize_params(*args, **options)
+
     def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
         assert isinstance(dn, DN)
 
@@ -475,7 +579,6 @@ class vaultcontainer_add_member(LDAPAddMember):
 class vaultcontainer_remove_member(LDAPRemoveMember):
     __doc__ = _('Remove members from a vault container.')
 
-
     takes_options = LDAPRemoveMember.takes_options + (
         Str('parent_id?',
             cli_name='parent_id',
@@ -483,6 +586,10 @@ class vaultcontainer_remove_member(LDAPRemoveMember):
         ),
     )
 
+    def params_2_args_options(self, **params):
+        (args, options) = super(vaultcontainer_remove_member, self).params_2_args_options(**params)
+        return self.obj.normalize_params(*args, **options)
+
     def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
         assert isinstance(dn, DN)
 
diff --git a/ipalib/plugins/vaultsecret.py b/ipalib/plugins/vaultsecret.py
index 7f44f0816b571dac718fa02edfd187fe8666565e..de15b014ca285387c7a1730fca3e110664a3ecf2 100644
--- a/ipalib/plugins/vaultsecret.py
+++ b/ipalib/plugins/vaultsecret.py
@@ -147,7 +147,7 @@ class vaultsecret_add(LDAPRetrieve):
 
         vault_name = args[0]
         secret_name = args[1]
-        container_id = self.api.Object.vaultcontainer.normalize_id(options.get('container_id'))
+        container_id = self.api.Object.vaultcontainer.absolute_id(options.get('container_id'))
 
         vault_type = 'standard'
         salt = None
@@ -362,7 +362,7 @@ class vaultsecret_del(LDAPRetrieve):
 
         vault_name = args[0]
         secret_name = args[1]
-        container_id = self.api.Object.vaultcontainer.normalize_id(options.get('container_id'))
+        container_id = self.api.Object.vaultcontainer.absolute_id(options.get('container_id'))
 
         vault_type = 'standard'
         salt = None
@@ -539,7 +539,7 @@ class vaultsecret_find(LDAPSearch):
     def forward(self, *args, **options):
 
         vault_name = args[0]
-        container_id = self.api.Object.vaultcontainer.normalize_id(options.get('container_id'))
+        container_id = self.api.Object.vaultcontainer.absolute_id(options.get('container_id'))
 
         vault_type = 'standard'
         salt = None
@@ -716,7 +716,7 @@ class vaultsecret_mod(LDAPRetrieve):
 
         vault_name = args[0]
         secret_name = args[1]
-        container_id = self.api.Object.vaultcontainer.normalize_id(options.get('container_id'))
+        container_id = self.api.Object.vaultcontainer.absolute_id(options.get('container_id'))
 
         vault_type = 'standard'
         salt = None
@@ -946,7 +946,7 @@ class vaultsecret_show(LDAPRetrieve):
 
         vault_name = args[0]
         secret_name = args[1]
-        container_id = self.api.Object.vaultcontainer.normalize_id(options.get('container_id'))
+        container_id = self.api.Object.vaultcontainer.absolute_id(options.get('container_id'))
 
         vault_type = 'standard'
         salt = None
diff --git a/ipatests/test_xmlrpc/test_vault_plugin.py b/ipatests/test_xmlrpc/test_vault_plugin.py
index f3a280b40d5b6972e8755f63d46013cadaa68334..98e0b543d280d5bb36d5f9aae5c925019e79e962 100644
--- a/ipatests/test_xmlrpc/test_vault_plugin.py
+++ b/ipatests/test_xmlrpc/test_vault_plugin.py
@@ -34,6 +34,8 @@ asymmetric_vault = u'asymmetric_vault'
 escrowed_symmetric_vault = u'escrowed_symmetric_vault'
 escrowed_asymmetric_vault = u'escrowed_asymmetric_vault'
 
+shared_test_vault = u'/shared/%s' % test_vault
+
 password = u'password'
 
 public_key = """
@@ -158,6 +160,7 @@ class test_vault_plugin(Declarative):
         ('vault_del', [asymmetric_vault], {'continue': True}),
         ('vault_del', [escrowed_symmetric_vault], {'continue': True}),
         ('vault_del', [escrowed_asymmetric_vault], {'continue': True}),
+        ('vault_del', [shared_test_vault], {'continue': True}),
     ]
 
     tests = [
@@ -621,4 +624,152 @@ class test_vault_plugin(Declarative):
             },
         },
 
+        {
+            'desc': 'Create test vault with absolute ID',
+            'command': (
+                'vault_add',
+                [shared_test_vault],
+                {},
+            ),
+            'expected': {
+                'value': test_vault,
+                'summary': u'Added vault "%s"' % test_vault,
+                'result': {
+                    'dn': u'cn=%s,cn=shared,cn=vaults,%s' % (test_vault, api.env.basedn),
+                    'objectclass': (u'ipaVault', u'top'),
+                    'cn': [test_vault],
+                    'vault_id': shared_test_vault,
+                    'owner_user': [u'admin'],
+                    'ipavaulttype': [u'standard'],
+                },
+            },
+        },
+
+        {
+            'desc': 'Find test vaults with absolute ID',
+            'command': (
+                'vault_find',
+                [u'/shared/'],
+                {},
+            ),
+            'expected': {
+                'count': 1,
+                'truncated': False,
+                'summary': u'1 vault matched',
+                'result': [
+                    {
+                        'dn': u'cn=%s,cn=shared,cn=vaults,%s' % (test_vault, api.env.basedn),
+                        'cn': [test_vault],
+                        'vault_id': shared_test_vault,
+                        'ipavaulttype': [u'standard'],
+                    },
+                ],
+            },
+        },
+
+        {
+            'desc': 'Show test vault with absolute ID',
+            'command': (
+                'vault_show',
+                [shared_test_vault],
+                {},
+            ),
+            'expected': {
+                'value': test_vault,
+                'summary': None,
+                'result': {
+                    'dn': u'cn=%s,cn=shared,cn=vaults,%s' % (test_vault, api.env.basedn),
+                    'cn': [test_vault],
+                    'vault_id': shared_test_vault,
+                    'owner_user': [u'admin'],
+                    'ipavaulttype': [u'standard'],
+                },
+            },
+        },
+
+        {
+            'desc': 'Modify test vault with absolute ID',
+            'command': (
+                'vault_mod',
+                [shared_test_vault],
+                {
+                    'description': u'Test vault',
+                },
+            ),
+            'expected': {
+                'value': test_vault,
+                'summary': u'Modified vault "%s"' % test_vault,
+                'result': {
+                    'cn': [test_vault],
+                    'vault_id': shared_test_vault,
+                    'description': [u'Test vault'],
+                    'owner_user': [u'admin'],
+                    'ipavaulttype': [u'standard'],
+                },
+            },
+        },
+
+        {
+            'desc': 'Archive binary data with absolute ID',
+            'command': (
+                'vault_archive',
+                [shared_test_vault],
+                {
+                    'data': binary_data,
+                },
+            ),
+            'expected': {
+                'value': test_vault,
+                'summary': u'Archived data into vault "%s"' % test_vault,
+                'result': {
+                    'dn': u'cn=%s,cn=shared,cn=vaults,%s' % (test_vault, api.env.basedn),
+                    'cn': [test_vault],
+                    'vault_id': shared_test_vault,
+                    'description': [u'Test vault'],
+                    'owner_user': [u'admin'],
+                    'ipavaulttype': [u'standard'],
+                },
+            },
+        },
+
+        {
+            'desc': 'Retrieve binary data with absolute ID',
+            'command': (
+                'vault_retrieve',
+                [shared_test_vault],
+                {},
+            ),
+            'expected': {
+                'value': test_vault,
+                'summary': u'Retrieved data from vault "%s"' % test_vault,
+                'result': {
+                    'dn': u'cn=%s,cn=shared,cn=vaults,%s' % (test_vault, api.env.basedn),
+                    'cn': [test_vault],
+                    'vault_id': shared_test_vault,
+                    'description': [u'Test vault'],
+                    'owner_user': [u'admin'],
+                    'ipavaulttype': [u'standard'],
+                    'nonce': fuzzy_string,
+                    'vault_data': fuzzy_string,
+                    'data': binary_data,
+                },
+            },
+        },
+
+        {
+            'desc': 'Delete test vault with absolute ID',
+            'command': (
+                'vault_del',
+                [shared_test_vault],
+                {},
+            ),
+            'expected': {
+                'value': [test_vault],
+                'summary': u'Deleted vault "%s"' % test_vault,
+                'result': {
+                    'failed': (),
+                },
+            },
+        },
+
     ]
diff --git a/ipatests/test_xmlrpc/test_vaultcontainer_plugin.py b/ipatests/test_xmlrpc/test_vaultcontainer_plugin.py
index 22e13769df19b40cd39a144df662bae8bbf53d9e..ca96bff4dcae8c62bc44245ba82c7bf4165754e5 100644
--- a/ipatests/test_xmlrpc/test_vaultcontainer_plugin.py
+++ b/ipatests/test_xmlrpc/test_vaultcontainer_plugin.py
@@ -24,9 +24,10 @@ Test the `ipalib/plugins/vaultcontainer.py` module.
 from ipalib import api, errors
 from xmlrpc_test import Declarative
 
-private_container = u'private_container'
-shared_container = u'shared_container'
-service_container = u'service_container'
+test_container = u'test_container'
+private_container = test_container
+shared_test_container = u'/shared/%s' % test_container
+service_test_container = u'/services/%s' % test_container
 
 base_container = u'base_container'
 child_container = u'child_container'
@@ -36,8 +37,8 @@ class test_vaultcontainer_plugin(Declarative):
 
     cleanup_commands = [
         ('vaultcontainer_del', [private_container], {'continue': True}),
-        ('vaultcontainer_del', [shared_container], {'parent_id': u'/shared/', 'continue': True}),
-        ('vaultcontainer_del', [service_container], {'parent_id': u'/services/', 'continue': True}),
+        ('vaultcontainer_del', [shared_test_container], {'continue': True}),
+        ('vaultcontainer_del', [service_test_container], {'continue': True}),
         ('vaultcontainer_del', [base_container], {'force': True, 'continue': True}),
     ]
 
@@ -200,19 +201,17 @@ class test_vaultcontainer_plugin(Declarative):
             'desc': 'Create shared container',
             'command': (
                 'vaultcontainer_add',
-                [shared_container],
-                {
-                    'parent_id': u'/shared/',
-                },
+                [shared_test_container],
+                {},
             ),
             'expected': {
-                'value': shared_container,
-                'summary': 'Added vault container "%s"' % shared_container,
+                'value': test_container,
+                'summary': 'Added vault container "%s"' % test_container,
                 'result': {
-                    'dn': u'cn=%s,cn=shared,cn=vaults,%s' % (shared_container, api.env.basedn),
+                    'dn': u'cn=%s,cn=shared,cn=vaults,%s' % (test_container, api.env.basedn),
                     'objectclass': (u'ipaVaultContainer', u'top'),
-                    'cn': [shared_container],
-                    'container_id': u'/shared/%s/' % shared_container,
+                    'cn': [test_container],
+                    'container_id': u'/shared/%s/' % test_container,
                     'owner_user': [u'admin'],
                 },
             },
@@ -222,10 +221,8 @@ class test_vaultcontainer_plugin(Declarative):
             'desc': 'Find shared containers',
             'command': (
                 'vaultcontainer_find',
-                [],
-                {
-                    'parent_id': u'/shared/',
-                },
+                [u'/shared/'],
+                { },
             ),
             'expected': {
                 'count': 1,
@@ -233,9 +230,9 @@ class test_vaultcontainer_plugin(Declarative):
                 'summary': u'1 vault container matched',
                 'result': [
                     {
-                        'dn': u'cn=%s,cn=shared,cn=vaults,%s' % (shared_container, api.env.basedn),
-                        'cn': [shared_container],
-                        'container_id': u'/shared/%s/' % shared_container,
+                        'dn': u'cn=%s,cn=shared,cn=vaults,%s' % (test_container, api.env.basedn),
+                        'cn': [test_container],
+                        'container_id': u'/shared/%s/' % test_container,
                     },
                 ],
             },
@@ -245,18 +242,16 @@ class test_vaultcontainer_plugin(Declarative):
             'desc': 'Show shared container',
             'command': (
                 'vaultcontainer_show',
-                [shared_container],
-                {
-                    'parent_id': u'/shared/',
-                },
+                [shared_test_container],
+                {},
             ),
             'expected': {
-                'value': shared_container,
+                'value': test_container,
                 'summary': None,
                 'result': {
-                    'dn': u'cn=%s,cn=shared,cn=vaults,%s' % (shared_container, api.env.basedn),
-                    'cn': [shared_container],
-                    'container_id': u'/shared/%s/' % shared_container,
+                    'dn': u'cn=%s,cn=shared,cn=vaults,%s' % (test_container, api.env.basedn),
+                    'cn': [test_container],
+                    'container_id': u'/shared/%s/' % test_container,
                     'owner_user': [u'admin'],
                 },
             },
@@ -266,18 +261,17 @@ class test_vaultcontainer_plugin(Declarative):
             'desc': 'Modify shared container',
             'command': (
                 'vaultcontainer_mod',
-                [shared_container],
+                [shared_test_container],
                 {
-                    'parent_id': u'/shared/',
                     'description': u'shared container',
                 },
             ),
             'expected': {
-                'value': shared_container,
-                'summary': 'Modified vault container "%s"' % shared_container,
+                'value': test_container,
+                'summary': 'Modified vault container "%s"' % test_container,
                 'result': {
-                    'cn': [shared_container],
-                    'container_id': u'/shared/%s/' % shared_container,
+                    'cn': [test_container],
+                    'container_id': u'/shared/%s/' % test_container,
                     'description': [u'shared container'],
                     'owner_user': [u'admin'],
                 },
@@ -288,14 +282,12 @@ class test_vaultcontainer_plugin(Declarative):
             'desc': 'Delete shared container',
             'command': (
                 'vaultcontainer_del',
-                [shared_container],
-                {
-                    'parent_id': u'/shared/',
-                },
+                [shared_test_container],
+                {},
             ),
             'expected': {
-                'value': [shared_container],
-                'summary': u'Deleted vault container "%s"' % shared_container,
+                'value': [test_container],
+                'summary': u'Deleted vault container "%s"' % test_container,
                 'result': {
                     'failed': (),
                 },
@@ -306,19 +298,17 @@ class test_vaultcontainer_plugin(Declarative):
             'desc': 'Create service container',
             'command': (
                 'vaultcontainer_add',
-                [service_container],
-                {
-                    'parent_id': u'/services/',
-                },
+                [service_test_container],
+                {},
             ),
             'expected': {
-                'value': service_container,
-                'summary': 'Added vault container "%s"' % service_container,
+                'value': test_container,
+                'summary': 'Added vault container "%s"' % test_container,
                 'result': {
-                    'dn': u'cn=%s,cn=services,cn=vaults,%s' % (service_container, api.env.basedn),
+                    'dn': u'cn=%s,cn=services,cn=vaults,%s' % (test_container, api.env.basedn),
                     'objectclass': (u'ipaVaultContainer', u'top'),
-                    'cn': [service_container],
-                    'container_id': u'/services/%s/' % service_container,
+                    'cn': [test_container],
+                    'container_id': u'/services/%s/' % test_container,
                     'owner_user': [u'admin'],
                 },
             },
diff --git a/ipatests/test_xmlrpc/test_vaultsecret_plugin.py b/ipatests/test_xmlrpc/test_vaultsecret_plugin.py
index cbfd231633e7c3c000e57d52d85b83f44f71df3c..d2a4e92507fbabbcc356dc889738f151521e896c 100644
--- a/ipatests/test_xmlrpc/test_vaultsecret_plugin.py
+++ b/ipatests/test_xmlrpc/test_vaultsecret_plugin.py
@@ -25,6 +25,7 @@ from ipalib import api, errors
 from xmlrpc_test import Declarative, fuzzy_string
 
 test_vault = u'test_vault'
+shared_test_vault = u'/shared/%s' % test_vault
 test_vaultsecret = u'test_vaultsecret'
 binary_data = '\x01\x02\x03\x04'
 text_data = u'secret'
@@ -33,6 +34,7 @@ class test_vaultsecret_plugin(Declarative):
 
     cleanup_commands = [
         ('vault_del', [test_vault], {'continue': True}),
+        ('vault_del', [shared_test_vault], {'continue': True}),
     ]
 
     tests = [
@@ -208,4 +210,117 @@ class test_vaultsecret_plugin(Declarative):
             },
         },
 
+        {
+            'desc': 'Create shared test vault',
+            'command': (
+                'vault_add',
+                [shared_test_vault],
+                {},
+            ),
+            'expected': {
+                'value': test_vault,
+                'summary': 'Added vault "%s"' % test_vault,
+                'result': {
+                    'dn': u'cn=%s,cn=shared,cn=vaults,%s' % (test_vault, api.env.basedn),
+                    'objectclass': (u'ipaVault', u'top'),
+                    'cn': [test_vault],
+                    'vault_id': u'/shared/%s' % test_vault,
+                    'owner_user': [u'admin'],
+                    'ipavaulttype': [u'standard'],
+                },
+            },
+        },
+
+        {
+            'desc': 'Create shared test vault secret with binary data',
+            'command': (
+                'vaultsecret_add',
+                [shared_test_vault, test_vaultsecret],
+                {
+                    'data': binary_data,
+                },
+            ),
+            'expected': {
+                'value': test_vaultsecret,
+                'summary': 'Added vault secret "%s"' % test_vaultsecret,
+                'result': {
+                    'secret_name': test_vaultsecret,
+                    'data': binary_data,
+                },
+            },
+        },
+
+        {
+            'desc': 'Find shared vault secrets',
+            'command': (
+                'vaultsecret_find',
+                [shared_test_vault],
+                {},
+            ),
+            'expected': {
+                'count': 1,
+                'truncated': False,
+                'summary': u'1 vault secret matched',
+                'result': [
+                    {
+                        'secret_name': test_vaultsecret,
+                        'data': binary_data,
+                    },
+                ],
+            },
+        },
+
+        {
+            'desc': 'Retrieve shared test vault secret',
+            'command': (
+                'vaultsecret_show',
+                [shared_test_vault, test_vaultsecret],
+                {},
+            ),
+            'expected': {
+                'value': test_vaultsecret,
+                'summary': None,
+                'result': {
+                    'secret_name': test_vaultsecret,
+                    'data': binary_data,
+                },
+            },
+        },
+
+        {
+            'desc': 'Modify shared test vault secret',
+            'command': (
+                'vaultsecret_mod',
+                [shared_test_vault, test_vaultsecret],
+                {
+                    'description': u'Test vault secret',
+                },
+            ),
+            'expected': {
+                'value': test_vaultsecret,
+                'summary': u'Modified vault secret "%s"' % test_vaultsecret,
+                'result': {
+                    'secret_name': test_vaultsecret,
+                    'description': u'Test vault secret',
+                    'data': binary_data,
+                },
+            },
+        },
+
+        {
+            'desc': 'Delete shared test vault secret',
+            'command': (
+                'vaultsecret_del',
+                [shared_test_vault, test_vaultsecret],
+                {},
+            ),
+            'expected': {
+                'value': test_vaultsecret,
+                'summary': u'Deleted vault secret "%s"' % test_vaultsecret,
+                'result': {
+                    'failed': (),
+                },
+            },
+        },
+
     ]
-- 
1.9.0



More information about the Freeipa-devel mailing list