Repository: ckan/ckan

Issue:
Problem adding datasets to a group on package_create, the user has 'Editor' capacity
### CKAN Version if known (or site URL)
Found in 2.2.2 and later

### Please describe the expected behaviour
I manage a customized CKAN for a client. The create dataset page is changed in a way it is possible to add all metadata to a dataset on 'package_create'. Also it should be possible to add the dataset direktly to  groups. The user has the capacity 'Editor' on the group.

### Please describe the actual behaviour
The auth function 'package_create' always does the `check2 = _check_group_auth(context,data_dict)`, which is a different approach than in 'package_update' auth function.
That leads to using the call to `authz.has_user_permission_for_group_or_org(group.id, user, 'update')`.
Later this leads to a comparison of permission '**update**' with the permissions of 'Editor' role  ('editor', ['read', 'delete_dataset', 'create_dataset', 'update_dataset', 'manage_group']). 
`if 'admin' in perms or permission in perms:
            return True`
In my opinion this can never be true and thus is bug.

Could you please check this?

Regards,
Daniel




Discussion:
Since CKAN 2.2 the available roles for Group members are `Admin` and `Member`. Perhaps this was migrated from an even older CKAN version. Can you try and manually change the entries for `editor` to `admin` on the `member` and `member_revision` tables and see if that helps? Make sure to do a backup and if you also are using organizations you should only update rows related to groups, not orgs.

Indeed we migrated from CKAN 1.8 to 2.2.2. The only documentation I could find is 

> Organizations and authorization

 at http://docs.ckan.org/en/ckan-2.2.3/authorization.html. It mainly speaks about organizations but groups are mentioned and as organizations are groups, why should it be different? Anyway having admin rights for every user on every group is not what we want. It should be possible to add datasets to groups without being able to modify the group metadata or delete it. 
It remains strange that the originally mentioned `authz.has_user_permission_for_group_or_org(group.id, user, 'update')` never evaluate to true at
`if 'admin' in perms or permission in perms` with the possible `perms` 
```
ROLE_PERMISSIONS = OrderedDict([
    ('admin', ['admin']),
    ('editor', ['read', 'delete_dataset', 'create_dataset', 'update_dataset', 'manage_group']),
    ('member', ['read', 'manage_group']),
])
```
runtime example:
`if 'admin' in ['read', 'delete_dataset', 'create_dataset', 'update_dataset', 'manage_group'] or 'update' in ['read', 'delete_dataset', 'create_dataset', 'update_dataset', 'manage_group']`

Another problem seems to be `def _check_group_auth(context, data_dict):` in ckan/logic/auth/create.py called on package_update.
In all cases I can reproduce, the block
```
    if pkg:
        pkg_groups = pkg.get_groups()

        groups = groups - set(pkg_groups)
``` 
removes all groups from the package and returns always true.
@amercader  This line was added [long time ago](https://github.com/ckan/ckan/blob/de9eeaeef74343e37757996f2410a66955dfc4ec/ckan/new_authz.py#L63-L67) and now it not actual. I think, that we should change `update` to `manage_group` in this check, so that users, who are members of group will be able to add dataset into it(member has this permission). And in that case we avoid giving permission to edit group metadata with adding new datasets.
PS
I've created pull request with small fix slightly related to this situation - #3351 - if you don't mind, i can change permission check there as well

Resolving patch:
diff --git a/ckan/logic/auth/create.py b/ckan/logic/auth/create.py
--- a/ckan/logic/auth/create.py
+++ b/ckan/logic/auth/create.py
@@ -195,7 +195,7 @@ def _check_group_auth(context, data_dict):
         groups = groups - set(pkg_groups)
 
     for group in groups:
-        if not authz.has_user_permission_for_group_or_org(group.id, user, 'update'):
+        if not authz.has_user_permission_for_group_or_org(group.id, user, 'manage_group'):
             return False
 
     return True


Test patch: