mirror of
https://github.com/imapsync/imapsync.git
synced 2025-06-08 21:54:31 +02:00
2.140
This commit is contained in:
parent
4ce248c075
commit
f26b2573c3
370 changed files with 14441 additions and 136699 deletions
79
oauth2/README_OAUTH2.txt
Executable file
79
oauth2/README_OAUTH2.txt
Executable file
|
@ -0,0 +1,79 @@
|
|||
|
||||
# $Id: README_OAUTH2.txt,v 1.1 2021/07/06 01:45:43 gilles Exp gilles $
|
||||
|
||||
1) Do you have a refresh_token?
|
||||
Yes: Good!
|
||||
|
||||
No: Get one. How? Run the commands:
|
||||
|
||||
cd oauth2/
|
||||
./generate_gmail_token youremail@gmail.com
|
||||
|
||||
You will be asked to go to a long url with a browser, like this:
|
||||
|
||||
To authorize token, visit this url and follow the directions:
|
||||
https://accounts.google.com/o/oauth2/auth?client_id=108687549524-86sjq07f3ch8otl9fnr56mjnniltdrvn.apps.googleusercontent.com&redirect_uri=urn%3Aietf%
|
||||
3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=https%3A%2F%2Fmail.google.com%2F
|
||||
|
||||
|
||||
Go to this url, the url above should be the same as presented by the script.
|
||||
Select your gmail address on the page, maybe do some 2-steps confirmation
|
||||
with your phone. Then you'll see this warning:
|
||||
|
||||
"Google hasn’t verified this app"
|
||||
"The app is requesting access to sensitive info in your Google Account.
|
||||
Until the developer (gilles.lamiral@gmail.com) verifies this app
|
||||
with Google, you shouldn't use it."
|
||||
|
||||
Well, gilles.lamiral@gmail.com is me and I haven't verify this app
|
||||
with google yet. But it's me Gilles LAMIRAL, the imapsync author.
|
||||
|
||||
Click on the link "Advanced".
|
||||
It writes:
|
||||
"Continue only if you understand the risks and trust the developer (gilles.lamiral@gmail.com)."
|
||||
|
||||
Then click on the link "Go to imapsync (unsafe)"
|
||||
|
||||
It then shows:
|
||||
"imapsync wants to access your Google Account"
|
||||
"Make sure you trust imapsync"
|
||||
"You may be sharing sensitive info with this site or app.
|
||||
You can always see or remove access in your Google Account."
|
||||
|
||||
Click on the blue button "Allow"
|
||||
|
||||
Copy/paste the code after the prompt "Enter verification code: "
|
||||
|
||||
It will generate a refresh token, an access token, and an oauthdirect
|
||||
token shown on the output, saved in three files,
|
||||
one file named ./D_oauth2_refresh_token_youremail@gmail.com.txt
|
||||
another named ./D_oauth2_access_token_youremail@gmail.com.txt
|
||||
another named ./D_oauth2_oauthdirect_youremail@gmail.com.txt
|
||||
|
||||
The refresh_token is just there to refresh the access_token and the
|
||||
oauthdirect token.
|
||||
|
||||
With imapsync you can use either the oauthdirect or the access_token
|
||||
token, like this:
|
||||
|
||||
imapsync ... --user1 useless --oauthdirect1 oauth2/D_oauth2_oauthdirect_youremail@gmail.com.txt
|
||||
|
||||
imapsync ... --user1 youremail@gmail.com --oauthaccesstoken1 oauth2/D_oauth2_access_token_youremail@gmail.com.txt
|
||||
|
||||
With --oauthdirect1 the --user1 parameter is useless because it is already
|
||||
coded inside the oauthdirect token.
|
||||
|
||||
With --oauthaccesstoken1 the --user1 parameter is important because it will be
|
||||
used by imapsync to generate the oauthdirect token.
|
||||
|
||||
2) How to get a fresh enough access_token (less than one hour)?
|
||||
|
||||
Run the same command:
|
||||
|
||||
cd oauth2/
|
||||
./generate_gmail_token youremail@gmail.com
|
||||
|
||||
It will generate a new access_token (and the oauthdirect one)
|
||||
without any prompt this time, because the refresh token is used for that.
|
||||
|
||||
|
189
oauth2/generate_gmail_token
Executable file
189
oauth2/generate_gmail_token
Executable file
|
@ -0,0 +1,189 @@
|
|||
#!/bin/sh
|
||||
|
||||
refresh_token_file()
|
||||
{
|
||||
echo ./D_oauth2_refresh_token_"$1".txt
|
||||
}
|
||||
|
||||
access_token_file()
|
||||
{
|
||||
echo ./D_oauth2_access_token_"$1".txt
|
||||
}
|
||||
|
||||
oauthdirect_file()
|
||||
{
|
||||
echo ./D_oauth2_oauthdirect_"$1".txt
|
||||
}
|
||||
|
||||
|
||||
|
||||
#echo
|
||||
#echo "get_refresh_token youremail@gmail.com # First time, then once in a while when the refresh_token is no longer working"
|
||||
get_refresh_token()
|
||||
{
|
||||
refresh_token_file="`refresh_token_file $1`"
|
||||
access_token_file="`access_token_file $1`"
|
||||
# 1 Get an access_token and a refresh_token
|
||||
|
||||
./oauth2_google.py --user="$1" \
|
||||
--client_id="108687549524-86sjq07f3ch8otl9fnr56mjnniltdrvn.apps.googleusercontent.com" \
|
||||
--client_secret=zAJO4PLxzeJ4yOaiJRk6f69k \
|
||||
--generate_oauth2_token --quiet
|
||||
|
||||
cat typescript | grep -i 'Refresh Token:' | tail -1 | sed -e 's/Refresh Token: *//' | tr -d '\r' | tee "$refresh_token_file"
|
||||
cat typescript | grep -i 'Access Token:' | tail -1 | sed -e 's/Access Token: *//' | tr -d '\r' | tee "$access_token_file"
|
||||
echo refresh_token saved in "$refresh_token_file"
|
||||
echo access_token saved in "$access_token_file"
|
||||
}
|
||||
|
||||
#echo
|
||||
#echo "regenerate_access_token youremail@gmail.com # 2 Regenerate an access_token if time passes too long (3600s)"
|
||||
regenerate_access_token()
|
||||
{
|
||||
refresh_token_file="`refresh_token_file $1`"
|
||||
access_token_file="`access_token_file $1`"
|
||||
# 2 Regenerate an access_token if time passes too long (3600s)
|
||||
refresh_token="`cat $refresh_token_file|tr -d '\r'`"
|
||||
echo ./oauth2_google.py --quiet --user="$1" \
|
||||
--client_id="108687549524-86sjq07f3ch8otl9fnr56mjnniltdrvn.apps.googleusercontent.com" \
|
||||
--client_secret=zAJO4PLxzeJ4yOaiJRk6f69k \
|
||||
--refresh_token="$refresh_token"
|
||||
|
||||
./oauth2_google.py --quiet --user="$1" \
|
||||
--client_id="108687549524-86sjq07f3ch8otl9fnr56mjnniltdrvn.apps.googleusercontent.com" \
|
||||
--client_secret=zAJO4PLxzeJ4yOaiJRk6f69k \
|
||||
--refresh_token="$refresh_token" | tee "$access_token_file"
|
||||
|
||||
echo access_token saved in "$access_token_file"
|
||||
}
|
||||
|
||||
|
||||
|
||||
refresh_token_is_here()
|
||||
{
|
||||
echo In refresh_token_is_here "$@"
|
||||
# force mode
|
||||
if test -n "$2"; then
|
||||
return $2
|
||||
fi
|
||||
|
||||
refresh_token_file="`refresh_token_file $1`"
|
||||
if test -f "$refresh_token_file" && test -s "$refresh_token_file" ; then
|
||||
echo $refresh_token_file is here
|
||||
return 0
|
||||
else
|
||||
echo $refresh_token_file is not here or empty
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
#echo
|
||||
#echo 'generate_oauthdirect youremail@gmail.com'
|
||||
generate_oauthdirect()
|
||||
{
|
||||
access_token_file="`access_token_file $1`"
|
||||
access_token="`cat $access_token_file`"
|
||||
oauthdirect_file="`oauthdirect_file $1`"
|
||||
# 3 Generate oauth2_string for imap authentication
|
||||
./oauth2_google.py --generate_oauth2_string --user="$1" \
|
||||
--access_token="$access_token" | tail -1 | tee "$oauthdirect_file"
|
||||
echo oauth2_string saved in "$oauthdirect_file"
|
||||
echo Give this to imapsync --oauthdirect1 or --oauthdirect2
|
||||
}
|
||||
|
||||
|
||||
#echo
|
||||
#echo authenticate_imap youremail@gmail.com
|
||||
authenticate_imap()
|
||||
{
|
||||
# 4
|
||||
access_token_file="`access_token_file $1`"
|
||||
access_token="`cat $access_token_file`"
|
||||
echo $access_token
|
||||
./oauth2_imap_from_token "$1" "$access_token"
|
||||
}
|
||||
|
||||
|
||||
#echo 'authenticate_imap_google_from_access_token youremail@gmail.com'
|
||||
authenticate_imap_google_from_access_token()
|
||||
{
|
||||
# 5
|
||||
access_token_file="`access_token_file $1`"
|
||||
access_token="`cat $access_token_file`"
|
||||
echo "$access_token"
|
||||
./oauth2_google.py --user="$1" \
|
||||
--access_token="$access_token" --test_imap_authentication
|
||||
}
|
||||
|
||||
#echo generate_for_imapsync_tests
|
||||
generate_for_imapsync_tests()
|
||||
{
|
||||
regenerate_access_token imapsync.gl0@gmail.com \
|
||||
&& generate_oauthdirect imapsync.gl0@gmail.com \
|
||||
&& authenticate_imap_google_from_access_token imapsync.gl0@gmail.com \
|
||||
&& authenticate_imap imapsync.gl0@gmail.com
|
||||
}
|
||||
|
||||
verify_email()
|
||||
{
|
||||
test X"" != X"$1"
|
||||
}
|
||||
|
||||
usage()
|
||||
{
|
||||
verify_email "$1" || {
|
||||
echo "Please, give an email address as parameter"
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
get_refresh_token_by_script_fork()
|
||||
{
|
||||
if test -f $0.lock; then
|
||||
echo I am a child in script $$
|
||||
get_refresh_token "$1"
|
||||
else
|
||||
echo I am the parent
|
||||
touch $0.lock
|
||||
echo will do: script -q -f -c "$0 $1 $2"
|
||||
script -q -f -c "$0 $1 $2"
|
||||
rm $0.lock
|
||||
regenerate_access_token "$1"
|
||||
generate_oauthdirect "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
I_am_interractive_or_exit()
|
||||
{
|
||||
if test -t 0; then
|
||||
echo Interractive
|
||||
return 0
|
||||
else
|
||||
echo Not interractive
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
#echo "generate_token youremail@gmail.com"
|
||||
generate_token()
|
||||
{
|
||||
echo I am PID $$ $0 "$@"
|
||||
#
|
||||
usage "$1" || return 1
|
||||
|
||||
if refresh_token_is_here "$1" "$2" ; then
|
||||
regenerate_access_token "$1"
|
||||
generate_oauthdirect "$1"
|
||||
authenticate_imap_google_from_access_token "$1"
|
||||
authenticate_imap "$1"
|
||||
else
|
||||
I_am_interractive_or_exit
|
||||
get_refresh_token_by_script_fork "$@"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
generate_token "$@"
|
||||
|
347
oauth2/oauth2_google.py
Executable file
347
oauth2/oauth2_google.py
Executable file
|
@ -0,0 +1,347 @@
|
|||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright 2012 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Performs client tasks for testing IMAP OAuth2 authentication.
|
||||
|
||||
To use this script, you'll need to have registered with Google as an OAuth
|
||||
application and obtained an OAuth client ID and client secret.
|
||||
See https://developers.google.com/identity/protocols/OAuth2 for instructions on
|
||||
registering and for documentation of the APIs invoked by this code.
|
||||
|
||||
This script has 3 modes of operation.
|
||||
|
||||
1. The first mode is used to generate and authorize an OAuth2 token, the
|
||||
first step in logging in via OAuth2.
|
||||
|
||||
oauth2 --user=xxx@gmail.com \
|
||||
--client_id=1038[...].apps.googleusercontent.com \
|
||||
--client_secret=VWFn8LIKAMC-MsjBMhJeOplZ \
|
||||
--generate_oauth2_token
|
||||
|
||||
The script will converse with Google and generate an oauth request
|
||||
token, then present you with a URL you should visit in your browser to
|
||||
authorize the token. Once you get the verification code from the Google
|
||||
website, enter it into the script to get your OAuth access token. The output
|
||||
from this command will contain the access token, a refresh token, and some
|
||||
metadata about the tokens. The access token can be used until it expires, and
|
||||
the refresh token lasts indefinitely, so you should record these values for
|
||||
reuse.
|
||||
|
||||
2. The script will generate new access tokens using a refresh token.
|
||||
|
||||
oauth2 --user=xxx@gmail.com \
|
||||
--client_id=1038[...].apps.googleusercontent.com \
|
||||
--client_secret=VWFn8LIKAMC-MsjBMhJeOplZ \
|
||||
--refresh_token=1/Yzm6MRy4q1xi7Dx2DuWXNgT6s37OrP_DW_IoyTum4YA
|
||||
|
||||
3. The script will generate an OAuth2 string that can be fed
|
||||
directly to IMAP or SMTP. This is triggered with the --generate_oauth2_string
|
||||
option.
|
||||
|
||||
oauth2 --generate_oauth2_string --user=xxx@gmail.com \
|
||||
--access_token=ya29.AGy[...]ezLg
|
||||
|
||||
The output of this mode will be a base64-encoded string. To use it, connect to a
|
||||
IMAPFE and pass it as the second argument to the AUTHENTICATE command.
|
||||
|
||||
a AUTHENTICATE XOAUTH2 a9sha9sfs[...]9dfja929dk==
|
||||
"""
|
||||
|
||||
import base64
|
||||
import imaplib
|
||||
import json
|
||||
from optparse import OptionParser
|
||||
import smtplib
|
||||
import sys
|
||||
import urllib
|
||||
|
||||
|
||||
def SetupOptionParser():
|
||||
# Usage message is the module's docstring.
|
||||
parser = OptionParser(usage=__doc__)
|
||||
parser.add_option('--generate_oauth2_token',
|
||||
action='store_true',
|
||||
dest='generate_oauth2_token',
|
||||
help='generates an OAuth2 token for testing')
|
||||
parser.add_option('--generate_oauth2_string',
|
||||
action='store_true',
|
||||
dest='generate_oauth2_string',
|
||||
help='generates an initial client response string for '
|
||||
'OAuth2')
|
||||
parser.add_option('--client_id',
|
||||
default=None,
|
||||
help='Client ID of the application that is authenticating. '
|
||||
'See OAuth2 documentation for details.')
|
||||
parser.add_option('--client_secret',
|
||||
default=None,
|
||||
help='Client secret of the application that is '
|
||||
'authenticating. See OAuth2 documentation for '
|
||||
'details.')
|
||||
parser.add_option('--access_token',
|
||||
default=None,
|
||||
help='OAuth2 access token')
|
||||
parser.add_option('--refresh_token',
|
||||
default=None,
|
||||
help='OAuth2 refresh token')
|
||||
parser.add_option('--scope',
|
||||
default='https://mail.google.com/',
|
||||
help='scope for the access token. Multiple scopes can be '
|
||||
'listed separated by spaces with the whole argument '
|
||||
'quoted.')
|
||||
parser.add_option('--test_imap_authentication',
|
||||
action='store_true',
|
||||
dest='test_imap_authentication',
|
||||
help='attempts to authenticate to IMAP')
|
||||
parser.add_option('--test_smtp_authentication',
|
||||
action='store_true',
|
||||
dest='test_smtp_authentication',
|
||||
help='attempts to authenticate to SMTP')
|
||||
parser.add_option('--user',
|
||||
default=None,
|
||||
help='email address of user whose account is being '
|
||||
'accessed')
|
||||
parser.add_option('--quiet',
|
||||
action='store_true',
|
||||
default=False,
|
||||
dest='quiet',
|
||||
help='Omit verbose descriptions and only print '
|
||||
'machine-readable outputs.')
|
||||
return parser
|
||||
|
||||
|
||||
# The URL root for accessing Google Accounts.
|
||||
GOOGLE_ACCOUNTS_BASE_URL = 'https://accounts.google.com'
|
||||
|
||||
|
||||
# Hardcoded dummy redirect URI for non-web apps.
|
||||
REDIRECT_URI = 'urn:ietf:wg:oauth:2.0:oob'
|
||||
|
||||
|
||||
def AccountsUrl(command):
|
||||
"""Generates the Google Accounts URL.
|
||||
|
||||
Args:
|
||||
command: The command to execute.
|
||||
|
||||
Returns:
|
||||
A URL for the given command.
|
||||
"""
|
||||
return '%s/%s' % (GOOGLE_ACCOUNTS_BASE_URL, command)
|
||||
|
||||
|
||||
def UrlEscape(text):
|
||||
# See OAUTH 5.1 for a definition of which characters need to be escaped.
|
||||
return urllib.quote(text, safe='~-._')
|
||||
|
||||
|
||||
def UrlUnescape(text):
|
||||
# See OAUTH 5.1 for a definition of which characters need to be escaped.
|
||||
return urllib.unquote(text)
|
||||
|
||||
|
||||
def FormatUrlParams(params):
|
||||
"""Formats parameters into a URL query string.
|
||||
|
||||
Args:
|
||||
params: A key-value map.
|
||||
|
||||
Returns:
|
||||
A URL query string version of the given parameters.
|
||||
"""
|
||||
param_fragments = []
|
||||
for param in sorted(params.iteritems(), key=lambda x: x[0]):
|
||||
param_fragments.append('%s=%s' % (param[0], UrlEscape(param[1])))
|
||||
return '&'.join(param_fragments)
|
||||
|
||||
|
||||
def GeneratePermissionUrl(client_id, scope='https://mail.google.com/'):
|
||||
"""Generates the URL for authorizing access.
|
||||
|
||||
This uses the "OAuth2 for Installed Applications" flow described at
|
||||
https://developers.google.com/accounts/docs/OAuth2InstalledApp
|
||||
|
||||
Args:
|
||||
client_id: Client ID obtained by registering your app.
|
||||
scope: scope for access token, e.g. 'https://mail.google.com'
|
||||
Returns:
|
||||
A URL that the user should visit in their browser.
|
||||
"""
|
||||
params = {}
|
||||
params['client_id'] = client_id
|
||||
params['redirect_uri'] = REDIRECT_URI
|
||||
params['scope'] = scope
|
||||
params['response_type'] = 'code'
|
||||
return '%s?%s' % (AccountsUrl('o/oauth2/auth'),
|
||||
FormatUrlParams(params))
|
||||
|
||||
|
||||
def AuthorizeTokens(client_id, client_secret, authorization_code):
|
||||
"""Obtains OAuth access token and refresh token.
|
||||
|
||||
This uses the application portion of the "OAuth2 for Installed Applications"
|
||||
flow at https://developers.google.com/accounts/docs/OAuth2InstalledApp#handlingtheresponse
|
||||
|
||||
Args:
|
||||
client_id: Client ID obtained by registering your app.
|
||||
client_secret: Client secret obtained by registering your app.
|
||||
authorization_code: code generated by Google Accounts after user grants
|
||||
permission.
|
||||
Returns:
|
||||
The decoded response from the Google Accounts server, as a dict. Expected
|
||||
fields include 'access_token', 'expires_in', and 'refresh_token'.
|
||||
"""
|
||||
params = {}
|
||||
params['client_id'] = client_id
|
||||
params['client_secret'] = client_secret
|
||||
params['code'] = authorization_code
|
||||
params['redirect_uri'] = REDIRECT_URI
|
||||
params['grant_type'] = 'authorization_code'
|
||||
request_url = AccountsUrl('o/oauth2/token')
|
||||
|
||||
response = urllib.urlopen(request_url, urllib.urlencode(params)).read()
|
||||
return json.loads(response)
|
||||
|
||||
|
||||
def RefreshToken(client_id, client_secret, refresh_token):
|
||||
"""Obtains a new token given a refresh token.
|
||||
|
||||
See https://developers.google.com/accounts/docs/OAuth2InstalledApp#refresh
|
||||
|
||||
Args:
|
||||
client_id: Client ID obtained by registering your app.
|
||||
client_secret: Client secret obtained by registering your app.
|
||||
refresh_token: A previously-obtained refresh token.
|
||||
Returns:
|
||||
The decoded response from the Google Accounts server, as a dict. Expected
|
||||
fields include 'access_token', 'expires_in', and 'refresh_token'.
|
||||
"""
|
||||
params = {}
|
||||
params['client_id'] = client_id
|
||||
params['client_secret'] = client_secret
|
||||
params['refresh_token'] = refresh_token
|
||||
params['grant_type'] = 'refresh_token'
|
||||
request_url = AccountsUrl('o/oauth2/token')
|
||||
|
||||
response = urllib.urlopen(request_url, urllib.urlencode(params)).read()
|
||||
return json.loads(response)
|
||||
|
||||
|
||||
def GenerateOAuth2String(username, access_token, base64_encode=True):
|
||||
"""Generates an IMAP OAuth2 authentication string.
|
||||
|
||||
See https://developers.google.com/google-apps/gmail/oauth2_overview
|
||||
|
||||
Args:
|
||||
username: the username (email address) of the account to authenticate
|
||||
access_token: An OAuth2 access token.
|
||||
base64_encode: Whether to base64-encode the output.
|
||||
|
||||
Returns:
|
||||
The SASL argument for the OAuth2 mechanism.
|
||||
"""
|
||||
auth_string = 'user=%s\1auth=Bearer %s\1\1' % (username, access_token)
|
||||
if base64_encode:
|
||||
auth_string = base64.b64encode(auth_string)
|
||||
return auth_string
|
||||
|
||||
|
||||
def TestImapAuthentication(user, auth_string):
|
||||
"""Authenticates to IMAP with the given auth_string.
|
||||
|
||||
Prints a debug trace of the attempted IMAP connection.
|
||||
|
||||
Args:
|
||||
user: The Gmail username (full email address)
|
||||
auth_string: A valid OAuth2 string, as returned by GenerateOAuth2String.
|
||||
Must not be base64-encoded, since imaplib does its own base64-encoding.
|
||||
"""
|
||||
print
|
||||
imap_conn = imaplib.IMAP4_SSL('imap.gmail.com')
|
||||
imap_conn.debug = 4
|
||||
imap_conn.authenticate('XOAUTH2', lambda x: auth_string)
|
||||
imap_conn.select('INBOX')
|
||||
|
||||
|
||||
def TestSmtpAuthentication(user, auth_string):
|
||||
"""Authenticates to SMTP with the given auth_string.
|
||||
|
||||
Args:
|
||||
user: The Gmail username (full email address)
|
||||
auth_string: A valid OAuth2 string, not base64-encoded, as returned by
|
||||
GenerateOAuth2String.
|
||||
"""
|
||||
print
|
||||
smtp_conn = smtplib.SMTP('smtp.gmail.com', 587)
|
||||
smtp_conn.set_debuglevel(True)
|
||||
smtp_conn.ehlo('test')
|
||||
smtp_conn.starttls()
|
||||
smtp_conn.docmd('AUTH', 'XOAUTH2 ' + base64.b64encode(auth_string))
|
||||
|
||||
|
||||
def RequireOptions(options, *args):
|
||||
missing = [arg for arg in args if getattr(options, arg) is None]
|
||||
if missing:
|
||||
print 'Missing options: %s' % ' '.join(missing)
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
def main(argv):
|
||||
options_parser = SetupOptionParser()
|
||||
(options, args) = options_parser.parse_args()
|
||||
if options.refresh_token:
|
||||
RequireOptions(options, 'client_id', 'client_secret')
|
||||
response = RefreshToken(options.client_id, options.client_secret,
|
||||
options.refresh_token)
|
||||
if options.quiet:
|
||||
print response['access_token']
|
||||
else:
|
||||
print 'Access Token: %s' % response['access_token']
|
||||
print 'Access Token Expiration Seconds: %s' % response['expires_in']
|
||||
elif options.generate_oauth2_string:
|
||||
RequireOptions(options, 'user', 'access_token')
|
||||
oauth2_string = GenerateOAuth2String(options.user, options.access_token)
|
||||
if options.quiet:
|
||||
print oauth2_string
|
||||
else:
|
||||
print 'OAuth2 argument:\n' + oauth2_string
|
||||
elif options.generate_oauth2_token:
|
||||
RequireOptions(options, 'client_id', 'client_secret')
|
||||
print 'To authorize token, visit this url and follow the directions:'
|
||||
print ' %s' % GeneratePermissionUrl(options.client_id, options.scope)
|
||||
authorization_code = raw_input('Enter verification code: ')
|
||||
response = AuthorizeTokens(options.client_id, options.client_secret,
|
||||
authorization_code)
|
||||
print 'Refresh Token: %s' % response['refresh_token']
|
||||
print 'Access Token: %s' % response['access_token']
|
||||
print 'Access Token Expiration Seconds: %s' % response['expires_in']
|
||||
elif options.test_imap_authentication:
|
||||
RequireOptions(options, 'user', 'access_token')
|
||||
TestImapAuthentication(options.user,
|
||||
GenerateOAuth2String(options.user, options.access_token,
|
||||
base64_encode=False))
|
||||
elif options.test_smtp_authentication:
|
||||
RequireOptions(options, 'user', 'access_token')
|
||||
TestSmtpAuthentication(options.user,
|
||||
GenerateOAuth2String(options.user, options.access_token,
|
||||
base64_encode=False))
|
||||
else:
|
||||
options_parser.print_help()
|
||||
print 'Nothing to do, exiting.'
|
||||
return
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
35
oauth2/oauth2_imap_from_token
Executable file
35
oauth2/oauth2_imap_from_token
Executable file
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use Mail::IMAPClient ;
|
||||
use MIME::Base64;
|
||||
|
||||
my $access_token ;
|
||||
|
||||
$access_token = $ARGV[1];
|
||||
|
||||
my $username;
|
||||
$username = $ARGV[0]; # "imapsync.gl0@gmail.com" ;
|
||||
|
||||
|
||||
my $oauth_string = "user=" . $username . "\x01auth=Bearer ". $access_token . "\x01\x01" ;
|
||||
print "oauth_string: $oauth_string\n" ;
|
||||
|
||||
|
||||
#my $oauth_string_base64 = $access_token ;
|
||||
my $oauth_string_base64 = encode_base64( $oauth_string , '' ) ;
|
||||
|
||||
print "oauth_string_base64: $oauth_string_base64\n" ;
|
||||
|
||||
my $imap = Mail::IMAPClient->new(
|
||||
Server => 'imap.gmail.com',
|
||||
Port => 993,
|
||||
Ssl => 1,
|
||||
Uid => 1,
|
||||
Showcredentials => 1,
|
||||
) or die("Can't connect to imap server.");
|
||||
|
||||
$imap->Debug(1) ;
|
||||
$imap->authenticate('XOAUTH2', sub { return $oauth_string_base64 }) or die("Auth error: ". $imap->LastError);
|
||||
|
||||
print join(", ",$imap->folders),".\n" or die("List folders error: ". $imap->LastError);
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue