@adobe/aio-cli-plugin-ims

The IMS plugin to aio supports managing tokens for IMS such as login, logout, and retrieving and using tokens.

Usage no npm install needed!

<script type="module">
  import adobeAioCliPluginIms from 'https://cdn.skypack.dev/@adobe/aio-cli-plugin-ims';
</script>

README

aio-cli-plugin-ims

The IMS plugin to aio supports managing tokens for IMS such as login, logout, and retrieving and using tokens.

oclif Version Downloads/week Build Status License Codecov Coverage

Motivation

IMS integration for authentication and subsequent use of the CLI for service access is critical to the success of the CLI. To that avail, this functionality needs to be as complete as to support anything the browser UI supports as well. In the end, this means support for logging in not only with JWT tokens for technical accounts but also leveraging the SUSI flow for three-legged user based authentication and even, at least for Adobe internal teams, with service tokens.

The current JWT Auth Plugin for the Adobe I/O CLI does a decent job supporting JWT based flows with some limitations, though:

  • Only a single configuration is supported, thus not allowing to switch for different configurations and thus different setups depending on the actual CLI task at hand. Even with the new local configuration support we are still limited to one configuration per local environment.
  • The configuration contains a lot of boiler plate data, which is the same for many configurations. This also makes the configuration hard to manage.
  • Only JWT tokens are supported. So we are missing real user tokens created using the SUSI UI based flow as well as service tokens, which are sometimes used by Adobe internal teams.
  • The actual JWT signing and token exchange are not easily re-usable outside of the CLI plugin.

Goals

So the goal of this project along with the companion repositories is to provide more complete support:

  • Have a separate module implementing a JavaScript interface to the IMS API, so that this IMS API can be leveraged from multiple places, inside of the Adobe I/O CLI IMS Plugins or outside.
  • Store as little information in the configuration data as possible. This boils down to the absolutely needed fields, such as client_id, client_secret, private_key etc. The boilerplate, such as the bulk of the JWT token should be provided dynamically.
  • The plugins should support all three of the login mechanism: SUSI/UI based for user token, JWT based (technical/utility) user tokens, as well as Adobe-internal service tokens.

The JavaScript Packages

Without much further ado, here is the collection of IMS supporting plugins:

  • The Adobe I/O Lib Core IMS Support Library is the reusable base library providing JavaScript level API to the IMS APIs as well as getting access to tokens. All the functionality of this library is available by simply requiring this library.
  • This Adobe I/O CLI IMS Plugin is the main CLI plugin to the Adobe IO CLI. See #plugin for more details below.
  • Three extension to the Adobe IO IMS Support Library supporting creation of IMS tokens for different use cases. They all come as node packages. They are used by the Adobe IO IMS Support Library to implement the access token creation. The plugins are:

How it works

This Adobe IO CLI IMS Plugin offers four commands:

  • login to create and return IMS access tokens. Since tokens are cached in the Adobe IO CLI configuration, an actual token is only created if the currently cached token has already expired (or is about to expire within 10 minutes).
  • logout invalidate cached tokens and remove them from the cache. Besides the access token, this can also be used to invalidate any refresh token that may be cached.
  • ctx to manage configuration contexts.
  • plugins to manage configuration contexts.
  • profile, organizations, and session to retrieve respective IMS information
  • Low level get and post to directly call IMS API using raw HTTP GET and POST requests.

PS

Oh, and yes, docs and tests are a bit lacking this time ... I want to just get this out ASAP for anyone to have a look.

Usage

$ aio plugins:install -g @adobe/aio-cli-plugin-ims
$ # OR
$ aio discover -i
$ aio ims --help

Commands

aio ims

IMS commands to login and logout.

USAGE
  $ aio ims

DESCRIPTION
  The main commands are ims:login to get or create an access token and
  ims:logout to invalidate an access token and thus log out from IMS.

  Logging in and out is based on configuration of which there may be
  multiple. Each set of configuration properties, called an IMS context,
  can be individually addressed by a label.

  Configuration for the IMS commands is stored in the "ims"
  configuration property. The special property "ims.config.current" contains the
  label of the current configuration which can be set using the
  "aio ims ctx -s <label>" command.

  Each set of properties in labeled IMS context configurations has
  configuration properties depending on the kind of access that is
  supported. The below example shows the configuration for OAuth2
  based (graphical SUSI) login.

  The "env" property is mandatory and designates the IMS environment
  used for authentication. Possible values are "stage" and "prod".
  If the property is missing or any other value, it defaults to "stage".

  All commands allow their normal output to be formatted in either
  HJSON (default), JSON, or YAML.

