You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CKAN技术问询:如何实现私有数据集元数据对登录用户可见并管控资源下载权限?

实现方案

要实现登录用户查看私有数据集元数据、仅有权限用户可下载资源的需求,直接基于CKAN的插件机制修改权限逻辑即可,具体步骤如下:

1. 放开私有数据集元数据的登录用户访问权限

CKAN默认会限制非管理员/编辑用户查看私有数据集的元数据,我们通过重写package_show权限函数来调整这个逻辑:

from ckan.plugins import implements, IAuthFunctions
from ckan.logic.auth.get import package_show as original_package_show

def custom_package_show(context, data_dict):
    # 先执行原权限逻辑,保留基础校验
    result = original_package_show(context, data_dict)
    # 若用户已登录,且原逻辑判定无权限(即私有数据集),则放行元数据查看
    if not result.get('success') and context.get('user'):
        result['success'] = True
    return result

class YourCustomPlugin(object):
    implements(IAuthFunctions)
    
    def get_auth_functions(self):
        return {
            'package_show': custom_package_show
        }

注:这个修改仅放开元数据查看权限,数据集的编辑、删除等核心权限仍会遵循原逻辑。

2. 拦截无权限用户的资源下载请求

资源下载对应的核心权限是resource_download,同时要配合resource_show确保资源元数据可见但下载被限制:

from ckan.logic.auth.get import resource_show as original_resource_show
from ckan.logic.auth.get import resource_download as original_resource_download

def custom_resource_show(context, data_dict):
    result = original_resource_show(context, data_dict)
    # 登录用户默认可以查看资源元数据,不管有没有下载权限
    if context.get('user'):
        result['success'] = True
    return result

def custom_resource_download(context, data_dict):
    # 校验用户是否拥有对应数据集的编辑权限(可替换为你自定义的权限)
    resource_id = data_dict.get('id')
    resource = context['model'].Resource.get(resource_id)
    pkg = resource.package if resource else None
    
    if not pkg:
        return {'success': False, 'msg': '资源不存在'}
    
    has_permission = context['auth_user_obj'].has_permission('package_update', pkg)
    if has_permission:
        return {'success': True}
    else:
        return {'success': False, 'msg': '你没有该资源的下载权限'}

class YourCustomPlugin(object):
    implements(IAuthFunctions)
    
    def get_auth_functions(self):
        return {
            'package_show': custom_package_show,
            'resource_show': custom_resource_show,
            'resource_download': custom_resource_download
        }

3. 前端适配(可选)

为了给用户更直观的提示,可通过模板助手在前端隐藏无权限用户的下载按钮:

from ckan.plugins import implements, ITemplateHelpers
from ckan.common import c

class YourCustomPlugin(object):
    implements(ITemplateHelpers)
    
    def get_helpers(self):
        return {
            'can_download_resource': can_download_resource
        }

def can_download_resource(resource):
    pkg = resource.package
    return c.userobj.has_permission('package_update', pkg)

然后在资源列表模板(比如package/snippets/resource_item.html)中修改:

{% if h.can_download_resource(resource) %}
  <a href="{{ h.url_for(controller='package', action='resource_download', id=pkg.id, resource_id=resource.id) }}" class="btn btn-primary">下载</a>
{% else %}
  <span class="btn btn-disabled">无下载权限</span>
{% endif %}

注意事项

  • 权限判断要基于CKAN的官方auth_user_obj和model对象,不要直接操作数据库,避免破坏原有权限体系
  • 若需要更细粒度的权限控制,可以自定义一个resource_download权限,通过CKAN的权限注册机制添加后替换代码中的package_update
  • 测试时要覆盖三类场景:未登录用户、登录无权限用户、登录有权限用户,确保逻辑符合预期

内容的提问来源于stack exchange,提问作者Theo Stefou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 05:22:45