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
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}
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')}
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-') }
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