diff --git a/src/spiffworkflow_backend/models/group.py b/src/spiffworkflow_backend/models/group.py
index b8928d73..3b7edd6c 100644
--- a/src/spiffworkflow_backend/models/group.py
+++ b/src/spiffworkflow_backend/models/group.py
@@ -14,6 +14,10 @@ if TYPE_CHECKING:
from spiffworkflow_backend.models.user import UserModel # noqa: F401
+class GroupNotFoundError(Exception):
+ """GroupNotFoundError."""
+
+
class GroupModel(FlaskBpmnGroupModel):
"""GroupModel."""
diff --git a/src/spiffworkflow_backend/scripts/get_user.py b/src/spiffworkflow_backend/scripts/get_current_user.py
similarity index 100%
rename from src/spiffworkflow_backend/scripts/get_user.py
rename to src/spiffworkflow_backend/scripts/get_current_user.py
diff --git a/src/spiffworkflow_backend/scripts/get_frontend_url.py b/src/spiffworkflow_backend/scripts/get_frontend_url.py
new file mode 100644
index 00000000..40dc482c
--- /dev/null
+++ b/src/spiffworkflow_backend/scripts/get_frontend_url.py
@@ -0,0 +1,25 @@
+"""Get_env."""
+from typing import Any
+from flask import current_app
+
+from spiffworkflow_backend.models.script_attributes_context import (
+ ScriptAttributesContext,
+)
+from spiffworkflow_backend.scripts.script import Script
+
+
+class GetFrontendUrl(Script):
+ """GetFrontendUrl."""
+
+ def get_description(self) -> str:
+ """Get_description."""
+ return """Return the url to the frontend."""
+
+ def run(
+ self,
+ script_attributes_context: ScriptAttributesContext,
+ *args: Any,
+ **kwargs: Any
+ ) -> Any:
+ """Run."""
+ return current_app.config['SPIFFWORKFLOW_FRONTEND_URL']
diff --git a/src/spiffworkflow_backend/scripts/get_group_members.py b/src/spiffworkflow_backend/scripts/get_group_members.py
new file mode 100644
index 00000000..243a8c52
--- /dev/null
+++ b/src/spiffworkflow_backend/scripts/get_group_members.py
@@ -0,0 +1,34 @@
+"""Get_env."""
+from typing import Any
+
+from spiffworkflow_backend.models.group import GroupModel
+from spiffworkflow_backend.models.group import GroupNotFoundError
+from spiffworkflow_backend.models.script_attributes_context import (
+ ScriptAttributesContext,
+)
+from spiffworkflow_backend.scripts.script import Script
+
+
+class GetGroupMembers(Script):
+ """GetGroupMembers."""
+
+ def get_description(self) -> str:
+ """Get_description."""
+ return """Return the list of usernames of the users in the given group."""
+
+ def run(
+ self,
+ script_attributes_context: ScriptAttributesContext,
+ *args: Any,
+ **kwargs: Any,
+ ) -> Any:
+ """Run."""
+ group_identifier = args[0]
+ group = GroupModel.query.filter_by(identifier=group_identifier).first()
+ if group is None:
+ raise GroupNotFoundError(
+ f"Script 'get_group_members' could not find group with identifier '{group_identifier}'."
+ )
+
+ usernames = [u.username for u in group.users]
+ return usernames
diff --git a/tests/data/get_group_members/get_group_members.bpmn b/tests/data/get_group_members/get_group_members.bpmn
new file mode 100644
index 00000000..23f6df07
--- /dev/null
+++ b/tests/data/get_group_members/get_group_members.bpmn
@@ -0,0 +1,52 @@
+
+
+
+
+ Flow_1j4jzft
+
+
+
+ Flow_01xr2ac
+
+
+ Flow_1j4jzft
+ Flow_10xyk22
+ members_a = get_group_members("GroupA")
+
+
+
+ Flow_10xyk22
+ Flow_01xr2ac
+ members_b = get_group_members("GroupB")
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/data/model_with_lanes/lanes_with_owner_dict.bpmn b/tests/data/model_with_lanes/lanes_with_owner_dict.bpmn
index 2b89acb0..1a6b52cb 100644
--- a/tests/data/model_with_lanes/lanes_with_owner_dict.bpmn
+++ b/tests/data/model_with_lanes/lanes_with_owner_dict.bpmn
@@ -81,7 +81,7 @@
Flow_0bgkfue
Flow_1ivhu7x
- approver = get_user()
+ approver = get_current_user()
lane_owners["Finance Team"].remove(approver)
diff --git a/tests/spiffworkflow_backend/scripts/test_get_group_members.py b/tests/spiffworkflow_backend/scripts/test_get_group_members.py
new file mode 100644
index 00000000..34a144db
--- /dev/null
+++ b/tests/spiffworkflow_backend/scripts/test_get_group_members.py
@@ -0,0 +1,52 @@
+"""Test_get_localtime."""
+from flask.app import Flask
+from flask_bpmn.models.db import db
+from tests.spiffworkflow_backend.helpers.base_test import BaseTest
+from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
+
+from spiffworkflow_backend.models.group import GroupModel
+from spiffworkflow_backend.services.process_instance_processor import (
+ ProcessInstanceProcessor,
+)
+from spiffworkflow_backend.services.user_service import UserService
+
+
+class TestGetGroupMembers(BaseTest):
+ """TestGetGroupMembers."""
+
+ def test_can_get_members_of_a_group(
+ self,
+ app: Flask,
+ with_db_and_bpmn_file_cleanup: None,
+ ) -> None:
+ """Test_can_get_members_of_a_group."""
+ initiator_user = self.find_or_create_user("initiator_user")
+ testuser1 = self.find_or_create_user("testuser1")
+ testuser2 = self.find_or_create_user("testuser2")
+ testuser3 = self.find_or_create_user("testuser3")
+ group_a = GroupModel(identifier="groupA")
+ group_b = GroupModel(identifier="groupB")
+ db.session.add(group_a)
+ db.session.add(group_b)
+ db.session.commit()
+
+ UserService.add_user_to_group(testuser1, group_a)
+ UserService.add_user_to_group(testuser2, group_a)
+ UserService.add_user_to_group(testuser3, group_b)
+
+ process_model = load_test_spec(
+ process_model_id="get_group_members",
+ bpmn_file_name="get_group_members.bpmn",
+ )
+ process_instance = self.create_process_instance_from_process_model(
+ process_model=process_model, user=initiator_user
+ )
+ processor = ProcessInstanceProcessor(process_instance)
+ processor.do_engine_steps(save=True)
+
+ assert processor.bpmn_process_instance.data
+ assert processor.bpmn_process_instance.data["members_a"] == [
+ "testuser1",
+ "testuser2",
+ ]
+ assert processor.bpmn_process_instance.data["members_b"] == ["testuser3"]