Automatically delete refresh-token if it is corrupted

This commit is contained in:
Michael Lazar
2017-06-08 01:04:29 -04:00
parent ca0f3f78ae
commit 979726ec6b
4 changed files with 88 additions and 4 deletions

View File

@@ -48,4 +48,8 @@ class TemporaryFileError(RTVError):
class MailcapEntryNotFound(RTVError): class MailcapEntryNotFound(RTVError):
"A valid mailcap entry could not be coerced from the given url" "A valid mailcap entry could not be coerced from the given url"
class InvalidRefreshToken(RTVError):
"The refresh token is corrupt and cannot be used to login"

View File

@@ -15,6 +15,8 @@ from six.moves.BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from . import docs from . import docs
from .config import TEMPLATES from .config import TEMPLATES
from .exceptions import InvalidRefreshToken
from .packages.praw.errors import HTTPException, OAuthException
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@@ -131,8 +133,25 @@ class OAuthHelper(object):
# If we already have a token, request new access credentials # If we already have a token, request new access credentials
if self.config.refresh_token: if self.config.refresh_token:
with self.term.loader('Logging in'): with self.term.loader('Logging in'):
self.reddit.refresh_access_information( try:
self.config.refresh_token) self.reddit.refresh_access_information(
self.config.refresh_token)
except (HTTPException, OAuthException) as e:
# Reddit didn't accept the refresh-token
# This appears to throw a generic 400 error instead of the
# more specific invalid_token message that it used to send
if isinstance(e, HTTPException):
if e._raw.status_code != 400:
# No special handling if the error is something
# temporary like a 5XX.
raise e
# Otherwise we know the token is bad, so we can remove it.
_logger.exception(e)
self.clear_oauth_data()
raise InvalidRefreshToken(
' Invalid user credentials!\n'
'The cached refresh token has been removed')
return return
state = uuid.uuid4().hex state = uuid.uuid4().hex
@@ -207,4 +226,4 @@ class OAuthHelper(object):
def clear_oauth_data(self): def clear_oauth_data(self):
self.reddit.clear_authentication() self.reddit.clear_authentication()
self.config.delete_refresh_token() self.config.delete_refresh_token()

View File

