Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions templates/error.html
Original file line number Diff line number Diff line change
Expand Up @@ -156,19 +156,24 @@ <h1 class="error-title">{{ error }}</h1>
{{ error_message }}
</div>

{% if link %}
<div class="error-link">
<a href="{{ link }}" target="_blank">{{ link }}</a>
</div>
{% endif %}

<div class="error-actions">
<button type="button" onclick="history.back()" class="btn-error-secondary">
← Back
</button>
{% if link %}
{# A supplied link is the recommended next step: make it the
primary action (in-page) and demote Dashboard to secondary. #}
<a href="{{ link }}" class="btn-error-primary">
{{ link_text if link_text else link }} →
</a>
<a href="/dashboard" class="btn-error-secondary">
Dashboard →
</a>
{% else %}
<a href="/dashboard" class="btn-error-primary">
Dashboard →
</a>
{% endif %}
</div>
</div>
</div>
Expand Down
42 changes: 42 additions & 0 deletions tests/test_setup_required.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""The 'Setup Required' error must link the user to /setup.

Creating a jamfpro/okta automation before JAWA is configured raises
AutomationError("Setup Required", ...). The error page must give the
admin a direct, in-page way to reach /setup instead of dead-ending.
"""

import json


def _unconfigure_jawa(jawa_env):
# Remove jawa_address so get_jawa_address() is falsy -> Setup Required.
jawa_env.server_file.write_text(json.dumps({"brand": "JAWA"}))


def test_jamfpro_new_without_jawa_links_to_setup(logged_in_client, jawa_env):
_unconfigure_jawa(jawa_env)
resp = logged_in_client.post(
"/automations/jamfpro/new",
data={"webhook_name": "test-hook"},
)
body = resp.data.decode()
assert "Setup Required" in body
# The page offers a direct link to /setup (the action the user needs).
assert 'href="/setup"' in body
# Friendly label, not the raw path as the only text.
assert "Go to Setup" in body
# Internal navigation -- not a new tab.
assert 'href="/setup" target="_blank"' not in body


def test_okta_new_without_jawa_links_to_setup(logged_in_client, jawa_env):
_unconfigure_jawa(jawa_env)
# Okta's handler reads the name from "webhookname" (no underscore).
resp = logged_in_client.post(
"/automations/okta/new",
data={"webhookname": "test-okta"},
)
body = resp.data.decode()
assert "Setup Required" in body
assert 'href="/setup"' in body
assert "Go to Setup" in body
9 changes: 8 additions & 1 deletion views/_type_handlers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,18 @@ class AutomationError(Exception):
"""Raised when an automation operation fails."""

def __init__(
self, title: str, message: str, link: Optional[str] = None
self,
title: str,
message: str,
link: Optional[str] = None,
link_text: Optional[str] = None,
) -> None:
self.title = title
self.message = message
self.link = link
# Friendly label for the link when rendered as an action button;
# falls back to the raw link if omitted.
self.link_text = link_text
super().__init__(message)


Expand Down
6 changes: 5 additions & 1 deletion views/_type_handlers/jamf_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,11 @@ def process_create(
server_address = get_jawa_address()
if not server_address:
raise AutomationError(
"Setup Required", "Please configure JAWA address first."
"Setup Required",
"Configure your JAWA address and Jamf Pro server "
"before creating an automation.",
link="/setup",
link_text="Go to Setup",
)

# Ensure token is valid
Expand Down
6 changes: 5 additions & 1 deletion views/_type_handlers/okta_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ def process_create(
server_address = get_jawa_address()
if not server_address:
raise AutomationError(
"Setup Required", "Please configure JAWA address first."
"Setup Required",
"Configure your JAWA address and Jamf Pro server "
"before creating an automation.",
link="/setup",
link_text="Go to Setup",
)

# Ensure okta verification file is executable
Expand Down
9 changes: 6 additions & 3 deletions views/automation_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,15 @@ def _get_session_data() -> dict:
}


def _error_page(title: str, message: str, link: str = None) -> str:
def _error_page(
title: str, message: str, link: str = None, link_text: str = None
) -> str:
return render_template(
"error.html",
error=title,
error_message=message,
link=link,
link_text=link_text,
username=session.get("username"),
)

Expand Down Expand Up @@ -175,7 +178,7 @@ def create(auto_type: str) -> Union[Response, str]:
request.form, request.files, session_data
)
except AutomationError as err:
return _error_page(err.title, err.message, err.link)
return _error_page(err.title, err.message, err.link, err.link_text)

# Persist the entry
entry = result.get("entry")
Expand Down Expand Up @@ -288,7 +291,7 @@ def edit(auto_type: str, name: str) -> Union[Response, str]:
all_items,
)
except AutomationError as err:
return _error_page(err.title, err.message, err.link)
return _error_page(err.title, err.message, err.link, err.link_text)

return render_template(
SUCCESS_TEMPLATE,
Expand Down
Loading