EXAMPLE
  {
       ims: {
         contexts: {
           postman: {
             env: "stage",
             callback_url: "https://callback.example.com",
             client_id: "example.com-client-id",
             client_secret: "XXXXXXXX",
             scope: "openid AdobeID additional_info.projectedProductContext read_organizations",
             state: ""
           }
         },
         config: {
           current: "postman"
         }
       }
     }

See code: src/commands/ims/index.js

aio ims:ctx

Manage IMS contexts.

USAGE
  $ aio ims:ctx

OPTIONS
  -c, --ctx=ctx  Name of the IMS context to use. Default is the current IMS context
  -g, --global   global config
  -l, --local    local config
  -s, --set=set  Sets the name of the current IMS context
  -v, --verbose  Verbose output
  --debug=debug  Debug level output
  --list         Names of the IMS contexts as an array
  --value        Prints named or current IMS context data

DESCRIPTION
  The following options exist for this command:

  * List the names of the configured IMS contexts
  * Print the name of the current IMS context
  * Set the name of the current IMS context
  * Print the configuration of the current or a named IMS context

  Currently it is not possible to update the IMS context configuration
  using this command. Use the "aio config" commands for this.

  Please note, that the following IMS context label names is reserved: `cli`
  and should not be used as an IMS context name.

  Also note that the current context can only be set locally.

See code: src/commands/ims/ctx.js

aio ims:get API

Call an IMS API using a GET request

USAGE
  $ aio ims:get API

ARGUMENTS
  API  The IMS API to call, for example: /ims/profile/v1

OPTIONS
  -c, --ctx=ctx    Name of the IMS context to use. Default is the current IMS context
  -d, --data=data  Request parameter in the form of name=value. Repeat for multiple parameters
  -g, --global     global config
  -l, --local      local config
  -v, --verbose    Verbose output
  --debug=debug    Debug level output

DESCRIPTION
  This is a raw and low level IMS API call command taking the IMS API
  path as the first argument and any additional request parameters
  as optional additional arguments.

  The API result is printed as an object if successful. If the call
  fails, the error message is returned as an error.

See code: src/commands/ims/get.js

aio ims:login

Log in with a certain IMS context and returns the access token.

USAGE
  $ aio ims:login

OPTIONS
  -c, --ctx=ctx  Name of the IMS context to use. Default is the current IMS context
  -d, --decode   Decode and display access token data

  -f, --force    Force logging in. This causes a forced logout on the context first and makes sure to not use any cached
                 data when calling the plugin.

  -g, --global   global config

  -l, --local    local config

  -v, --verbose  Verbose output

  --debug=debug  Debug level output

DESCRIPTION
  If the IMS context already has a valid access token set (valid meaning
  at least 10 minutes before expiry), that token is returned.

  Otherwise, if the IMS context has a valid refresh token set (valid
  meaning at least 10 minutes before expiry) that refresh token is
  exchanged for an access token before returning the access token.

  Lastly, if the IMS context properties are supported by one of the
  IMS login plugins, that login plugin is called to guide through
  the IMS login process.

  The currently supported IMS login plugins are:

  * aio-lib-ims-jwt for JWT token based login supporting
     Adobe I/O Console service integrations.
  * aio-lib-ims-oauth for browser based OAuth2 login. This
     plugin will launch a Chromium browser to guide through the
     login process. The plugin itself will *never* see the user's
     password but only receive the authorization token after the
     user authenticated with IMS.

See code: src/commands/ims/login.js

aio ims:logout

Log out the current or a named IMS context.

USAGE
  $ aio ims:logout

OPTIONS
  -c, --ctx=ctx  Name of the IMS context to use. Default is the current IMS context

  -f, --force    Invalidate the refresh token as well as all access tokens.
                 Otherwise only the access token is invalidated. For IMS
                 contexts not supporting refresh tokens, this flag has no
                 effect.

  -g, --global   global config

  -l, --local    local config

  -v, --verbose  Verbose output

  --debug=debug  Debug level output