@@ -0,0 +1,51 @@
interactions:
- request:
body: grant_type=refresh_token&redirect_uri=http%3A%2F%2F127.0.0.1%3A65000%2F&refresh_token=**********
headers:
Accept: ['*/*']
Accept-Encoding: ['gzip, deflate']
Authorization: ['**********']
Connection: [keep-alive]
Content-Length: ['99']
Content-Type: [application/x-www-form-urlencoded]
User-Agent: [rtv test suite PRAW/3.6.1 Python/3.6.1 b'Darwin-14.5.0-x86_64-i386-64bit']
method: POST
uri: https://api.reddit.com/api/v1/access_token/
response:
body: {string: '{"message": "Bad Request", "error": 400}'}
headers:
Accept-Ranges: [bytes]
Connection: [keep-alive]
Content-Length: ['40']
Content-Type: [application/json; charset=UTF-8]
Date: ['Thu, 08 Jun 2017 04:57:59 GMT']
Server: [snooserv]
Set-Cookie: ['session_tracker=2Pb665rWf1oCGZfV3L.0.1496897879415.Z0FBQUFBQlpPTmxYQl9PVkQ5ekc5U3FDdWZ3cTZMRlRMWVMtZmdhd1duVGdLYTFva09aZmVIazNucGdHSV9tOV9qUy1FZ0M0RS15aWNYVDNxSWpzU1lOTnBQcGpoU19fY0JuM3NnczVyZ3JBcGhKYUQ0RzVPWXUyb0t4dkt3Y1kzRkRvWHg0TXFJbjI;
Domain=reddit.com; Max-Age=7199; Path=/; expires=Thu, 08-Jun-2017 06:57:59
GMT; secure', 'loid=000000000003fg1hbe.2.1496897879427.Z0FBQUFBQlpPTmxYX2xyMng2Mlk4bmVsUmt6bU04M01ZdTZmZGZ6a3JINnlqdnJKWjZINHNvUFNKc0FJUGVkU2NTem1ycXk3LW1WdXp1bERTM0RsU1J6MlFZZVNsRGZoOGFoREY2QU16ckpHQm01dHI0N2lES2JocmM2ZXVnVXphdFUzUi1yQ3VsQTQ;
Domain=reddit.com; Max-Age=63071999; Path=/; expires=Sat, 08-Jun-2019 04:57:59
GMT; secure', 'session_tracker=vxk8Omjl7TIIb6u89z.0.1496897879423.Z0FBQUFBQlpPTmxYSmFBVDFlRG42OWZCN1V2R2QyVWlhd3VoaWxHWXBUZE9KRGpLSHZOWmhVVHVrTEdIaWQyWW04cXpnMG1TZ2JRUWRMMU5zc1JQQ21ta2NGcGx5RzZtZjNocmlrVEJzTmVuMnBER04ycWN0bzJpaVJnQ0dvS3ZNUWdWOXZIcmJvWEQ;
Domain=reddit.com; Max-Age=7199; Path=/; expires=Thu, 08-Jun-2017 06:57:59
GMT; secure', edgebucket=Tgg4R0Ag556DPxZZBR; Domain=reddit.com; Max-Age=63071999;
Path=/; secure]
Via: [1.1 varnish]
X-Cache: [MISS]
X-Cache-Hits: ['0']
X-Moose: [majestic]
X-Served-By: [cache-ord1735-ORD]
X-Timer: ['S1496897879.401425,VS0,VE37']
cache-control: ['max-age=0, must-revalidate']
set-cookie: ['session_tracker=2Pb665rWf1oCGZfV3L.0.1496897879415.Z0FBQUFBQlpPTmxYQl9PVkQ5ekc5U3FDdWZ3cTZMRlRMWVMtZmdhd1duVGdLYTFva09aZmVIazNucGdHSV9tOV9qUy1FZ0M0RS15aWNYVDNxSWpzU1lOTnBQcGpoU19fY0JuM3NnczVyZ3JBcGhKYUQ0RzVPWXUyb0t4dkt3Y1kzRkRvWHg0TXFJbjI;
Domain=reddit.com; Max-Age=7199; Path=/; expires=Thu, 08-Jun-2017 06:57:59
GMT; secure', 'loid=000000000003fg1hbe.2.1496897879427.Z0FBQUFBQlpPTmxYX2xyMng2Mlk4bmVsUmt6bU04M01ZdTZmZGZ6a3JINnlqdnJKWjZINHNvUFNKc0FJUGVkU2NTem1ycXk3LW1WdXp1bERTM0RsU1J6MlFZZVNsRGZoOGFoREY2QU16ckpHQm01dHI0N2lES2JocmM2ZXVnVXphdFUzUi1yQ3VsQTQ;
Domain=reddit.com; Max-Age=63071999; Path=/; expires=Sat, 08-Jun-2019 04:57:59
GMT; secure', 'session_tracker=vxk8Omjl7TIIb6u89z.0.1496897879423.Z0FBQUFBQlpPTmxYSmFBVDFlRG42OWZCN1V2R2QyVWlhd3VoaWxHWXBUZE9KRGpLSHZOWmhVVHVrTEdIaWQyWW04cXpnMG1TZ2JRUWRMMU5zc1JQQ21ta2NGcGx5RzZtZjNocmlrVEJzTmVuMnBER04ycWN0bzJpaVJnQ0dvS3ZNUWdWOXZIcmJvWEQ;
Domain=reddit.com; Max-Age=7199; Path=/; expires=Thu, 08-Jun-2017 06:57:59
GMT; secure', edgebucket=Tgg4R0Ag556DPxZZBR; Domain=reddit.com; Max-Age=63071999;
Path=/; secure]
x-content-type-options: [nosniff]
x-frame-options: [SAMEORIGIN]
x-ua-compatible: [IE=edge]
x-xss-protection: [1; mode=block]
status: {code: 400, message: Bad Request}
version: 1

View File

@@ -4,6 +4,7 @@ from __future__ import unicode_literals
import requests import requests
from rtv.oauth import OAuthHelper, OAuthHandler from rtv.oauth import OAuthHelper, OAuthHandler
from rtv.exceptions import InvalidRefreshToken
from rtv.packages.praw.errors import OAuthException from rtv.packages.praw.errors import OAuthException
@@ -75,6 +76,15 @@ def test_oauth_terminal_mobile_authorize(reddit, terminal, config):
assert '.compact' in oauth.reddit.config.API_PATHS['authorize'] assert '.compact' in oauth.reddit.config.API_PATHS['authorize']
def test_oauth_authorize_invalid_token(oauth, terminal):
oauth.config.refresh_token = 'invalid_token'
oauth.authorize()
assert oauth.server is None
assert oauth.config.refresh_token is None
assert isinstance(terminal.loader.exception, InvalidRefreshToken)
def test_oauth_authorize_with_refresh_token(oauth, refresh_token): def test_oauth_authorize_with_refresh_token(oauth, refresh_token):
oauth.config.refresh_token = refresh_token oauth.config.refresh_token = refresh_token