Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Listing API tokens with CKAN CLI runs into error if token has already been used #6789

@wolfm89

Description

@wolfm89

CKAN version
2.9.5 (Python 2.7.13)
Describe the bug
When using the CKAN CLI to run ckan user token list default and there is an existing token that has been accessed before, then the CKAN CLI throws an exception: TypeError: isoformat() argument 1 must be char, not unicode.

Steps to reproduce
Run CKAN, create API token for user default, use this token at least once, run ckan user token list default.

Expected behavior
All API tokens for the default user should be listed.

Additional details
The full exception looks like this:

ckan@f858a3d49658:/$ ckan --config "${CKAN_CONFIG}/production.ini" user token list default
2022-04-01 15:01:44,626 INFO  [ckan.cli] Using configuration file /etc/ckan/production.ini
2022-04-01 15:01:44,626 INFO  [ckan.config.environment] Loading static files from public
2022-04-01 15:01:44,675 INFO  [ckan.config.environment] Loading templates from /usr/lib/ckan/venv/src/ckan/ckan/templates
2022-04-01 15:01:45,019 INFO  [ckan.config.environment] Loading templates from /usr/lib/ckan/venv/src/ckan/ckan/templates
Tokens([id] name - lastAccess):
        [DiJpgRiMDnPVrFU8PN9X6lO0D46n_qTzRerLvfNThDSoFZXlb3N_tCqYDMrLeuhkJ9Xz3R458TuvS54m] default_token_1648824584 - Never
Traceback (most recent call last):
  File "/usr/local/bin/ckan", line 11, in <module>
    load_entry_point('ckan', 'console_scripts', 'ckan')()
  File "/usr/lib/ckan/venv/local/lib/python2.7/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/ckan/venv/local/lib/python2.7/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/usr/lib/ckan/venv/local/lib/python2.7/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/lib/ckan/venv/local/lib/python2.7/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/lib/ckan/venv/local/lib/python2.7/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/lib/ckan/venv/local/lib/python2.7/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/lib/ckan/venv/local/lib/python2.7/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/usr/lib/ckan/venv/src/ckan/ckan/cli/user.py", line 244, in list_tokens
    accessed.second).isoformat(u" ")
TypeError: isoformat() argument 1 must be char, not unicode

The issue seems to be in ckan/cli/user.py:

@token.command(u"list")
@click.argument(u"username")
def list_tokens(username):
    u"""List all API Tokens for the given user"""
    try:
        tokens = plugin.toolkit.get_action(u"api_token_list")(
            {u"ignore_auth": True}, {u"user": username}
        )
    except plugin.toolkit.ObjectNotFound as e:
        error_shout(e)
        raise click.Abort()
    if not tokens:
        click.secho(u"No tokens have been created for user yet", fg=u"red")
        return
    click.echo(u"Tokens([id] name - lastAccess):")

    for token in tokens:
        last_access = token[u"last_access"]
        if last_access:
            accessed = plugin.toolkit.h.date_str_to_datetime(last_access)
            if six.PY2:
                """
                Strip out microseconds to force formatting as isoformat doesnt
                have a timespec param on Python 2.
                """
                accessed = datetime(
                    accessed.year,
                    accessed.month,
                    accessed.day,
                    accessed.hour,
                    accessed.minute,
                    accessed.second).isoformat(u" ")
            else:
                accessed = accessed.isoformat(u" ", u"seconds")

        else:
            accessed = u"Never"
        click.echo(
            u"\t[{id}] {name} - {accessed}".format(
                name=token[u"name"], id=token[u"id"], accessed=accessed
            )
        )

According to the documentation isoformat() expects this:

The optional argument sep (default 'T') is a one-character separator, placed between the date and time portions of the result.

Which u" " isn't.

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions