Skip to content

Commit

Permalink
Make redirect_uri optional for flows that don't use it
Browse files Browse the repository at this point in the history
  • Loading branch information
simonrob committed Sep 10, 2024
1 parent 075752e commit 963ec4b
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 13 deletions.
10 changes: 3 additions & 7 deletions emailproxy.config
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ local_address = 127.0.0.1
[Account setup]
documentation = Accounts are specified using your email address as the section heading (e.g., [[email protected]],
etc, below). Account usernames (i.e., email addresses) must be unique - only one entry per account is permitted.
Each account section must provide values for `permission_url`, `token_url`, `oauth2_scope` and `redirect_uri`. If
you are adding an account for a service other than the examples shown below then the provider's documentation should
provide these details.
Each account section must provide values for at least `token_url`, `oauth2_scope` and `client_id`. Depending on the
OAuth 2.0 flow you are using, other values may also be required (see examples below). If you are adding an account
for a service other than the examples shown below then the provider's documentation should provide these details.

You will also need to add your own `client_id` and `client_secret` values as indicated below. These can either be
reused from an existing source (such as another email client that supports OAuth 2.0), or you can register and use
Expand Down Expand Up @@ -228,7 +228,6 @@ documentation = *** note: this is an advanced O365 account example; in most case
token_url = https://login.microsoftonline.com/*** your tenant id here ***/oauth2/v2.0/token
oauth2_scope = https://outlook.office365.com/.default
oauth2_flow = client_credentials
redirect_uri = http://localhost
client_id = *** your client id here ***
client_secret = *** your client secret here ***

Expand All @@ -237,7 +236,6 @@ documentation = *** note: this is an advanced O365 account example; in most case
token_url = https://login.microsoftonline.com/*** your tenant id here ***/oauth2/v2.0/token
oauth2_scope = https://outlook.office365.com/IMAP.AccessAsUser.All https://outlook.office365.com/POP.AccessAsUser.All https://outlook.office365.com/SMTP.Send offline_access
oauth2_flow = password
redirect_uri = http://localhost
client_id = *** your client id here ***
client_secret = *** your client secret here ***

Expand All @@ -246,7 +244,6 @@ documentation = *** note: this is an advanced Google account example; in most ca
token_url = https://oauth2.googleapis.com/token
oauth2_scope = https://mail.google.com/
oauth2_flow = service_account
redirect_uri = http://localhost
client_id = file
client_secret = *** your /path/to/service-account-key.json here ***

Expand All @@ -255,7 +252,6 @@ documentation = *** note: this is an advanced Google account example; in most ca
token_url = https://oauth2.googleapis.com/token
oauth2_scope = https://mail.google.com/
oauth2_flow = service_account
redirect_uri = http://localhost
client_id = key
client_secret = *** your pasted service account JSON key file contents here,
making sure to indent all lines by at least one space ***
Expand Down
13 changes: 7 additions & 6 deletions emailproxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
__author__ = 'Simon Robinson'
__copyright__ = 'Copyright (c) 2024 Simon Robinson'
__license__ = 'Apache 2.0'
__version__ = '2024-09-07' # ISO 8601 (YYYY-MM-DD)
__version__ = '2024-09-10' # ISO 8601 (YYYY-MM-DD)
__package_version__ = '.'.join([str(int(i)) for i in __version__.split('-')]) # for pyproject.toml usage only

import abc
Expand Down Expand Up @@ -725,13 +725,12 @@ def get_oauth2_credentials(username, password, reload_remote_accounts=True):
jwt_certificate_path = AppConfig.get_option_with_catch_all_fallback(config, username, 'jwt_certificate_path')
jwt_key_path = AppConfig.get_option_with_catch_all_fallback(config, username, 'jwt_key_path')

# note that we don't require permission_url here because it is not needed for the client credentials grant flow,
# and likewise for client_secret here because it can be optional for Office 365 configurations
if not (token_url and oauth2_scope and redirect_uri and client_id):
# because the proxy supports a wide range of OAuth 2.0 flows, in addition to the token_url we only mandate the
# core parameters that are required by all methods: oauth2_scope and client_id
if not (token_url and oauth2_scope and client_id):
Log.error('Proxy config file entry incomplete for account', username, '- aborting login')
return (False, '%s: Incomplete config file entry found for account %s - please make sure all required '
'fields are added (permission_url, token_url, oauth2_scope, redirect_uri, client_id '
'and client_secret)' % (APP_NAME, username))
'fields are added (at least token_url, oauth2_scope and client_id)' % (APP_NAME, username))

# while not technically forbidden (RFC 6749, A.1 and A.2), it is highly unlikely the example value is valid
example_client_value = '*** your'
Expand Down Expand Up @@ -1136,6 +1135,8 @@ def get_oauth2_authorisation_tokens(token_url, redirect_uri, client_id, client_s
if oauth2_flow == 'password':
params['username'] = username
params['password'] = password
if not redirect_uri:
del params['redirect_uri'] # redirect_uri is not typically required in non-code flows; remove if empty
try:
response = urllib.request.urlopen(
urllib.request.Request(token_url, data=urllib.parse.urlencode(params).encode('utf-8'),
Expand Down

0 comments on commit 963ec4b

Please sign in to comment.