mirror of
https://github.com/derrod/legendary.git
synced 2024-12-22 01:45:28 +00:00
[cli/utils] Skip logout when using Qt/GTK, faster logout on Windows
This commit is contained in:
parent
20c08aa9a4
commit
96ff42f05a
|
@ -163,11 +163,7 @@ class LegendaryCLI:
|
|||
sid = sid.strip('"')
|
||||
exchange_token = self.core.auth_sid(sid)
|
||||
else:
|
||||
def callback(web_sid):
|
||||
exchange_code = self.core.auth_sid(web_sid)
|
||||
return exchange_code and self.core.auth_code(exchange_code)
|
||||
|
||||
if do_webview_login(callback=callback):
|
||||
if do_webview_login(callback_sid=self.core.auth_sid, callback_code=self.core.auth_code):
|
||||
logger.info(f'Successfully logged in as "{self.core.lgd.userdata["displayName"]}" via WebView')
|
||||
else:
|
||||
logger.error('WebView login attempt failed, please see log for details.')
|
||||
|
|
|
@ -2,6 +2,8 @@ import logging
|
|||
import json
|
||||
import webbrowser
|
||||
|
||||
from legendary import __version__
|
||||
|
||||
logger = logging.getLogger('WebViewHelper')
|
||||
webview_available = True
|
||||
|
||||
|
@ -17,7 +19,8 @@ except Exception as e:
|
|||
|
||||
login_url = 'https://www.epicgames.com/id/login'
|
||||
sid_url = 'https://www.epicgames.com/id/api/redirect?'
|
||||
logout_url = 'https://www.epicgames.com/id/logout?productName=epic-games&redirectUrl=https://www.epicgames.com/site/'
|
||||
logout_url = 'https://www.epicgames.com/id/logout?productName=epic-games&redirectUrl=' + login_url
|
||||
goodbye_url = 'https://legendary.gl/goodbye'
|
||||
window_js = '''
|
||||
window.ue = {
|
||||
signinprompt: {
|
||||
|
@ -47,11 +50,10 @@ sid_req.send();
|
|||
|
||||
|
||||
class MockLauncher:
|
||||
def __init__(self, callback=None):
|
||||
self.callback = callback
|
||||
def __init__(self, callback_sid, callback_code):
|
||||
self.callback_sid = callback_sid
|
||||
self.callback_code = callback_code
|
||||
self.window = None
|
||||
self.exchange_code = None
|
||||
self.sid = None
|
||||
self.inject_js = True
|
||||
self.destroy_on_load = False
|
||||
self.callback_result = None
|
||||
|
@ -59,17 +61,19 @@ class MockLauncher:
|
|||
def on_loaded(self):
|
||||
url = self.window.get_current_url()
|
||||
logger.debug(f'Loaded url: {url.partition("?")[0]}')
|
||||
# make sure JS necessary window. stuff is available
|
||||
|
||||
if self.destroy_on_load:
|
||||
logger.info('Closing login window...')
|
||||
self.window.destroy()
|
||||
return
|
||||
|
||||
# Inject JS so required window.ue stuff is available
|
||||
if self.inject_js:
|
||||
self.window.evaluate_js(window_js)
|
||||
|
||||
if 'logout' in url:
|
||||
# prepare to close browser after logout redirect
|
||||
self.destroy_on_load = True
|
||||
elif self.destroy_on_load:
|
||||
# close browser after logout
|
||||
logger.info('Closing web view...')
|
||||
self.window.destroy()
|
||||
|
||||
def nop(self, *args, **kwargs):
|
||||
return
|
||||
|
@ -78,37 +82,51 @@ class MockLauncher:
|
|||
webbrowser.open(url)
|
||||
|
||||
def set_exchange_code(self, exchange_code):
|
||||
self.inject_js = False
|
||||
logger.debug('Got exchange code (stage 1)!')
|
||||
# we cannot use this exchange code as our login would be invalidated
|
||||
# after logging out on the website. Hence we do the dance of using
|
||||
# the SID to create *another* exchange code which will create a session
|
||||
# that remains valid after logging out.
|
||||
self.exchange_code = exchange_code
|
||||
# The default Windows webview retains cookies, GTK/Qt do not. Therefore we can
|
||||
# skip logging out on those platforms and directly use the exchange code we're given.
|
||||
# On windows we have to do a little dance with the SID to create a session that
|
||||
# remains valid after logging out in the embedded browser.
|
||||
if self.window.gui.renderer in ('gtkwebkit2', 'qtwebengine', 'qtwebkit'):
|
||||
self.destroy_on_load = True
|
||||
try:
|
||||
self.callback_result = self.callback_code(exchange_code)
|
||||
except Exception as e:
|
||||
logger.error(f'Logging in via exchange-code failed with {e!r}')
|
||||
finally:
|
||||
# We cannot destroy the browser from here,
|
||||
# so we'll load a small goodbye site first.
|
||||
self.window.load_url(goodbye_url)
|
||||
|
||||
def trigger_sid_exchange(self, *args, **kwargs):
|
||||
self.inject_js = False
|
||||
# first obtain SID, then log out
|
||||
self.window.evaluate_js(get_sid_js)
|
||||
# check if code-based login hasn't already set the destroy flag
|
||||
if not self.destroy_on_load:
|
||||
logger.debug(f'Injecting SID JS')
|
||||
# inject JS to get SID API response and call our API
|
||||
self.window.evaluate_js(get_sid_js)
|
||||
|
||||
def login_sid(self, sid_json):
|
||||
# Try SID login, then log out
|
||||
try:
|
||||
j = json.loads(sid_json)
|
||||
self.sid = j['sid']
|
||||
logger.debug(f'Got SID (stage 2)!')
|
||||
if self.callback:
|
||||
logger.debug(f'Calling login callback...')
|
||||
self.callback_result = self.callback(self.sid)
|
||||
sid = j['sid']
|
||||
logger.debug(f'Got SID (stage 2)! Executing sid login callback...')
|
||||
exchange_code = self.callback_sid(sid)
|
||||
if exchange_code:
|
||||
self.callback_result = self.callback_code(exchange_code)
|
||||
except Exception as e:
|
||||
logger.error(f'Loading SID response failed with {e!r}')
|
||||
logger.error(f'SID login failed with {e!r}')
|
||||
finally:
|
||||
logger.debug('Starting browser logout...')
|
||||
self.window.load_url(logout_url)
|
||||
|
||||
|
||||
def do_webview_login(callback=None):
|
||||
api = MockLauncher(callback=callback)
|
||||
logger.info('Opening web view with Epic Games Login...')
|
||||
window = webview.create_window('Epic Login', url=login_url, width=1024, height=1024, js_api=api)
|
||||
def do_webview_login(callback_sid=None, callback_code=None):
|
||||
api = MockLauncher(callback_sid=callback_sid, callback_code=callback_code)
|
||||
logger.info('Opening Epic Games login window...')
|
||||
window = webview.create_window(f'Legendary {__version__} - Epic Games Account Login',
|
||||
url=login_url, width=768, height=1024, js_api=api)
|
||||
api.window = window
|
||||
window.loaded += api.on_loaded
|
||||
webview.start()
|
||||
|
|
Loading…
Reference in a new issue