Skip to content

Commit

Permalink
Merge pull request #74 from kpedro88/user2
Browse files Browse the repository at this point in the history
Manual username parameter
  • Loading branch information
tarickb authored Jul 18, 2023
2 parents edb5b1a + 739dbab commit d5bcf14
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 13 deletions.
27 changes: 16 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,10 @@ Gmail OAuth tokens. Run the script as follows:

```shell
$ sasl-xoauth2-tool get-token gmail \
PATH_TO_TOKENS_FILE \
--client-id=CLIENT_ID_FROM_SASL_XOAUTH2_CONF \
--client-secret=CLIENT_SECRET_FROM_SASL_XOAUTH2_CONF \
--scope="https://mail.google.com/" \
PATH_TO_TOKENS_FILE
--scope="https://mail.google.com/"

Please open this URL in a browser ON THIS HOST:

Expand Down Expand Up @@ -344,9 +344,9 @@ Microsoft OAuth tokens. Run the script as follows:

```shell
$ sasl-xoauth2-tool get-token outlook \
PATH_TO_TOKENS_FILE \
--client-id=CLIENT_ID_FROM_SASL_XOAUTH2_CONF \
--use-device-flow \
PATH_TO_TOKENS_FILE
--use-device-flow
To sign in, use a web browser to open the page https://www.microsoft.com/link and enter the code REDACTED to authenticate.
```

Expand Down Expand Up @@ -429,8 +429,9 @@ Microsoft OAuth tokens. Run the script as follows:

```shell
$ sasl-xoauth2-tool get-token outlook \
--client-id=CLIENT_ID_FROM_SASL_XOAUTH2_CONF \
PATH_TO_TOKENS_FILE
PATH_TO_TOKENS_FILE \
--client-id=CLIENT_ID_FROM_SASL_XOAUTH2_CONF

Please visit the following link in a web browser, then paste the resulting URL:

https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?client_id=REDACTED&response_type=code&redirect_uri=https%3A//login.microsoftonline.com/common/oauth2/nativeclient&response_mode=query&scope=openid%20offline_access%20https%3A//outlook.office.com/SMTP.Send
Expand Down Expand Up @@ -558,11 +559,14 @@ Token refresh succeeded.
$ service postfix restart
```

## Using Multiple Mail Providers Simultaneously
## Using Multiple Mail Providers or Users Simultaneously

One instance of sasl-xoauth2 may provide tokens for different mail providers,
but each provider will require its own client ID, client secret, and token
endpoint. In this case, each of these may be set in the token file rather than
One instance of sasl-xoauth2 may provide tokens for different mail providers
and/or users.
Each provider will require its own client ID, client secret, and token
endpoint. Each user may require a username to be specified, if the username
automatically obtained from postfix is not correct.
In this case, each of these may be set in the token file rather than
in `/etc/sasl-xoauth2.conf`. Set them when setting the initial access token:

```json
Expand All @@ -572,7 +576,8 @@ in `/etc/sasl-xoauth2.conf`. Set them when setting the initial access token:
"client_secret": "client secret goes here, if required",
"token_endpoint": "token endpoint goes here, for non-Gmail",
"expiry" : "0",
"refresh_token" : "refresh token goes here"
"refresh_token" : "refresh token goes here",
"user" : "username goes here"
}
```

Expand Down
1 change: 1 addition & 0 deletions src/client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ int Client::InitialStep(sasl_client_params_t *params,
user_ = auth_name;
token_ = TokenStore::Create(log_.get(), password);
if (!token_) return SASL_FAIL;
if (token_->HasUser()) user_ = token_->User();

err = SendToken(to_server, to_server_len);
if (err != SASL_OK) return err;
Expand Down
8 changes: 6 additions & 2 deletions src/token_store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ int TokenStore::Read() {
refresh_.clear();
access_.clear();
expiry_ = 0;
user_.clear();

try {
log_->Write("TokenStore::Read: file=%s", path_.c_str());
Expand Down Expand Up @@ -211,9 +212,11 @@ int TokenStore::Read() {
if (root.isMember("access_token"))
access_ = root["access_token"].asString();
if (root.isMember("expiry")) expiry_ = stoi(root["expiry"].asString());
if (root.isMember("user"))
user_ = root["user"].asString();

log_->Write("TokenStore::Read: refresh=%s, access=%s", refresh_.c_str(),
access_.c_str());
log_->Write("TokenStore::Read: refresh=%s, access=%s, user=%s", refresh_.c_str(),
access_.c_str(), user_.c_str());
return SASL_OK;

} catch (const std::exception &e) {
Expand All @@ -235,6 +238,7 @@ int TokenStore::Write() {
root["refresh_token"] = refresh_;
root["access_token"] = access_;
root["expiry"] = std::to_string(expiry_);
if (HasUser()) root["user"] = user_;

WriteOverride("client_id", override_client_id_, &root);
WriteOverride("client_secret", override_client_secret_, &root);
Expand Down
4 changes: 4 additions & 0 deletions src/token_store.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class TokenStore {

int GetAccessToken(std::string *token);
int Refresh();
std::string User() const { return user_; }
bool HasUser() const { return !user_.empty(); }

private:
TokenStore(Log *log, const std::string &path, bool enable_updates);
Expand All @@ -55,6 +57,8 @@ class TokenStore {
std::string access_;
std::string refresh_;
time_t expiry_ = 0;
std::string user_;


int refresh_attempts_ = 0;
};
Expand Down

0 comments on commit d5bcf14

Please sign in to comment.