Search code examples
ckan

Is there a way to disable API tokens for non-Sysadmins in CKAN?


Basically, I want to totally disable API access for all user other than sysadmins (v2.9.1).

  1. Where in the code can I see the logic related to this? Closest I could find was via
$ grep -rnw /usr/lib/ckan/default/src/ckan -e 'api-tokens'
/usr/lib/ckan/default/src/ckan/ckan/views/user.py
/usr/lib/ckan/default/src/ckan/doc/api/index.rst
/usr/lib/ckan/default/src/ckan/doc/maintaining/configuration.rst

The ...user.py file appears to be based on Django, but not much experience w/ that framework to really know what should be changed here. Any other places to look?

  1. Is there a way to create API tokens for users (eg. selected sysadmins) via the ckan CLI?

Solution

  • Currently just hiding the API token generation tab from non sysadmin users in the web UI html (https://github.com/ckan/ckan/blob/cc000d3acf7401957d8321be53e8cabc2d9ebf3a/ckan/templates/user/api_tokens.html) by a similar mechanism that html templates can control visibility of the Visibility functionality of packages here (https://github.com/ckan/ckan/blob/master/ckan/templates/package/snippets/package_basic_fields.html#L72)...

    {% set user_is_sysadmin = h.check_access('sysadmin') %}
    {% block page_primary_action %}
            {% if user_is_sysadmin %}
    
                {% if h.check_access('api_token_create', {'user': user['name']}) %}
                .
                .
                .
                {% endif %}
            {% endif %}
    {% endblock page_primary_action %}
    

    Note that it is important to put the conditional inside the block tag templates (was not working elsewise and confused me for some time). This is (seems to be) due to the fact the the API tokens tab jinja2 template is an extension (child?) of the user/read_base.html template (https://github.com/ckan/ckan/blob/cc000d3acf7401957d8321be53e8cabc2d9ebf3a/ckan/templates/user/api_tokens.html#L1).

    IDK if generating tokens is possible via public API. For that would need to inspect the files that seem to be related to API token creation via API:

    Will update post after checking these.


    UPDATE:

    https://github.com/ckan/ckan/blob/d43ce9bfd882f63c986711e2d59e186a58c8e489/ckan/logic/auth/create.py#L258 can be modified to something like...

    def api_token_create(context, data_dict):
        """
        Create new token for current user.
        """
        user = context['model'].User.get(data_dict['user'])
        return {'success': (user.name == context['user']) and (authz.is_sysadmin(user.name))}
    

    ...which should limit/restrict (https://docs.ckan.org/en/2.9/contributing/architecture.html?highlight=architecture#auth-functions-and-check-access) API access.

    Making this change also (I'd think solely, since that seems to be the only thing the api_token_create (https://github.com/ckan/ckan/blob/d43ce9bfd882f63c986711e2d59e186a58c8e489/ckan/logic/auth/create.py#L258) is used for) hides the API token creation tab in the user's profile mgmt screen (https://github.com/ckan/ckan/blob/cc000d3acf7401957d8321be53e8cabc2d9ebf3a/ckan/templates/user/api_tokens.html#L6). (So could get rid of the code doing the conditional checks inside of the block template).