From ec6ac443fb1b3a53a465b65edb431e8d7cddc073 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Wed, 25 Feb 2026 11:22:49 -0600 Subject: [PATCH 1/5] fix: add separate permission for each quick form view --- src/wuttafarm/web/views/quick/__init__.py | 5 +++++ src/wuttafarm/web/views/quick/base.py | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/wuttafarm/web/views/quick/__init__.py b/src/wuttafarm/web/views/quick/__init__.py index 92595e1..8423b0d 100644 --- a/src/wuttafarm/web/views/quick/__init__.py +++ b/src/wuttafarm/web/views/quick/__init__.py @@ -27,4 +27,9 @@ from .base import QuickFormView def includeme(config): + + # perm group + config.add_wutta_permission_group("quick", "Quick Forms", overwrite=False) + + # quick form views config.include("wuttafarm.web.views.quick.eggs") diff --git a/src/wuttafarm/web/views/quick/base.py b/src/wuttafarm/web/views/quick/base.py index 2fb73e4..a40e8e3 100644 --- a/src/wuttafarm/web/views/quick/base.py +++ b/src/wuttafarm/web/views/quick/base.py @@ -151,6 +151,10 @@ class QuickFormView(View): def _defaults(cls, config): route_slug = cls.get_route_slug() url_slug = cls.get_url_slug() + form_title = cls.get_form_title() + config.add_wutta_permission("quick", f"quick.{route_slug}", form_title) config.add_route(f"quick.{route_slug}", f"/quick/{url_slug}") - config.add_view(cls, route_name=f"quick.{route_slug}") + config.add_view( + cls, route_name=f"quick.{route_slug}", permission=f"quick.{route_slug}" + ) From df517cfbfafc6a4e4a625b9bf70dfca256a0f064 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Wed, 25 Feb 2026 14:36:28 -0600 Subject: [PATCH 2/5] fix: expose config for farmOS OAuth2 client_id and scope refs: #3 --- src/wuttafarm/farmos/handler.py | 6 +++++ .../web/templates/appinfo/configure.mako | 22 +++++++++++++++++++ src/wuttafarm/web/views/auth.py | 5 +++-- src/wuttafarm/web/views/settings.py | 13 ++++++++++- 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/wuttafarm/farmos/handler.py b/src/wuttafarm/farmos/handler.py index 6eee14f..e905f92 100644 --- a/src/wuttafarm/farmos/handler.py +++ b/src/wuttafarm/farmos/handler.py @@ -94,3 +94,9 @@ class FarmOSHandler(GenericHandler): return f"{base}/{path}" return base + + def get_oauth2_client_id(self): + return self.config.get("farmos.oauth2.client_id", default="farm") + + def get_oauth2_scope(self): + return self.config.get("farmos.oauth2.scope", default="farm_manager") diff --git a/src/wuttafarm/web/templates/appinfo/configure.mako b/src/wuttafarm/web/templates/appinfo/configure.mako index 3760577..8dc5e8a 100644 --- a/src/wuttafarm/web/templates/appinfo/configure.mako +++ b/src/wuttafarm/web/templates/appinfo/configure.mako @@ -14,6 +14,28 @@ + + + + + + + + + + + + + + + + + + Date: Wed, 25 Feb 2026 14:55:30 -0600 Subject: [PATCH 3/5] fix: only show quick form menu if perms allow --- src/wuttafarm/web/menus.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wuttafarm/web/menus.py b/src/wuttafarm/web/menus.py index 6ce4a8d..fe7719e 100644 --- a/src/wuttafarm/web/menus.py +++ b/src/wuttafarm/web/menus.py @@ -72,7 +72,7 @@ class WuttaFarmMenuHandler(base.MenuHandler): { "title": "Eggs", "route": "quick.eggs", - # "perm": "assets.list", + "perm": "quick.eggs", }, ], } From 127ea49d744bd0492be424084501f985cb8710ba Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Wed, 25 Feb 2026 14:55:47 -0600 Subject: [PATCH 4/5] fix: add more default perms for first site admin user --- src/wuttafarm/web/views/common.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/wuttafarm/web/views/common.py b/src/wuttafarm/web/views/common.py index f15e92b..674d76e 100644 --- a/src/wuttafarm/web/views/common.py +++ b/src/wuttafarm/web/views/common.py @@ -87,10 +87,20 @@ class CommonView(base.CommonView): "farmos_logs_medical.view", "farmos_logs_observation.list", "farmos_logs_observation.view", + "farmos_plant_assets.list", + "farmos_plant_assets.view", + "farmos_plant_types.list", + "farmos_plant_types.view", + "farmos_quantities_standard.list", + "farmos_quantities_standard.view", + "farmos_quantity_types.list", + "farmos_quantity_types.view", "farmos_structure_assets.list", "farmos_structure_assets.view", "farmos_structure_types.list", "farmos_structure_types.view", + "farmos_units.list", + "farmos_units.view", "farmos_users.list", "farmos_users.view", "group_assets.create", @@ -121,6 +131,7 @@ class CommonView(base.CommonView): "logs_observation.list", "logs_observation.view", "logs_observation.versions", + "quick.eggs", "structure_types.list", "structure_types.view", "structure_types.versions", From f4b5f3960c7b251ecee78170024d047c0ec58645 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Wed, 25 Feb 2026 15:22:25 -0600 Subject: [PATCH 5/5] fix: set log type, status enums for log grids --- src/wuttafarm/util.py | 37 +++++++++++++++++++++++++++++++ src/wuttafarm/web/views/assets.py | 7 ++++++ src/wuttafarm/web/views/logs.py | 22 ++++++++---------- 3 files changed, 53 insertions(+), 13 deletions(-) create mode 100644 src/wuttafarm/util.py diff --git a/src/wuttafarm/util.py b/src/wuttafarm/util.py new file mode 100644 index 0000000..1700998 --- /dev/null +++ b/src/wuttafarm/util.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8; -*- +################################################################################ +# +# WuttaFarm --Web app to integrate with and extend farmOS +# Copyright © 2026 Lance Edgar +# +# This file is part of WuttaFarm. +# +# WuttaFarm is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# WuttaFarm is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# WuttaFarm. If not, see . +# +################################################################################ +""" +misc. utilities +""" + +from collections import OrderedDict + + +def get_log_type_enum(config, session=None): + app = config.get_app() + model = app.model + log_types = OrderedDict() + with app.short_session(session=session) as sess: + query = sess.query(model.LogType).order_by(model.LogType.name) + for log_type in query: + log_types[log_type.drupal_id] = log_type.name + return log_types diff --git a/src/wuttafarm/web/views/assets.py b/src/wuttafarm/web/views/assets.py index b78f149..70534db 100644 --- a/src/wuttafarm/web/views/assets.py +++ b/src/wuttafarm/web/views/assets.py @@ -32,6 +32,7 @@ from wuttafarm.web.views import WuttaFarmMasterView from wuttafarm.db.model import Asset, Log from wuttafarm.web.forms.schema import AssetParentRefs from wuttafarm.web.forms.widgets import ImageWidget +from wuttafarm.util import get_log_type_enum def get_asset_type_enum(config): @@ -301,7 +302,12 @@ class AssetMasterView(WuttaFarmMasterView): def configure_row_grid(self, grid): g = grid super().configure_row_grid(g) + enum = self.app.enum model = self.app.model + session = self.Session() + + # status + g.set_enum("status", enum.LOG_STATUS) # drupal_id g.set_label("drupal_id", "ID", column_only=True) @@ -318,6 +324,7 @@ class AssetMasterView(WuttaFarmMasterView): # log_type g.set_sorter("log_type", model.Log.log_type) g.set_filter("log_type", model.Log.log_type) + g.set_enum("log_type", get_log_type_enum(self.config, session=session)) def get_row_action_url_view(self, log, i): return self.request.route_url(f"logs_{log.log_type}.view", uuid=log.uuid) diff --git a/src/wuttafarm/web/views/logs.py b/src/wuttafarm/web/views/logs.py index eeef49e..b393cec 100644 --- a/src/wuttafarm/web/views/logs.py +++ b/src/wuttafarm/web/views/logs.py @@ -34,17 +34,7 @@ from wuttaweb.forms.widgets import WuttaDateTimeWidget from wuttafarm.web.views import WuttaFarmMasterView from wuttafarm.db.model import LogType, Log from wuttafarm.web.forms.schema import LogAssetRefs - - -def get_log_type_enum(config): - app = config.get_app() - model = app.model - session = Session() - log_types = OrderedDict() - query = session.query(model.LogType).order_by(model.LogType.name) - for log_type in query: - log_types[log_type.drupal_id] = log_type.name - return log_types +from wuttafarm.util import get_log_type_enum class LogTypeView(WuttaFarmMasterView): @@ -142,6 +132,7 @@ class LogView(WuttaFarmMasterView): def configure_grid(self, grid): g = grid super().configure_grid(g) + session = self.Session() # drupal_id g.set_label("drupal_id", "ID", column_only=True) @@ -154,7 +145,7 @@ class LogView(WuttaFarmMasterView): g.set_link("message") # log_type - g.set_enum("log_type", get_log_type_enum(self.config)) + g.set_enum("log_type", get_log_type_enum(self.config, session=session)) # assets g.set_renderer("assets", self.render_assets_for_grid) @@ -224,8 +215,10 @@ class LogMasterView(WuttaFarmMasterView): g = grid super().configure_grid(g) model = self.app.model + enum = self.app.enum # status + g.set_enum("status", enum.LOG_STATUS) g.set_sorter("status", model.Log.status) g.set_filter("status", model.Log.status) @@ -255,6 +248,7 @@ class LogMasterView(WuttaFarmMasterView): f = form super().configure_form(f) enum = self.app.enum + session = self.Session() log = f.model_instance # timestamp @@ -280,7 +274,9 @@ class LogMasterView(WuttaFarmMasterView): else: f.set_node( "log_type", - WuttaDictEnum(self.request, get_log_type_enum(self.config)), + WuttaDictEnum( + self.request, get_log_type_enum(self.config, session=session) + ), ) f.set_readonly("log_type")