DESCRIPTION
  This command can be called multiple times on the same IMS context with
  out causing any errors. The assumption is that after calling this command
  without an error, the IMS context's access and refresh tokens have been
  invalidated and removed from persistence storage. Repeatedly calling this
  command will just do nothing.

See code: src/commands/ims/logout.js

aio ims:organizations

Retrieve the organizations to which the user is associated

USAGE
  $ aio ims:organizations

OPTIONS
  -c, --ctx=ctx    Name of the IMS context to use. Default is the current IMS context
  -d, --data=data  Request parameter in the form of name=value. Repeat for multiple parameters
  -g, --global     global config
  -l, --local      local config
  -v, --verbose    Verbose output
  --debug=debug    Debug level output

DESCRIPTION
  This is a raw and low level IMS API call command taking the IMS API
  path as the first argument and any additional request parameters
  as optional additional arguments.

  The API result is printed as an object if successful. If the call
  fails, the error message is returned as an error.

See code: src/commands/ims/organizations.js

aio ims:plugins [PLUGIN]

Manage Create Token Plugins.

USAGE
  $ aio ims:plugins [PLUGIN]

ARGUMENTS
  PLUGIN  List of plugins to configure. If not provided, prints the current list instead

OPTIONS
  -c, --ctx=ctx  Name of the IMS context to use. Default is the current IMS context
  -f, --force    Force configuring the list of plugins without checking for existence or contract
  -g, --global   global config
  -l, --local    local config
  -v, --verbose  Verbose output
  --debug=debug  Debug level output

DESCRIPTION
  The following options exist for this command:

  * Print the current list of token creation plugins
  * Update the list of token creation plugins

  Note: If provoding a list of plugis to configure, they are not currently
  checked for existence or implementation of the correct contract.

See code: src/commands/ims/plugins.js

aio ims:post API

Call an IMS API using a POST request

USAGE
  $ aio ims:post API

ARGUMENTS
  API  The IMS API to call, for example: /ims/profile/v1

OPTIONS
  -c, --ctx=ctx    Name of the IMS context to use. Default is the current IMS context
  -d, --data=data  Request parameter in the form of name=value. Repeat for multiple parameters
  -g, --global     global config
  -l, --local      local config
  -v, --verbose    Verbose output
  --debug=debug    Debug level output

DESCRIPTION
  This is a raw and low level IMS API call command taking the IMS API
  path as the first argument and any additional request parameters
  as optional additional arguments.

  The API result is printed as an object if successful. If the call
  fails, the error message is returned as an error.

See code: src/commands/ims/post.js

aio ims:profile

Retrieve the IMS Profile (for a user token)

USAGE
  $ aio ims:profile

OPTIONS
  -c, --ctx=ctx    Name of the IMS context to use. Default is the current IMS context
  -d, --data=data  Request parameter in the form of name=value. Repeat for multiple parameters
  -g, --global     global config
  -l, --local      local config
  -v, --verbose    Verbose output
  --debug=debug    Debug level output

DESCRIPTION
  This is a raw and low level IMS API call command taking the IMS API
  path as the first argument and any additional request parameters
  as optional additional arguments.

  The API result is printed as an object if successful. If the call
  fails, the error message is returned as an error.

See code: src/commands/ims/profile.js

aio ims:session

Retrieve the IMS Profile (for a user token)

USAGE
  $ aio ims:session

OPTIONS
  -c, --ctx=ctx    Name of the IMS context to use. Default is the current IMS context
  -d, --data=data  Request parameter in the form of name=value. Repeat for multiple parameters
  -g, --global     global config
  -l, --local      local config
  -v, --verbose    Verbose output
  --debug=debug    Debug level output

DESCRIPTION
  This is a raw and low level IMS API call command taking the IMS API
  path as the first argument and any additional request parameters
  as optional additional arguments.

  The API result is printed as an object if successful. If the call
  fails, the error message is returned as an error.

See code: src/commands/ims/session.js

Contributing

Contributions are welcomed! Read the Contributing Guide for more information.

Licensing

This project is licensed under the Apache V2 License. See LICENSE for more information.