fix: explicitly save session when token refresh happens
this should only affect "secondary" threads for use with real-time sync to farmOS. the belief is that when a token refresh happens in main thread, the session is auto-saved with the new token. but when a token refresh happens in secondary thread, the session was not being auto-saved with new token. so this should fix that...
This commit is contained in:
parent
78c6a8070a
commit
47d817712b
2 changed files with 30 additions and 5 deletions
|
|
@ -27,7 +27,26 @@ from pyramid import httpexceptions
|
||||||
from webhelpers2.html import HTML
|
from webhelpers2.html import HTML
|
||||||
|
|
||||||
|
|
||||||
def get_farmos_client_for_user(request):
|
def get_farmos_client_for_user(request, main_thread=True):
|
||||||
|
"""
|
||||||
|
Make and return a new farmOS API client instance.
|
||||||
|
|
||||||
|
This is a wrapper around
|
||||||
|
:meth:`~wuttafarm.farmos.handler.FarmOSHandler.get_farmos_client()`
|
||||||
|
with conveniences to automatically handle token refresh for the
|
||||||
|
current user session.
|
||||||
|
|
||||||
|
:param request: Current web request; this determines the user.
|
||||||
|
|
||||||
|
:param main_thread: Boolean indicating whether this client is for
|
||||||
|
use within the main thread, or a separate one. In the latter
|
||||||
|
case it must perform certain extra steps to help with token
|
||||||
|
refresh. This defaults to ``True`` in which case the client is
|
||||||
|
part of the main thread, i.e. the normal request/response
|
||||||
|
cycle.
|
||||||
|
|
||||||
|
:returns: farmOS API client instance
|
||||||
|
"""
|
||||||
token = request.session.get("farmos.oauth2.token")
|
token = request.session.get("farmos.oauth2.token")
|
||||||
if not token:
|
if not token:
|
||||||
raise httpexceptions.HTTPForbidden()
|
raise httpexceptions.HTTPForbidden()
|
||||||
|
|
@ -39,14 +58,14 @@ def get_farmos_client_for_user(request):
|
||||||
token = dict(token)
|
token = dict(token)
|
||||||
|
|
||||||
def token_updater(token):
|
def token_updater(token):
|
||||||
save_farmos_oauth2_token(request, token)
|
save_farmos_oauth2_token(request, token, main_thread=main_thread)
|
||||||
|
|
||||||
config = request.wutta_config
|
config = request.wutta_config
|
||||||
app = config.get_app()
|
app = config.get_app()
|
||||||
return app.get_farmos_client(token=token, token_updater=token_updater)
|
return app.get_farmos_client(token=token, token_updater=token_updater)
|
||||||
|
|
||||||
|
|
||||||
def save_farmos_oauth2_token(request, token):
|
def save_farmos_oauth2_token(request, token, main_thread=True):
|
||||||
"""
|
"""
|
||||||
Common logic for saving the given OAuth2 token within the user
|
Common logic for saving the given OAuth2 token within the user
|
||||||
session. This function is called from 2 places:
|
session. This function is called from 2 places:
|
||||||
|
|
@ -61,6 +80,12 @@ def save_farmos_oauth2_token(request, token):
|
||||||
# save token to user session
|
# save token to user session
|
||||||
request.session["farmos.oauth2.token"] = token
|
request.session["farmos.oauth2.token"] = token
|
||||||
|
|
||||||
|
if not main_thread:
|
||||||
|
# nb. must call persist() explicitly in separate thread, since
|
||||||
|
# pyramid_beaker may not be in effect (iiuc?)
|
||||||
|
request.session.save()
|
||||||
|
request.session.persist()
|
||||||
|
|
||||||
|
|
||||||
def use_farmos_style_grid_links(config):
|
def use_farmos_style_grid_links(config):
|
||||||
return config.get_bool(f"{config.appname}.farmos_style_grid_links", default=True)
|
return config.get_bool(f"{config.appname}.farmos_style_grid_links", default=True)
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ class WuttaFarmMasterView(MasterView):
|
||||||
if self.app.is_farmos_mirror():
|
if self.app.is_farmos_mirror():
|
||||||
if self.creating:
|
if self.creating:
|
||||||
session.flush() # need the new uuid
|
session.flush() # need the new uuid
|
||||||
client = get_farmos_client_for_user(self.request)
|
client = get_farmos_client_for_user(self.request, main_thread=False)
|
||||||
thread = threading.Thread(
|
thread = threading.Thread(
|
||||||
target=self.auto_sync_to_farmos, args=(client, obj.uuid)
|
target=self.auto_sync_to_farmos, args=(client, obj.uuid)
|
||||||
)
|
)
|
||||||
|
|
@ -168,7 +168,7 @@ class WuttaFarmMasterView(MasterView):
|
||||||
|
|
||||||
# maybe delete from farmOS also
|
# maybe delete from farmOS also
|
||||||
if farmos_uuid:
|
if farmos_uuid:
|
||||||
client = get_farmos_client_for_user(self.request)
|
client = get_farmos_client_for_user(self.request, main_thread=False)
|
||||||
# nb. must use separate thread to avoid some kind of race
|
# nb. must use separate thread to avoid some kind of race
|
||||||
# condition (?) - seems as though maybe a "boomerang"
|
# condition (?) - seems as though maybe a "boomerang"
|
||||||
# effect is happening; this seems to help anyway
|
# effect is happening; this seems to help anyway
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue