Ejemplo n.º 1
0
def owner_org_validator(key, data, errors, context):

    value = data.get(key)

    if value is missing or value is None:
        if not authz.check_config_permission('create_unowned_dataset'):
            raise Invalid(_('An organization must be provided'))
        data.pop(key, None)
        raise df.StopOnError

    model = context['model']
    user = context['user']
    user = model.User.get(user)
    package = context.get('package')

    if value == '':
        if not authz.check_config_permission('create_unowned_dataset'):
            raise Invalid(_('An organization must be provided'))
        return

    if (authz.check_config_permission('allow_dataset_collaborators')
            and not authz.check_config_permission(
                'allow_collaborators_to_change_owner_org')):

        if package and user and not user.sysadmin:
            is_collaborator = authz.user_is_collaborator_on_dataset(
                user.id, package.id, ['admin', 'editor'])
            if is_collaborator:
                # User is a collaborator, check if it's also a member with
                # edit rights of the current organization (redundant, but possible)
                user_orgs = logic.get_action('organization_list_for_user')(
                    {
                        'ignore_auth': True
                    }, {
                        'id': user.id,
                        'permission': 'update_dataset'
                    })
                user_is_org_member = package.owner_org in [
                    org['id'] for org in user_orgs
                ]
                if data.get(
                        key) != package.owner_org and not user_is_org_member:
                    raise Invalid(
                        _('You cannot move this dataset to another organization'
                          ))

    group = model.Group.get(value)
    if not group:
        raise Invalid(_('Organization does not exist'))
    group_id = group.id

    if not package or (package and package.owner_org != group_id):
        # This is a new dataset or we are changing the organization
        if not context.get(u'ignore_auth', False) and not (
                user.sysadmin or authz.has_user_permission_for_group_or_org(
                    group_id, user.name, 'create_dataset')):
            raise Invalid(_('You cannot add a dataset to this organization'))

    data[key] = group_id
Ejemplo n.º 2
0
def package_update(context, data_dict):
    model = context['model']
    user = context.get('user')

    package = logic_auth.get_package_object(context, data_dict)
    if package.owner_org:
        # if there is an owner org then we must have update_dataset
        # permission for that organization
        check1 = authz.has_user_permission_for_group_or_org(
            package.owner_org, user, 'update_dataset')
    else:
        # If dataset is not owned then we can edit if config permissions allow
        if authz.auth_is_anon_user(context):
            check1 = all(
                authz.check_config_permission(p) for p in (
                    'anon_create_dataset',
                    'create_dataset_if_not_in_organization',
                    'create_unowned_dataset',
                ))
        else:
            check1 = all(
                authz.check_config_permission(p) for p in (
                    'create_dataset_if_not_in_organization',
                    'create_unowned_dataset',
                )) or authz.has_user_permission_for_some_org(
                    user, 'create_dataset')

    if not check1:
        success = False
        if authz.check_config_permission('allow_dataset_collaborators'):
            # if org-level auth failed, check dataset-level auth
            # (ie if user is a collaborator)
            user_obj = model.User.get(user)
            if user_obj:
                success = authz.user_is_collaborator_on_dataset(
                    user_obj.id, package.id, ['admin', 'editor'])
        if not success:
            return {
                'success':
                False,
                'msg':
                _('User %s not authorized to edit package %s') %
                (str(user), package.id)
            }
    else:
        check2 = _check_group_auth(context, data_dict)
        if not check2:
            return {
                'success':
                False,
                'msg':
                _('User %s not authorized to edit these groups') % (str(user))
            }

    return {'success': True}
Ejemplo n.º 3
0
def restricted_check_user_resource_access(user,
                                          resource_dict,
                                          package_dict,
                                          user_obj=None,
                                          check_access_package_show=True,
                                          user_organization_dict={}):
    # Check access to package
    if check_access_package_show:
        logic.check_access('package_show', {'user': user},
                           {'id': package_dict['id']})

    restricted_dict = restricted_get_restricted_dict(resource_dict)

    if user:
        if user_obj:
            user_id = user_obj.id
        else:
            user_id = toolkit.get_action('user_show')({
                'ignore_auth': True
            }, {
                'id': user
            })['id']
        if authz.user_is_collaborator_on_dataset(user_id, package_dict['id']):
            return {'success': True}

    restricted_level = restricted_dict.get('level', 'restricted')
    allowed_users = restricted_dict.get('allowed_users', [])
    allowed_organizations = restricted_dict.get('allowed_organizations', [])
    # Public resources
    if restricted_level == 'public':
        return {'success': True}
    # Registered user
    if not user:
        return {
            'success': False,
            'msg': 'Resource access restricted to registered users'
        }
    # Since we have a user, check if it is in the allowed list
    if user in allowed_users:
        return {'success': True}

    if not user_organization_dict:
        user_organization_dict = get_organization_dict(user_id)

    pkg_organization_id = package_dict.get('owner_org', '')
    # Same Organization Members
    for org_id, org_name in user_organization_dict.items():
        if org_id != "" and (org_id == pkg_organization_id
                             or org_name in allowed_organizations):
            return {'success': True}
    return {'success': False, 'msg': ('Resource access restricted')}
Ejemplo n.º 4
0
def auth_resource_show(context, data_dict):
    """
    if the grace period is set and the user does not belong to collaborators
     --> do not allow access
    :return:
    """
    resource = data_dict.get('resource', context.get('resource', {}))
    if not resource:
        resource = logic_auth.get_resource_object(context, data_dict)
    if type(resource) is not dict:
        resource = resource.as_dict()

    pkg_id = resource.get('package_id')

    # Basic check:
    # Ensure user who can edit the package can see the resource
    if authz.is_authorized('package_update', context, {
            'id': pkg_id
    }).get('success'):
        return {'success': True}

    # If the user is not authorized, deny access
    auth = authz.is_authorized('package_show', context, {'id': pkg_id})
    if not auth.get('success', False):
        return {
            'success': False,
            'msg': _('User {} not authorized to read resource').format(g.user)
        }

    # The user is authorized so far: now check for grace period
    # If there are not grace period constraints, the resource is allowed
    if is_allowed_by_grace_period(resource):
        return {'success': True}

    # We are within grace period.
    # Owner and admins have already been granted access (because they can update the package)
    # Allow read-only collaborators to access the resource
    if g.userobj and \
            authz.check_config_permission('allow_dataset_collaborators') and \
            authz.user_is_collaborator_on_dataset(g.userobj.id, pkg_id):
        return {'success': True}

    return {
        'success':
        False,
        'msg':
        _('User {} not authorized to read resource in its grace period').
        format(g.userobj.name if g.userobj else '-Anonymous-')
    }
Ejemplo n.º 5
0
    def _is_resource_available(self, pkg, res):
        if 'available_since' in res:
            try:
                dt = datetime.strptime(res['available_since'], '%Y.%m.%d')
            except ValueError:
                is_available = False
            else:
                is_available = dt > datetime.now()

                # https://docs.ckan.org/en/2.9/maintaining/authorization.html#dataset-collaborators
                if is_available and \
                        authz.check_config_permission('allow_dataset_collaborators'):
                    is_available = authz.user_is_collaborator_on_dataset(
                        g.userobj.id, pkg['id'])
        else:
            is_available = True
        return is_available