2022年5月3日 星期二

CKAN Extensions Tutorial(v2.9): 實作 IAuthFunctions 自訂授權規則

https://docs.ckan.org/en/2.9/extensions/tutorial.html#implementing-the-iauthfunctions-plugin-interface

CKAN 提供許多 plugin interfaces(v2.9) 以便掛勾/hook 到 CKAN 修改或擴充功能:

  • u'Interface',
  • u'IRoutes',
  • u'IMapper',
  • u'ISession',
  • u'IMiddleware',
  • u'IAuthFunctions',
  • u'IDomainObjectModification',
  • u'IFeed',
  • u'IGroupController',
  • u'IOrganizationController',
  • u'IPackageController',
  • u'IPluginObserver',
  • u'IConfigurable',
  • u'IConfigurer',
  • u'IActions',
  • u'IResourceUrlChange',
  • u'IDatasetForm',
  • u'IValidators',
  • u'IResourcePreview',
  • u'IResourceView',
  • u'IResourceController',
  • u'IGroupForm',
  • u'ITagController',
  • u'ITemplateHelpers',
  • u'IFacets',
  • u'IAuthenticator',
  • u'ITranslation',
  • u'IUploader',
  • u'IBlueprint',
  • u'IPermissionLabels',
  • u'IForkObserver',
  • u'IApiToken',
  • u'IClick',

CKAN 如何驗證

參考: plugin interfaces。凡可透過 CKAN web 介面或 API 呼叫的動作都是以 ckan/logic/action/{create,delete,get,update}.py 實作的 action function。

例如資料集相關的 Web API 便對應到:

  • func:`ckan.logic.action.create.package_create`
  • func:`ckan.logic.action.get.package_show`
  • func:`ckan.logic.action.update.package_update`
  • func:`ckan.logic.action.delete.package_delete`

每個 action function 都有對應的 authorization function (ckan/logic/auth/{create,delete,get,update}.py),CKAN 呼叫 authorization function 決定使用者是否有被授權執行。

實作 ckan.plugins.interfaces.IAuthFunctions,並註冊與 CKAN 同名的 authorization function,如:'user_create', 'group_create',即可覆寫 CKAN 的授權規則。

在 CKAN 呼叫 authorization function 之前,會先驗證呼叫端是否提供合法的 API key。若要允許匿名執行, authorization function 需標示為 auth_allow_anonymous_access。如:

            @p.toolkit.auth_allow_anonymous_access
            def my_search_action(context, data_dict):
                略⋯⋯

IAuthFunctions

實作 ckan.plugins.interfaces.IAuthFunctions。所有 authorization function 都有兩個參數:

  • context
    • model: 可用來查詢資料庫
    • user: 內容使用者的 名稱/IP(匿名存取)
    • auth_user_obj: model.User物件/None(匿名存取)
  • data_dict
    • CKAN 會傳給所有 authorization and action functions data_dict,內容所有 post 進來的資料,可能是網頁中填寫的表單欄位內容,或 API 呼叫傳入的 JSON 內容如:
{'description': u'A really cool group',
 'image_url': u'',
 'name': u'my_group',
 'title': u'My Group',
 'type': 'group',
 'users': [{'capacity': 'admin', 'name': u'seanh'}]}

回傳 dictionary:

  • {'success': True} 授權
  • {'success': False} 拒絕

範例如下:

def user_create(context, data_dict=None):
  if (some condition):
    return {'success': True}
  else:
    return {'success': False, 'msg': 'Not allowed to register'}


實作 Iauthfunctions 不允許建立 group

建立 ckanext-iauthfunctions

參考 CKAN Extensions Tutorial(v2.9):一個空的 CKAN extension ,接續往下做。

修改 plugin.py:撰寫 plugin 類別

import ckan.plugins as plugins

def group_create(context, data_dict=None):
    return {'success': False, 'msg': '[ExampleIAuthFunctionsPlugin]-No one is allowed to create groups'}

class ExampleIAuthFunctionsPlugin(plugins.SingletonPlugin):
    plugins.implements(plugins.IAuthFunctions)

    def get_auth_functions(self):
        return {'group_create': group_create}

安裝

    1. 進入Python Virtual Environment:
      . /usr/lib/ckan/default/bin/activate
    2. 編輯 setup.py
      cd /usr/lib/ckan/default/src/ckanext-iauthfunctions
      vi setup.py 內容如下:
    3. entry_points='''
          [ckan.plugins]
          example_iauthfunctions=ckanext.iauthfunctions.plugin:ExampleIAuthFunctionsPlugin
    4. 安裝 Plugin:
      python setup.py develop
    5. 修改 ckan.ini
      vi /etc/ckan/default/ckan.ini
      ckan.plugins = stats text_view 略... example_iauthfunctions
    6. 重啟 CKAN 服務:
      sudo supervisorctl restart ckan-uwsgi:*

    測試

    1. 準備一個非管理者的使用,取得其 API Key。
      (系統管理者不受權限控管)
    2. 開 Postman 執行 api 呼叫
    curl POST 'http://[CKAN web site]/api/3/action/group_create
    --header 'Authorization: [測試者的API Key]
    --header 'Content-Type: application/json' 
    --data-raw '{
        "name": "0506-Group",
        "owner_org": "0427-org",
        "description": "test ckanext-iauthfunctions2"    
    }'

    回傳:

    {
        "error": {
            "__type": "Authorization Error",
            "message": "拒絕存取: No one is allowed to create groups[ExampleIAuthFunctionsPlugin]"
        },
        "help": "...",
        "success": false
    }

    沒有留言:

    張貼留言