Skip to content

Commit

Permalink
Fix auth with escaped cookies
Browse files Browse the repository at this point in the history
handle web exceptions

possible fix when user cookie is escaped by galaxy cef

rm sensitive data; check cookie valid during auth

bump ver
  • Loading branch information
UncleGoogle committed Jul 21, 2019
1 parent ab243b3 commit 1a8a195
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 22 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
.env
galaxy/
info.md
credentials.data
credentials*

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
5 changes: 3 additions & 2 deletions src/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ async def authenticate(self, stored_credentials=None):
return Authentication(user_id, user_name)

async def pass_login_credentials(self, step, credentials, cookies):
logging.debug(json.dumps(cookies, indent=2))
auth_cookie = next(filter(lambda c: c['name'] == '_simpleauth_sess', cookies))
self.store_credentials(auth_cookie)

user_id, user_name = await self._api.authenticate(auth_cookie)
self.store_credentials(auth_cookie)
return Authentication(user_id, user_name)

async def get_owned_games(self):
Expand All @@ -59,7 +60,7 @@ def is_game(sub):
gamekeys = await self._api.get_gamekeys()
for gamekey in gamekeys:
details = await self._api.get_order_details(gamekey)
# logging.info(f'Parsing details of order {gamekey}:\n{json.dumps(details, indent=4)}')
logging.info(f'Parsing details of order {gamekey}:\n{json.dumps(details, indent=4)}')
for sub in details['subproducts']:
if is_game(sub):
games[sub['machine_name']] = HumbleGame(sub)
Expand Down
2 changes: 1 addition & 1 deletion src/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.1"
__version__ = "0.1.1"
31 changes: 20 additions & 11 deletions src/webservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import base64
import logging

from galaxy.http import create_client_session
from galaxy.http import create_client_session, handle_exception


class AuthorizedHumbleAPI:
Expand All @@ -24,24 +24,33 @@ def __init__(self):
self._session = create_client_session(headers=self._DEFAULT_HEADERS)

async def _request(self, *args, **kwargs):
if 'params' not in kwargs:
kwargs['params'] = self._DEFAULT_PARAMS
return await self._session.request(*args, **kwargs)
with handle_exception():
if 'params' not in kwargs:
kwargs['params'] = self._DEFAULT_PARAMS
return await self._session.request(*args, **kwargs)

def _decode_user_id(self, _simpleauth_sess):
info = _simpleauth_sess.split('|')[0]
# get rid of escape characters
info = bytes(info, "utf-8").decode("unicode_escape")
info_padded = info + '=='
decoded = json.loads(base64.b64decode(info_padded))
logging.debug(decoded)
logging.debug(f'user info cookie: {info}')
info += '==' # ensure full padding
decoded = json.loads(base64.b64decode(info))
return decoded['user_id']

async def authenticate(self, auth_cookie: dict):
# recreate original cookie
cookie = SimpleCookie()
cookie[auth_cookie['name']] = auth_cookie['value']
cookie_val = bytes(auth_cookie['value'], "utf-8").decode("unicode_escape")
# some users have cookies with escaped characters, some not...
# for the first group strip quotes:
cookie_val = cookie_val.replace('"', '')
cookie[auth_cookie['name']] = cookie_val

user_id = self._decode_user_id(cookie_val)
self._session.cookie_jar.update_cookies(cookie)
user_id = self._decode_user_id(auth_cookie['value'])

# check if auth session is valid
await self.get_gamekeys()

return (user_id, user_id)

async def get_gamekeys(self):
Expand Down
3 changes: 3 additions & 0 deletions tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ def dist(output=DIST_PLUGIN, galaxy_path=GALAXY_PATH):
for proc in psutil.process_iter(attrs=['exe'], ad_value=''):
if proc.info['exe'] == galaxy_path:
print(f'Galaxy at {galaxy_path} is running!. Terminating...')
for child in proc.children():
child.terminate()
proc.terminate()
break
else:
print('Galaxy instance not found.')

Expand Down
19 changes: 12 additions & 7 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@
from pathlib import Path
import asyncio


CREDENTIALS_FILE = "credentials-other"


if __name__ == "__main__":

async def run_server_connection(reader, writer):

credentials = ""
path = Path("credentials.data")
path = Path(CREDENTIALS_FILE)
if not path.exists():
path.touch()

with open("credentials.data", "r") as f:
with open(CREDENTIALS_FILE, "r") as f:
data = f.read()
if data:
credentials = json.loads(data)
Expand All @@ -37,15 +41,16 @@ async def run_server_connection(reader, writer):
tokens = json.loads(tokens.decode())
try:
if 'method' in tokens and tokens['method'] == 'store_credentials':
with open('credentials.data', 'w') as f:
print(f'overwriting {CREDENTIALS_FILE}')
with open(CREDENTIALS_FILE, 'w') as f:
f.write(json.dumps(tokens['params']))

print("tokens", tokens)
ret = await reader.readline()
print("ret", ret)
except Exception as e:
print(f'{str(e)}: Removing credentials')
os.remove('credentials.data')
print(f'{str(e)}.\n Probably you need refresh it?')


print("owned")
writer.write(b'{"jsonrpc": "2.0", "id": "3", "method": "import_owned_games"}\n')
Expand All @@ -59,8 +64,8 @@ async def run_server_connection(reader, writer):
# ret = await reader.readline()
# print("ret", ret)

print("install_game")
writer.write(b'{"jsonrpc": "2.0", "method": "install_game", "params":{"game_id": "samorost2"}}\n')
# print("install_game")
# writer.write(b'{"jsonrpc": "2.0", "method": "install_game", "params":{"game_id": "samorost2"}}\n')

# print("launch_game")
# writer.write(b'{"jsonrpc": "2.0", "method": "launch_game", "params":{"game_id": "samorost2"}}\n')
Expand Down

0 comments on commit 1a8a195

Please sign in to comment.