Set permissions for the given path

    .. versionadded:: 2019.2.0

    Args:

        obj_name (str):
            The name or full path to the object

        obj_type (Optional[str]):
            The type of object for which to check permissions. Default is 'file'

        grant_perms (dict):
            A dictionary containing the user/group and the basic permissions to
            grant, ie: ``{'user': {'perms': 'basic_permission'}}``. You can also
            set the ``applies_to`` setting here. The default for ``applise_to``
            is ``this_folder_subfolders_files``. Specify another ``applies_to``
            setting like this:

            .. code-block:: yaml

                {'user': {'perms': 'full_control', 'applies_to': 'this_folder'}}

            To set advanced permissions use a list for the ``perms`` parameter,
            ie:

            .. code-block:: yaml

                {'user': {'perms': ['read_attributes', 'read_ea'], 'applies_to': 'this_folder'}}

            To see a list of available attributes and applies to settings see
            the documentation for salt.utils.win_dacl.

            A value of ``None`` will make no changes to the ``grant`` portion of
            the DACL. Default is ``None``.

        deny_perms (dict):
            A dictionary containing the user/group and permissions to deny along
            with the ``applies_to`` setting. Use the same format used for the
            ``grant_perms`` parameter. Remember, deny permissions supersede
            grant permissions.

            A value of ``None`` will make no changes to the ``deny`` portion of
            the DACL. Default is ``None``.

        inheritance (bool):
            If ``True`` the object will inherit permissions from the parent, if
            ``False``, inheritance will be disabled. Inheritance setting will
            not apply to parent directories if they must be created. Default is
            ``False``.

        reset (bool):
            If ``True`` the existing DCL will be cleared and replaced with the
            settings defined in this function. If ``False``, new entries will be
            appended to the existing DACL. Default is ``False``.

    Returns:
        bool: True if successful

    Raises:
        CommandExecutionError: If unsuccessful

    Usage:

    .. code-block:: bash

        import salt.utils.win_dacl

        # To grant the 'Users' group 'read & execute' permissions.
        salt.utils.win_dacl.set_perms(obj_name='C:\\Temp',
                                      obj_type='file',
                                      grant_perms={
                                          'Users': {
                                              'perms': 'read_execute'
                                          }
                                      })

        # Specify advanced attributes with a list
        salt.utils.win_dacl.set_perms(obj_name='C:\\Temp',
                                      obj_type='file',
                                      grant_perms={
                                          'jsnuffy': {
                                              'perms': [
                                                  'read_attributes',
                                                  'read_ea'
                                              ],
                                              'applies_to': 'this_folder_only'
                                          }
                                      }"

def set_perms(obj_name,
              obj_type='file',
              grant_perms=None,
              deny_perms=None,
              inheritance=True,
              reset=False):
    '''
    Set permissions for the given path

    .. versionadded:: 2019.2.0

    Args:

        obj_name (str):
            The name or full path to the object

        obj_type (Optional[str]):
            The type of object for which to check permissions. Default is 'file'

        grant_perms (dict):
            A dictionary containing the user/group and the basic permissions to
            grant, ie: ``{'user': {'perms': 'basic_permission'}}``. You can also
            set the ``applies_to`` setting here. The default for ``applise_to``
            is ``this_folder_subfolders_files``. Specify another ``applies_to``
            setting like this:

            .. code-block:: yaml

                {'user': {'perms': 'full_control', 'applies_to': 'this_folder'}}

            To set advanced permissions use a list for the ``perms`` parameter,
            ie:

            .. code-block:: yaml

                {'user': {'perms': ['read_attributes', 'read_ea'], 'applies_to': 'this_folder'}}

            To see a list of available attributes and applies to settings see
            the documentation for salt.utils.win_dacl.

            A value of ``None`` will make no changes to the ``grant`` portion of
            the DACL. Default is ``None``.

        deny_perms (dict):
            A dictionary containing the user/group and permissions to deny along
            with the ``applies_to`` setting. Use the same format used for the
            ``grant_perms`` parameter. Remember, deny permissions supersede
            grant permissions.

            A value of ``None`` will make no changes to the ``deny`` portion of
            the DACL. Default is ``None``.

        inheritance (bool):
            If ``True`` the object will inherit permissions from the parent, if
            ``False``, inheritance will be disabled. Inheritance setting will
            not apply to parent directories if they must be created. Default is
            ``False``.

        reset (bool):
            If ``True`` the existing DCL will be cleared and replaced with the
            settings defined in this function. If ``False``, new entries will be
            appended to the existing DACL. Default is ``False``.

    Returns:
        bool: True if successful

    Raises:
        CommandExecutionError: If unsuccessful

    Usage:

    .. code-block:: bash

        import salt.utils.win_dacl

        # To grant the 'Users' group 'read & execute' permissions.
        salt.utils.win_dacl.set_perms(obj_name='C:\\Temp',
                                      obj_type='file',
                                      grant_perms={
                                          'Users': {
                                              'perms': 'read_execute'
                                          }
                                      })

        # Specify advanced attributes with a list
        salt.utils.win_dacl.set_perms(obj_name='C:\\Temp',
                                      obj_type='file',
                                      grant_perms={
                                          'jsnuffy': {
                                              'perms': [
                                                  'read_attributes',
                                                  'read_ea'
                                              ],
                                              'applies_to': 'this_folder_only'
                                          }
                                      }"
    '''
    ret = {}

    if reset:
        # Get an empty DACL
        obj_dacl = dacl(obj_type=obj_type)

        # Get an empty perms dict
        cur_perms = {}

    else:
        # Get the DACL for the directory
        obj_dacl = dacl(obj_name, obj_type=obj_type)

        # Get current file/folder permissions
        cur_perms = get_permissions(obj_name=obj_name, obj_type=obj_type)

    # Set 'deny' perms if any
    if deny_perms is not None:
        ret['deny'] = _set_perms(obj_dacl=obj_dacl,
                                 obj_type=obj_type,
                                 new_perms=deny_perms,
                                 cur_perms=cur_perms,
                                 access_mode='deny')

    # Set 'grant' perms if any
    if grant_perms is not None:
        ret['grant'] = _set_perms(obj_dacl=obj_dacl,
                                  obj_type=obj_type,
                                  new_perms=grant_perms,
                                  cur_perms=cur_perms,
                                  access_mode='grant')

    # Order the ACL
    obj_dacl.order_acl()

    # Save the DACL, setting the inheritance
    # you have to invert inheritance because dacl.save is looking for
    # protected. protected True means Inherited False...

    if obj_dacl.save(obj_name, not inheritance):
        return ret

    return {}