Automatically delete refresh-token if it is corrupted
This commit is contained in:
@@ -49,3 +49,7 @@ 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"
|
||||||
|
|||||||
19
rtv/oauth.py
19
rtv/oauth.py
@@ -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'):
|
||||||
|
try:
|
||||||
self.reddit.refresh_access_information(
|
self.reddit.refresh_access_information(
|
||||||
self.config.refresh_token)
|
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
|
||||||
|
|||||||
51
tests/cassettes/test_oauth_authorize_invalid_token.yaml
Normal file
51
tests/cassettes/test_oauth_authorize_invalid_token.yaml
Normal 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
|
||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user