From 8ccd5a2441ebf9971cf3804ba414fa617a87bef7 Mon Sep 17 00:00:00 2001 From: Rossen Georgiev Date: Fri, 13 May 2016 05:04:50 +0100 Subject: [PATCH] added tests for WebAuth #25 --- Makefile | 4 ++ tests/generete_webauth_vcr.py | 83 +++++++++++++++++++++++++ tests/test_webauth.py | 47 ++++++++++++++ vcr/webauth_user_pass_only_fail.yaml | 52 ++++++++++++++++ vcr/webauth_user_pass_only_success.yaml | 54 ++++++++++++++++ 5 files changed, 240 insertions(+) create mode 100644 tests/generete_webauth_vcr.py create mode 100644 tests/test_webauth.py create mode 100644 vcr/webauth_user_pass_only_fail.yaml create mode 100644 vcr/webauth_user_pass_only_success.yaml diff --git a/Makefile b/Makefile index 5afafa3..1d33430 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,10 @@ test: coverage erase PYTHONHASHSEED=0 nosetests --nologcapture --verbosity 1 --with-coverage --cover-package=steam +webauth_gen: + rm -f vcr/webauth* + python tests/generete_webauth_vcr.py + pylint: pylint -r n -f colorized steam || true diff --git a/tests/generete_webauth_vcr.py b/tests/generete_webauth_vcr.py new file mode 100644 index 0000000..7f6caba --- /dev/null +++ b/tests/generete_webauth_vcr.py @@ -0,0 +1,83 @@ +from __future__ import print_function +import os +import sys + +filepath = os.path.dirname(os.path.realpath(__file__)) +rootdir = os.path.abspath(os.path.join(filepath, '..')) +os.chdir(rootdir) +sys.path.insert(0, rootdir) + +from getpass import getpass +import json +import mock +import vcr +import requests + +from steam import webauth as wa + +# personal info scrubbers +# ----------------------- +# The recorded vcr is anonymized and should not contain +# any personal info. MAKE SURE TO CHECK THE VCR BEFORE COMMIT TO REPO + +def request_scrubber(r): + r.body = '' + return r + +def response_scrubber(r): + if 'set-cookie' in r['headers']: + del r['headers']['set-cookie'] + + if r.get('body', ''): + data = json.loads(r['body']['string']) + + if 'token_gid' in data: + data['token_gid'] = 0 + if 'transfer_parameters' in data: + data['transfer_parameters']['steamid'] = '0' + data['transfer_parameters']['token'] = 'A'*16 + data['transfer_parameters']['token_secure'] = 'B'*16 + data['transfer_parameters']['auth'] = 'C'*16 + + body = json.dumps(data) + r['body']['string'] = body + r['headers']['content-length'] = [str(len(body))] + + print(r) + + return r + +anon_vcr = vcr.VCR( + before_record=request_scrubber, + before_record_response=response_scrubber, + serializer='yaml', + record_mode='new_episodes', + cassette_library_dir=os.path.join(rootdir, 'vcr'), +) + +# scenarios +# ----------------- + +def user_pass_only(): + print("Please enter a user that can login with just password.") + u = raw_input("Username: ") + p = getpass("Password (no echo): ") + + user_pass_only_success(u, p) + user_pass_only_fail(u, p + '123') + +@anon_vcr.use_cassette('webauth_user_pass_only_success.yaml') +def user_pass_only_success(u, p): + wa.WebAuth(u, p).login() + +@anon_vcr.use_cassette('webauth_user_pass_only_fail.yaml') +def user_pass_only_fail(u, p): + try: + wa.WebAuth(u, p).login() + except wa.LoginIncorrect: + pass + +# run +# ----------------- +if __name__ == '__main__': + user_pass_only() diff --git a/tests/test_webauth.py b/tests/test_webauth.py new file mode 100644 index 0000000..1de0144 --- /dev/null +++ b/tests/test_webauth.py @@ -0,0 +1,47 @@ +###################################################### +#### +#### NOT TO BE RAN WITHOUT GENERATING A VCR FIRST +#### use .... +#### +###################################################### +import vcr +import unittest +import mock +import requests + +from steam import webauth as wa + +class WACase(unittest.TestCase): + @mock.patch('steam.webauth.make_requests_session') + def test_http_error(self, mrs_mock): + mm = mrs_mock.return_value = mock.MagicMock() + + mm.post.side_effect = requests.exceptions.ConnectTimeout('test') + + with self.assertRaises(wa.HTTPError): + wa.WebAuth('a', 'b').login() + + mm.post.reset_mock() + mm.post.side_effect = requests.exceptions.ReadTimeout('test') + + with self.assertRaises(wa.HTTPError): + wa.WebAuth('c', 'd').login() + + @vcr.use_cassette('vcr/webauth_user_pass_only_success.yaml', mode='none', serializer='yaml') + def test_login_user_and_pass_only_ok(self): + user = wa.WebAuth('testuser', 'testpass') + s = user.login() + + self.assertTrue(user.complete) + self.assertIsInstance(s, requests.Session) + + for domain in s.cookies.list_domains(): + self.assertEqual(s.cookies.get('steamLogin', domain=domain), '0||%s' % ('A'*16)) + self.assertEqual(s.cookies.get('steamLoginSecure', domain=domain), '0||%s' % ('B'*16)) + + self.assertEqual(s, user.login()) + + @vcr.use_cassette('vcr/webauth_user_pass_only_fail.yaml', mode='none', serializer='yaml') + def test_login_user_and_pass_only_fail(self): + with self.assertRaises(wa.LoginIncorrect): + wa.WebAuth('testuser', 'testpass').login() diff --git a/vcr/webauth_user_pass_only_fail.yaml b/vcr/webauth_user_pass_only_fail.yaml new file mode 100644 index 0000000..dbf2562 --- /dev/null +++ b/vcr/webauth_user_pass_only_fail.yaml @@ -0,0 +1,52 @@ +interactions: +- request: + body: '' + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Length: ['46'] + Content-Type: [application/x-www-form-urlencoded] + User-Agent: [python-steam/0.7.4 python-requests/2.9.1] + method: POST + uri: https://store.steampowered.com/login/getrsakey/ + response: + body: {string: !!python/unicode '{"timestamp": "75683600000", "token_gid": 0, + "publickey_mod": "C91B651503A9831EB1708001E9D77FC618D472D29467B7CA31984918BECED0E1E54687EC744B93A10E12D3107B0CC7533923593600D98CCAA921914FB16B4D9910EB7CD556663778C081A22848DCCAB178772C88F24373679441AF0D7042208FE24AB9ADCB17F8C147425ED0C88B67E3E4C997511AB1B3A42F6CE2D0EC1D16FDEFE40D92C778EF45DACAD2AC10177D03B5736C6C339EAD8F03768036E3546A070D5A1FC04BA30495BEAA4A342D842A59971A179A39B6AA532F3BEEDE50596F52F15C9DF7D1DF4EFB470ACB2C36C005FDBDB5A3AB7D9A3D665120B0E04DD782C5E3CFBDA922761ADE5B09D742ED54C198C11A60C77725E4C001AE68C9855D5ED5", + "publickey_exp": "010001", "success": true}'} + headers: + cache-control: [no-cache] + connection: [keep-alive] + content-length: ['621'] + content-type: [application/json; charset=utf-8] + date: ['Fri, 13 May 2016 03:01:26 GMT'] + expires: ['Mon, 26 Jul 1997 05:00:00 GMT'] + server: [Apache] + x-frame-options: [DENY] + status: {code: 200, message: OK} +- request: + body: '' + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Length: ['578'] + Content-Type: [application/x-www-form-urlencoded] + User-Agent: [python-steam/0.7.4 python-requests/2.9.1] + method: POST + uri: https://store.steampowered.com/login/dologin/ + response: + body: {string: !!python/unicode '{"captcha_gid": -1, "success": false, "requires_twofactor": + false, "captcha_needed": false, "clear_password_field": true, "message": "Incorrect + login."}'} + headers: + cache-control: [no-cache] + connection: [keep-alive] + content-length: ['152'] + content-type: [application/json; charset=utf-8] + date: ['Fri, 13 May 2016 03:01:27 GMT'] + expires: ['Mon, 26 Jul 1997 05:00:00 GMT'] + server: [Apache] + x-frame-options: [DENY] + status: {code: 200, message: OK} +version: 1 diff --git a/vcr/webauth_user_pass_only_success.yaml b/vcr/webauth_user_pass_only_success.yaml new file mode 100644 index 0000000..9005877 --- /dev/null +++ b/vcr/webauth_user_pass_only_success.yaml @@ -0,0 +1,54 @@ +interactions: +- request: + body: '' + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Length: ['46'] + Content-Type: [application/x-www-form-urlencoded] + User-Agent: [python-steam/0.7.4 python-requests/2.9.1] + method: POST + uri: https://store.steampowered.com/login/getrsakey/ + response: + body: {string: !!python/unicode '{"timestamp": "75683600000", "token_gid": 0, + "publickey_mod": "C91B651503A9831EB1708001E9D77FC618D472D29467B7CA31984918BECED0E1E54687EC744B93A10E12D3107B0CC7533923593600D98CCAA921914FB16B4D9910EB7CD556663778C081A22848DCCAB178772C88F24373679441AF0D7042208FE24AB9ADCB17F8C147425ED0C88B67E3E4C997511AB1B3A42F6CE2D0EC1D16FDEFE40D92C778EF45DACAD2AC10177D03B5736C6C339EAD8F03768036E3546A070D5A1FC04BA30495BEAA4A342D842A59971A179A39B6AA532F3BEEDE50596F52F15C9DF7D1DF4EFB470ACB2C36C005FDBDB5A3AB7D9A3D665120B0E04DD782C5E3CFBDA922761ADE5B09D742ED54C198C11A60C77725E4C001AE68C9855D5ED5", + "publickey_exp": "010001", "success": true}'} + headers: + cache-control: [no-cache] + connection: [keep-alive] + content-length: ['621'] + content-type: [application/json; charset=utf-8] + date: ['Fri, 13 May 2016 03:01:24 GMT'] + expires: ['Mon, 26 Jul 1997 05:00:00 GMT'] + server: [Apache] + x-frame-options: [DENY] + status: {code: 200, message: OK} +- request: + body: '' + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Length: ['588'] + Content-Type: [application/x-www-form-urlencoded] + User-Agent: [python-steam/0.7.4 python-requests/2.9.1] + method: POST + uri: https://store.steampowered.com/login/dologin/ + response: + body: {string: !!python/unicode '{"requires_twofactor": false, "login_complete": + true, "transfer_urls": ["https://steamcommunity.com/login/transfer", "https://help.steampowered.com/login/transfer"], + "transfer_parameters": {"steamid": "0", "remember_login": false, "token": + "AAAAAAAAAAAAAAAA", "token_secure": "BBBBBBBBBBBBBBBB", "auth": "CCCCCCCCCCCCCCCC"}, + "success": true}'} + headers: + cache-control: [no-cache] + connection: [keep-alive] + content-length: ['341'] + content-type: [application/json; charset=utf-8] + date: ['Fri, 13 May 2016 03:01:25 GMT'] + expires: ['Mon, 26 Jul 1997 05:00:00 GMT'] + server: [Apache] + x-frame-options: [DENY] + status: {code: 200, message: OK} +version: 1