From d465934818a4827599a3b5a05beb5168a3d708af Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sat, 28 Feb 2026 12:53:18 -0600 Subject: [PATCH] fix: ensure token refresh works regardless where API client is used --- src/wuttafarm/app.py | 16 ++++++++-------- src/wuttafarm/farmos/importing/wuttafarm.py | 8 +++++--- src/wuttafarm/importing/farmos.py | 8 +++++--- src/wuttafarm/web/views/animals.py | 5 +++-- src/wuttafarm/web/views/master.py | 4 ++-- src/wuttafarm/web/views/plants.py | 5 +++-- src/wuttafarm/web/views/quick/eggs.py | 7 ++++--- 7 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/wuttafarm/app.py b/src/wuttafarm/app.py index 30c7f51..a3fa566 100644 --- a/src/wuttafarm/app.py +++ b/src/wuttafarm/app.py @@ -136,7 +136,7 @@ class WuttaFarmAppHandler(base.AppHandler): factory = self.load_object(spec) return factory(self.config, farmos_client) - def auto_sync_to_farmos(self, obj, model_name=None, token=None, require=True): + def auto_sync_to_farmos(self, obj, model_name=None, client=None, require=True): """ Export the given object to farmOS, using configured handler. @@ -147,8 +147,8 @@ class WuttaFarmAppHandler(base.AppHandler): :param obj: Any data object in WuttaFarm, e.g. AnimalAsset instance. - :param token: OAuth2 token for the farmOS client. If not - specified, the import handler will obtain a new token. + :param client: Existing farmOS API client to use. If not + specified, a new one will be instantiated. :param require: If true, this will *require* the export handler to support objects of the given type. If false, @@ -165,12 +165,12 @@ class WuttaFarmAppHandler(base.AppHandler): return # nb. begin txn to establish the API client - handler.begin_target_transaction(token) + handler.begin_target_transaction(client) importer = handler.get_importer(model_name, caches_target=False) normal = importer.normalize_source_object(obj) importer.process_data(source_data=[normal]) - def auto_sync_from_farmos(self, obj, model_name, token=None, require=True): + def auto_sync_from_farmos(self, obj, model_name, client=None, require=True): """ Import the given object from farmOS, using configured handler. @@ -179,8 +179,8 @@ class WuttaFarmAppHandler(base.AppHandler): :param model_name': Model name for the importer to use, e.g. ``"AnimalAsset"``. - :param token: OAuth2 token for the farmOS client. If not - specified, the import handler will obtain a new token. + :param client: Existing farmOS API client to use. If not + specified, a new one will be instantiated. :param require: If true, this will *require* the import handler to support objects of the given type. If false, @@ -195,7 +195,7 @@ class WuttaFarmAppHandler(base.AppHandler): return # nb. begin txn to establish the API client - handler.begin_source_transaction(token) + handler.begin_source_transaction(client) with self.short_session(commit=True) as session: handler.target_session = session importer = handler.get_importer(model_name, caches_target=False) diff --git a/src/wuttafarm/farmos/importing/wuttafarm.py b/src/wuttafarm/farmos/importing/wuttafarm.py index bb5350d..96cefb2 100644 --- a/src/wuttafarm/farmos/importing/wuttafarm.py +++ b/src/wuttafarm/farmos/importing/wuttafarm.py @@ -50,13 +50,15 @@ class ToFarmOSHandler(ImportHandler): # TODO: a lot of duplication to cleanup here; see FromFarmOSHandler - def begin_target_transaction(self, token=None): + def begin_target_transaction(self, client=None): """ Establish the farmOS API client. """ - if not token: + if client: + self.farmos_client = client + else: token = self.get_farmos_oauth2_token() - self.farmos_client = self.app.get_farmos_client(token=token) + self.farmos_client = self.app.get_farmos_client(token=token) self.farmos_4x = self.app.is_farmos_4x(self.farmos_client) def get_farmos_oauth2_token(self): diff --git a/src/wuttafarm/importing/farmos.py b/src/wuttafarm/importing/farmos.py index 9e922da..5bc351e 100644 --- a/src/wuttafarm/importing/farmos.py +++ b/src/wuttafarm/importing/farmos.py @@ -46,13 +46,15 @@ class FromFarmOSHandler(ImportHandler): source_key = "farmos" generic_source_title = "farmOS" - def begin_source_transaction(self, token=None): + def begin_source_transaction(self, client=None): """ Establish the farmOS API client. """ - if not token: + if client: + self.farmos_client = client + else: token = self.get_farmos_oauth2_token() - self.farmos_client = self.app.get_farmos_client(token=token) + self.farmos_client = self.app.get_farmos_client(token=token) self.farmos_4x = self.app.is_farmos_4x(self.farmos_client) self.normal = self.app.get_normalizer(self.farmos_client) diff --git a/src/wuttafarm/web/views/animals.py b/src/wuttafarm/web/views/animals.py index fc4c646..b52a353 100644 --- a/src/wuttafarm/web/views/animals.py +++ b/src/wuttafarm/web/views/animals.py @@ -32,6 +32,7 @@ from wuttafarm.db.model import AnimalType, AnimalAsset from wuttafarm.web.views.assets import AssetTypeMasterView, AssetMasterView from wuttafarm.web.forms.schema import AnimalTypeRef from wuttafarm.web.forms.widgets import ImageWidget +from wuttafarm.web.util import get_farmos_client_for_user class AnimalTypeView(AssetTypeMasterView): @@ -168,8 +169,8 @@ class AnimalTypeView(AssetTypeMasterView): session.flush() if self.app.is_farmos_mirror(): - token = self.request.session.get("farmos.oauth2.token") - self.app.auto_sync_to_farmos(animal_type, token=token) + client = get_farmos_client_for_user(self.request) + self.app.auto_sync_to_farmos(animal_type, client=client) return { "uuid": animal_type.uuid.hex, diff --git a/src/wuttafarm/web/views/master.py b/src/wuttafarm/web/views/master.py index ec3c913..747cdc5 100644 --- a/src/wuttafarm/web/views/master.py +++ b/src/wuttafarm/web/views/master.py @@ -112,8 +112,8 @@ class WuttaFarmMasterView(MasterView): # maybe also sync change to farmOS if self.app.is_farmos_mirror(): - token = self.request.session.get("farmos.oauth2.token") - self.app.auto_sync_to_farmos(obj, token=token, require=False) + client = get_farmos_client_for_user(self.request) + self.app.auto_sync_to_farmos(obj, client=client, require=False) def get_farmos_entity_type(self): if self.farmos_entity_type: diff --git a/src/wuttafarm/web/views/plants.py b/src/wuttafarm/web/views/plants.py index a2d0cb1..c831201 100644 --- a/src/wuttafarm/web/views/plants.py +++ b/src/wuttafarm/web/views/plants.py @@ -32,6 +32,7 @@ from wuttafarm.db.model import PlantType, PlantAsset from wuttafarm.web.views.assets import AssetTypeMasterView, AssetMasterView from wuttafarm.web.forms.schema import PlantTypeRefs from wuttafarm.web.forms.widgets import ImageWidget +from wuttafarm.web.util import get_farmos_client_for_user class PlantTypeView(AssetTypeMasterView): @@ -161,8 +162,8 @@ class PlantTypeView(AssetTypeMasterView): session.flush() if self.app.is_farmos_mirror(): - token = self.request.session.get("farmos.oauth2.token") - self.app.auto_sync_to_farmos(plant_type, token=token) + client = get_farmos_client_for_user(self.request) + self.app.auto_sync_to_farmos(plant_type, client=client) return { "uuid": plant_type.uuid.hex, diff --git a/src/wuttafarm/web/views/quick/eggs.py b/src/wuttafarm/web/views/quick/eggs.py index 0482132..e5461b1 100644 --- a/src/wuttafarm/web/views/quick/eggs.py +++ b/src/wuttafarm/web/views/quick/eggs.py @@ -34,6 +34,7 @@ from wuttaweb.forms.schema import WuttaDateTime from wuttaweb.forms.widgets import WuttaDateTimeWidget from wuttafarm.web.views.quick import QuickFormView +from wuttafarm.web.util import get_farmos_client_for_user class EggsQuickForm(QuickFormView): @@ -118,11 +119,11 @@ class EggsQuickForm(QuickFormView): if self.app.is_farmos_mirror(): quantity = json.loads(response["create-quantity"]["body"]) - token = self.request.session.get("farmos.oauth2.token") + client = get_farmos_client_for_user(self.request) self.app.auto_sync_from_farmos( - quantity["data"], "StandardQuantity", token=token + quantity["data"], "StandardQuantity", client=client ) - self.app.auto_sync_from_farmos(log["data"], "HarvestLog", token=token) + self.app.auto_sync_from_farmos(log["data"], "HarvestLog", client=client) return log