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

Forward-compatible SASL API #68

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

nevans
Copy link
Contributor

@nevans nevans commented Oct 9, 2023

It is my belief that the current API for #start and #authenticate can't fully support every SASL mechanism. Most of the necessary changes have been implemented by #71, and are described in that ticket.

This PR adds a new Net::SMTP#auth method which is similar to #authenticate, but uses a different call signature: type is passed in either as a keyword argument or as the first positional argument. All other arguments are forwarded to the authenticator.

Although #71 updates #authenticate to forward keyword args and a block and makes username and secret both optional, there are limitations to maintaining backward-compatibility with the existing #authenticate method. Because the mechanism is last and optional it's not possible to use an authenticator with a single positional parameter or with more than two positional parameters. The call signature used by #auth avoids this problem.

As currently written, this PR depends on the following other PRs:

This PR is intended as a transition between the v0.4.0 #authenticate method and a shared SASL implementation, either using net-imap's implementation or extracting it to a net-sasl gem (see ruby/net-imap#23). The #auth and #start API in this PR are both compatible with all of the SASL mechanisms supported by net-imap v0.4.1. The following PRs depend on this one:

@nevans
Copy link
Contributor Author

nevans commented Oct 10, 2023

I've been using a personal fork of net-smtp that shares the SASL implementation with net-imap, for over a year. It was always my intention to create a PR, but... I never made time for it. My apologies: this PR is probably larger than it would have been if I'd submitted a year ago!

@nevans nevans force-pushed the sasl/forward-compatible-api branch 2 times, most recently from baf9035 to 628f113 Compare October 11, 2023 13:10
@nevans nevans marked this pull request as draft October 11, 2023 14:17
@nevans
Copy link
Contributor Author

nevans commented Oct 11, 2023

This PR is still fairly large. So I've converted it to draft, and I'm going to split it into several more bite-sized PRs which can mostly be applied directly to master without any dependencies on other PRs.

I'd still welcome feedback on this PR as it is. Unless I hear feedback otherwise, I don't expect the final form will be significantly different from this.

@nevans nevans force-pushed the sasl/forward-compatible-api branch 9 times, most recently from 4efd8a4 to 745c320 Compare October 15, 2023 11:28
@nevans nevans force-pushed the sasl/forward-compatible-api branch from 745c320 to 5e2e2ef Compare October 21, 2023 00:28
@nevans nevans force-pushed the sasl/forward-compatible-api branch 2 times, most recently from 846e9cb to 510c293 Compare November 9, 2023 15:42
This adds a new `auth` keyword param to `Net::SMTP.start` and `#start`
that can be used to pass any arbitrary keyword parameters to
`#authenticate`.  The pre-existing `username`, `secret`, etc keyword
params will retain their existing behavior as positional arguments to
`#authenticate`.
Although "user" is a reasonable abbreviation, the parameter is more
accurately described as a "username" or an "authentication identity".
They are synonomous here, with "username" winning when both are present.
Username can be set by args[0], authcid, username, or user.
Secret can be set by args[1], secret, or password.

Since all of the existing authenticators have the same API, it is
sufficient to update `check_args` in the base class.
This API is a little bit confusing, IMO.  But it does preserve backward
compatibility, while allowing authenticators that don't allow positional
parameters to work without crashing.  But, authenticators that require
only one parameter—or more than three—will still be inaccessible.
This is convenient for `smtp.start auth: {type:, **etc}`.
Although `#authenticate` can be updated to make username and secret
_both_ optional, by placing the mechanism last and making it optional,
it's not possible to use an authenticator with a _single_ positional
parameter or with more than two positional parameters.  By placing
`type` first among positional parameters or as a keyword argument, we
avoid this problem.
@nevans nevans force-pushed the sasl/forward-compatible-api branch from 510c293 to d8cc256 Compare May 5, 2024 15:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

1 participant