Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ADR] JAMES-3400 James CLI based on webadmin endpoints #251

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 126 additions & 0 deletions server/protocols/webadmin-cli/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# A WebAdmin based CLI for Apache James

## Development

Webadmin command-line interface is an upcoming replacement for the outdated, security-vulnerable JMX command-line interface. It also aims at providing a more modern and intuitive interface.

## Run the command line

## Syntax

General syntax to run the command line

```
$ james-cli [OPTION] ENTITY ACTION {ARGUMENT}
```

where

OPTION: optional parameter when running the command line,

ENTITY: represents the entity to perform action on,

ACTION: name of the action to perform,

ARGUMENT: arguments needed for the action.

Example:
```
$ james-cli --url http://127.0.0.1 --port 9999 domain list
```

The above command lists all domain names available on domain route at address http://127.0.0.1:9999.
It does not require any argument to execute. Options --url and --port are optional. Without them, the default value is http://127.0.0.0:8000.
As for other commands, arguments might be required after the sub-command (ACTION such as list, add and remove).

## Navigation menu

- [Manage Domains](#manage-domains)
- [Create a domain](#create-a-domain)
- [Delete a domain](#delete-a-domain)
- [Check if a domain exists](#check-if-a-domain-exists)
- [Get the list of domains](#get-the-list-of-domains)
- [Manage Users](#manage-users)
- [Create an user](#create-a-user)
- [Test an user existence](#test-a-user-existence)
- [Delete an user](#delete-a-user)
- [Get users list](#get-users-list)
- [Update an user password](#update-a-user-password)

## Manage Domains

### Create a domain
Add a domain to the domain list.
```
james-cli domain create <domainToBeCreated>
```
Resource name **domainToBeCreated**:

- can not be null or empty
- can not contain ‘@’
- can not be more than 255 characters
- can not contain ‘/’

### Delete a domain

Remove a domain from the domain list.
```
james-cli domain delete <domainToBeDeleted>
```
Note: Deletion of an auto-detected domain, default domain or of an auto-detected ip is not supported. We encourage you instead to review your [domain list configuration](https://james.apache.org/server/config-domainlist.html).

### Check if a domain exists
Check whether a domain exists on the domain list or not.
```
james-cli domain exist <domainToBeChecked>
```

### Get the list of domains
Show all domains' name on the list.
```
james-cli domain list
```



## Manage Users

### Create an user

Add an user to the user list.
```
james-cli user create <username> <password>
```
Resource name <username> representing valid users, hence it should match the criteria at [User Repositories documentation](https://james.apache.org/server/config-users.html)

Note: if the user exists already, its password will be updated.

### Test an user existence

Check whether an user exists on the user list or not.
```
james-cli user exist <username>
```
Resource name <username> representing valid users, hence it should match the criteria at [User Repositories documentation](https://james.apache.org/server/config-users.html)

### Delete an user

Remove an user from the user list.
```
james-cli user delete <username>
```

### Get users list

Show all users' name on the list.

```
james-cli user list
```

### Update an user password
Same as Create, but an user need to exist.

If the user do not exist, then it will be created.


84 changes: 84 additions & 0 deletions src/adr/0042-james-cli-based-on-webadmin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# 42. James CLI based on webadmin API

Date: 2020-10-05
quantranhong1999 marked this conversation as resolved.
Show resolved Hide resolved

## Status

Accepted (lazy consensus).

## Context

James servers offer a command-line interface in order to interact with the server. However, it relies on the JMX protocol, which is known to be insecure. The JMX server embedded in Apache James, also used by the command line client is exposed to a java de-serialization issue according to [NVD-CVE-2017-12628 Detail](https://nvd.nist.gov/vuln/detail/CVE-2017-12628), and thus can be used to execute arbitrary commands.

Besides, the current CLI interface is also not optimal for users. It places actions in front of entities with contiguous syntax, making it harder for the user to remember the command (for example, which entity the GET action command can interact with). If we design to place the entity first and the outgoing actions can interact with that entity afterward, the user will easily imagine what he/she can do with each entity. This creates an intuitive interface that is easier to remember.

Webadmin APIs use HTTP protocol, which is more secure than JMX protocol to interact with James servers.

Webadmin command-line interface is an upcoming replacement for the outdated, security-vulnerable JMX command-line interface.

## Decision

We decided to write a new CLI client, running on top of the JVM, communicating with James via the webadmin protocol, using http.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you intend to make it buildable with GraalVM native image in order to make the adoption easier and have decent start performance?
It's a matter of avoiding not-supported stuff but for a CLI it should be doable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with distributing this CLI as a GraalVM native image 👍

Looks easily achievable https://www.graalvm.org/reference-manual/native-image/NativeImageMavenPlugin/


* What libraries will we use?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's not wise to list libraries here as it's an implementation detail and it would require a new ADT to modify them is people find that the choices validated here don't work as expected.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Later ADRs can superseed this and overide the original choice?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just too many details, as far as I know we never wrote an ADR about our libraries choices.


* http client: ***Feign library***. We used it as an http client in other parts of James so we continue to use it.

* CLI: ***Picocli library***. Picocli is a one-file command line parsing framework written in Java that allows us to create command line applications with almost no code. It allows mixing Options with positional Parameters (Eg: no need to the follow order Options then Parameters), [automatic type conversion](https://picocli.info/#_strongly_typed_everything) of command line arguments to the type of the annotated field, provide Automatic Help and better Subcommand Support, easily handle Exceptions.

* How will we limit breaking changes this new CLI will cause?

* Work on a wrapper to adapt the old CLI API.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea 👍

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

credits to @rouazana :-)


* Where will we locate this cli code?

* server/protocols/webadmin-cli
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't make sense to me: it's not part of the server, it's a standalone app.

What about app/cli?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO that's a promotion that could come later

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you argue about putting it inside server/protocols? I can't find any rational for that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is related to webadmin, having it close to webadmin feels natural to me.

Putting something that is not (yet) the official cli in an official cli place might be confusing. I would defer that choice.


* Distribute this CLI as a GraalVM native image.

* Write a man page.

* Picocli generates beautiful documentation for our CLI (HTML, PDF and Unix man pages).

* We decided to adopt a more modern, modular CLI syntax:

```
$ james-cli [OPTION] ENTITY ACTION {ARGUMENT}
```
where

OPTION: optional parameter when running the command line,

ENTITY: represents the entity to perform action on,

ACTION: name of the action to perform,

ARGUMENT: arguments needed for the action.

#### Examples

Add a domain to the domain list.
```
$ james-cli --url http://127.0.0.1 --port 9999 domain create domainNameToBeCreated
```

In above command-line

OPTION: --url http://127.0.0.1 --port 9999

ENTITY: domain

ACTION: create

ARGUMENT: domainNameToBeCreated


## Consequences

It aims at providing a more modern and more secure CLI, also bringing compatibility ability with old CLI.

## References
* [NVD-CVE-2017-12628 Detail](https://nvd.nist.gov/vuln/detail/CVE-2017-12628)
* [Picocli 2.0: Do More With Less](https://dzone.com/articles/whats-new-in-picocli-20)
* [Picocli Homepage](https://picocli.info/)
* [Native Image Maven Plugin](https://www.graalvm.org/reference-manual/native-image/NativeImageMavenPlugin/)