From 6ec965484ccbb29dc2211b1837b416696d08ae65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vil=C3=A9m=20Duha?= <vilda.novak@gmail.com> Date: Fri, 13 Sep 2019 09:31:46 +0200 Subject: [PATCH] BlenderKit: Only refresh tokens when needed - on the end of their lifetime. --- blenderkit/__init__.py | 18 ++++++++++++++++++ blenderkit/bkit_oauth.py | 25 ++++++++++++++++--------- blenderkit/oauth.py | 8 +++++--- blenderkit/rerequests.py | 2 +- blenderkit/search.py | 16 ++++++++++------ 5 files changed, 50 insertions(+), 19 deletions(-) diff --git a/blenderkit/__init__.py b/blenderkit/__init__.py index f37c81c79..09ac01708 100644 --- a/blenderkit/__init__.py +++ b/blenderkit/__init__.py @@ -1273,6 +1273,24 @@ class BlenderKitAddonPreferences(AddonPreferences): subtype="PASSWORD", ) + api_key_timeout: IntProperty( + name = 'api key timeout', + description = 'time where the api key will need to be refreshed', + default = 0, + ) + + api_key_life: IntProperty( + name='api key life time', + description='maximum lifetime of the api key, in seconds', + default=0, + ) + + refresh_in_progress: BoolProperty( + name="Api key refresh in progress", + description="Api key is currently being refreshed. Don't refresh it again.", + default=False + ) + login_attempt: BoolProperty( name="Login/Signup attempt", description="When this is on, BlenderKit is trying to connect and login.", diff --git a/blenderkit/bkit_oauth.py b/blenderkit/bkit_oauth.py index 57d3389f6..259fedf53 100644 --- a/blenderkit/bkit_oauth.py +++ b/blenderkit/bkit_oauth.py @@ -33,7 +33,7 @@ import bpy import threading import requests - +import time from bpy.props import ( BoolProperty, @@ -44,44 +44,52 @@ PORTS = [62485, 65425, 55428, 49452] active_authenticator = None + def login_thread(signup=False): global active_authenticator r_url = paths.get_oauth_landing_url() url = paths.get_bkit_url() authenticator = oauth.SimpleOAuthAuthenticator(server_url=url, client_id=CLIENT_ID, ports=PORTS) - #we store authenticator globally to be able to ping the server if connection fails. + # we store authenticator globally to be able to ping the server if connection fails. active_authenticator = authenticator thread = threading.Thread(target=login, args=([signup, url, r_url, authenticator]), daemon=True) thread.start() def login(signup, url, r_url, authenticator): - auth_token, refresh_token = authenticator.get_new_token(register=signup, redirect_url=r_url) + auth_token, refresh_token, oauth_response = authenticator.get_new_token(register=signup, redirect_url=r_url) utils.p('tokens retrieved') - tasks_queue.add_task((write_tokens, (auth_token, refresh_token))) + tasks_queue.add_task((write_tokens, (auth_token, refresh_token, oauth_response))) def refresh_token_thread(): preferences = bpy.context.preferences.addons['blenderkit'].preferences - if len(preferences.api_key_refresh) > 0: + if len(preferences.api_key_refresh) > 0 and preferences.refresh_in_progress == False: + preferences.refresh_in_progress = True url = paths.get_bkit_url() thread = threading.Thread(target=refresh_token, args=([preferences.api_key_refresh, url]), daemon=True) thread.start() + else: + ui.add_report('Already Refreshing token, will be ready soon.') def refresh_token(api_key_refresh, url): authenticator = oauth.SimpleOAuthAuthenticator(server_url=url, client_id=CLIENT_ID, ports=PORTS) - auth_token, refresh_token = authenticator.get_refreshed_token(api_key_refresh) + auth_token, refresh_token, oauth_response = authenticator.get_refreshed_token(api_key_refresh) if auth_token is not None and refresh_token is not None: - tasks_queue.add_task((write_tokens, (auth_token, refresh_token))) + tasks_queue.add_task((write_tokens, (auth_token, refresh_token, oauth_response))) return auth_token, refresh_token -def write_tokens(auth_token, refresh_token): + +def write_tokens(auth_token, refresh_token, oauth_response): utils.p('writing tokens') preferences = bpy.context.preferences.addons['blenderkit'].preferences preferences.api_key_refresh = refresh_token preferences.api_key = auth_token + preferences.api_key_timeout = time.time() + oauth_response['expires_in'] + preferences.api_key_life = oauth_response['expires_in'] preferences.login_attempt = False + preferences.refresh_in_progress = False props = utils.get_search_props() if props is not None: props.report = '' @@ -97,7 +105,6 @@ class RegisterLoginOnline(bpy.types.Operator): bl_label = "BlenderKit login or signup" bl_options = {'REGISTER', 'UNDO'} - signup: BoolProperty( name="create a new account", description="True for register, otherwise login", diff --git a/blenderkit/oauth.py b/blenderkit/oauth.py index bd237953e..afbd8f655 100644 --- a/blenderkit/oauth.py +++ b/blenderkit/oauth.py @@ -53,9 +53,11 @@ class SimpleOAuthAuthenticator(object): print("error retrieving refresh tokens %s" % response.status_code) print(response.content) return None, None - refresh_token = json.loads(response.content)['refresh_token'] - access_token = json.loads(response.content)['access_token'] - return access_token, refresh_token + + response_json = json.loads(response.content) + refresh_token = response_json ['refresh_token'] + access_token = response_json ['access_token'] + return access_token, refresh_token, response_json def get_new_token(self, register=True, redirect_url=None): class HTTPServerHandler(BaseHTTPRequestHandler): diff --git a/blenderkit/rerequests.py b/blenderkit/rerequests.py index d58214bc5..0524c1569 100644 --- a/blenderkit/rerequests.py +++ b/blenderkit/rerequests.py @@ -57,7 +57,7 @@ def rerequest(method, url, **kwargs): if user_preferences.enable_oauth: tasks_queue.add_task((ui.add_report, ('refreshing token.',))) refresh_url = paths.get_bkit_url() - auth_token, refresh_token = bkit_oauth.refresh_token(user_preferences.api_key_refresh, refresh_url) + auth_token, refresh_token, oauth_response = bkit_oauth.refresh_token(user_preferences.api_key_refresh, refresh_url) # utils.p(auth_token, refresh_token) if auth_token is not None: diff --git a/blenderkit/search.py b/blenderkit/search.py index 8e0c01409..11a2d5c8b 100644 --- a/blenderkit/search.py +++ b/blenderkit/search.py @@ -82,11 +82,13 @@ reports = '' def refresh_token_timer(): - ''' this timer gets run every 20 hours. It refreshes tokens and categories.''' - print('refresh timer') + ''' this timer gets run every time the token needs refresh. It refreshes tokens and also categories.''' + utils.p('refresh timer') + user_preferences = bpy.context.preferences.addons['blenderkit'].preferences fetch_server_data() categories.load_categories() - return 72000 + + return max(3600, user_preferences.api_key_life - 3600) @persistent @@ -97,7 +99,7 @@ def scene_load(context): # wm['bkit_update'] = version_checker.compare_versions(blenderkit) categories.load_categories() if not bpy.app.timers.is_registered(refresh_token_timer): - bpy.app.timers.register(refresh_token_timer, persistent=True, first_interval=72000) + bpy.app.timers.register(refresh_token_timer, persistent=True, first_interval=36000) def fetch_server_data(): @@ -106,8 +108,10 @@ def fetch_server_data(): user_preferences = bpy.context.preferences.addons['blenderkit'].preferences url = paths.BLENDERKIT_ADDON_URL api_key = user_preferences.api_key - # version_checker.check_version_thread(url, api_key, blenderkit) - if user_preferences.enable_oauth: + # Only refresh new type of tokens(by length), and only one hour before the token timeouts. + if user_preferences.enable_oauth and \ + len(user_preferences.api_key)<38 and \ + user_preferences.api_key_timeout<time.time()+ 3600: bkit_oauth.refresh_token_thread() if api_key != '': get_profile() -- GitLab