Skip to content

Commit dc14da9

Browse files
authored
3110 dashboard design feedback & permission changes (#3142)
* update org dashboard * allowing org admins to access serviecs within an org * fix test
1 parent 957c3ee commit dc14da9

File tree

20 files changed

+115
-111
lines changed

20 files changed

+115
-111
lines changed

app/main/views/activity.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def get_filtered_jobs(service_id, page):
123123

124124

125125
@main.route("/activity/services/<uuid:service_id>")
126-
@user_has_permissions(ServicePermission.VIEW_ACTIVITY)
126+
@user_has_permissions(ServicePermission.VIEW_ACTIVITY, allow_org_user=True)
127127
def all_jobs_activity(service_id):
128128
service_data_retention_days = 8
129129
page = get_page_from_request()

app/main/views/api_keys.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424

2525
@main.route("/services/<uuid:service_id>/api")
26-
@user_has_permissions("manage_api_keys")
26+
@user_has_permissions("manage_api_keys", allow_org_user=True)
2727
def api_integration(service_id):
2828
callbacks_link = (
2929
".api_callbacks"
@@ -40,7 +40,7 @@ def api_integration(service_id):
4040

4141

4242
@main.route("/services/<uuid:service_id>/api/documentation")
43-
@user_has_permissions("manage_api_keys")
43+
@user_has_permissions("manage_api_keys", allow_org_user=True)
4444
def api_documentation(service_id):
4545
return redirect(url_for(".documentation"), code=301)
4646

@@ -51,7 +51,7 @@ def api_documentation(service_id):
5151
endpoint="old_guest_list",
5252
)
5353
@main.route("/services/<uuid:service_id>/api/guest-list", methods=["GET", "POST"])
54-
@user_has_permissions("manage_api_keys")
54+
@user_has_permissions("manage_api_keys", allow_org_user=True)
5555
def guest_list(service_id):
5656
form = GuestList()
5757
if form.validate_on_submit():
@@ -70,15 +70,15 @@ def guest_list(service_id):
7070

7171

7272
@main.route("/services/<uuid:service_id>/api/keys")
73-
@user_has_permissions("manage_api_keys")
73+
@user_has_permissions("manage_api_keys", allow_org_user=True)
7474
def api_keys(service_id):
7575
return render_template(
7676
"views/api/keys.html",
7777
)
7878

7979

8080
@main.route("/services/<uuid:service_id>/api/keys/create", methods=["GET", "POST"])
81-
@user_has_permissions("manage_api_keys", restrict_admin_usage=True)
81+
@user_has_permissions("manage_api_keys", restrict_admin_usage=True, allow_org_user=True)
8282
def create_api_key(service_id):
8383
form = CreateKeyForm(current_service.api_keys)
8484
form.key_type.choices = [
@@ -118,7 +118,7 @@ def create_api_key(service_id):
118118
@main.route(
119119
"/services/<uuid:service_id>/api/keys/revoke/<uuid:key_id>", methods=["GET", "POST"]
120120
)
121-
@user_has_permissions("manage_api_keys")
121+
@user_has_permissions("manage_api_keys", allow_org_user=True)
122122
def revoke_api_key(service_id, key_id):
123123
key_name = current_service.get_api_key(key_id)["name"]
124124
if request.method == "GET":
@@ -161,7 +161,7 @@ def check_token_against_dummy_bearer(token):
161161

162162

163163
@main.route("/services/<uuid:service_id>/api/callbacks", methods=["GET"])
164-
@user_has_permissions("manage_api_keys")
164+
@user_has_permissions("manage_api_keys", allow_org_user=True)
165165
def api_callbacks(service_id):
166166
if not current_service.has_permission(ServicePermission.INBOUND_SMS):
167167
return redirect(url_for(".delivery_status_callback", service_id=service_id))
@@ -192,7 +192,7 @@ def get_delivery_status_callback_details():
192192
"/services/<uuid:service_id>/api/callbacks/delivery-status-callback",
193193
methods=["GET", "POST"],
194194
)
195-
@user_has_permissions("manage_api_keys")
195+
@user_has_permissions("manage_api_keys", allow_org_user=True)
196196
def delivery_status_callback(service_id):
197197
delivery_status_callback = get_delivery_status_callback_details()
198198
back_link = (
@@ -259,7 +259,7 @@ def get_received_text_messages_callback():
259259
"/services/<uuid:service_id>/api/callbacks/received-text-messages-callback",
260260
methods=["GET", "POST"],
261261
)
262-
@user_has_permissions("manage_api_keys")
262+
@user_has_permissions("manage_api_keys", allow_org_user=True)
263263
def received_text_messages_callback(service_id):
264264
if not current_service.has_permission(ServicePermission.INBOUND_SMS):
265265
return redirect(url_for(".api_integration", service_id=service_id))

app/main/views/conversation.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414

1515
@main.route("/services/<uuid:service_id>/conversation/<uuid:notification_id>")
16-
@user_has_permissions(ServicePermission.VIEW_ACTIVITY)
16+
@user_has_permissions(ServicePermission.VIEW_ACTIVITY, allow_org_user=True)
1717
def conversation(service_id, notification_id):
1818
user_number = get_user_number(service_id, notification_id)
1919

@@ -31,7 +31,7 @@ def conversation(service_id, notification_id):
3131

3232

3333
@main.route("/services/<uuid:service_id>/conversation/<uuid:notification_id>.json")
34-
@user_has_permissions(ServicePermission.VIEW_ACTIVITY)
34+
@user_has_permissions(ServicePermission.VIEW_ACTIVITY, allow_org_user=True)
3535
def conversation_updates(service_id, notification_id):
3636
return jsonify(
3737
get_conversation_partials(
@@ -46,7 +46,7 @@ def conversation_updates(service_id, notification_id):
4646
@main.route(
4747
"/services/<uuid:service_id>/conversation/<uuid:notification_id>/reply-with/from-folder/<uuid:from_folder>"
4848
)
49-
@user_has_permissions(ServicePermission.SEND_MESSAGES)
49+
@user_has_permissions(ServicePermission.SEND_MESSAGES, allow_org_user=True)
5050
def conversation_reply(
5151
service_id,
5252
notification_id,
@@ -70,7 +70,7 @@ def conversation_reply(
7070
@main.route(
7171
"/services/<uuid:service_id>/conversation/<uuid:notification_id>/reply-with/<uuid:template_id>"
7272
)
73-
@user_has_permissions(ServicePermission.SEND_MESSAGES)
73+
@user_has_permissions(ServicePermission.SEND_MESSAGES, allow_org_user=True)
7474
def conversation_reply_with_template(
7575
service_id,
7676
notification_id,

app/main/views/dashboard.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@
2424

2525

2626
@main.route("/services/<uuid:service_id>/dashboard")
27-
@user_has_permissions(ServicePermission.VIEW_ACTIVITY, ServicePermission.SEND_MESSAGES)
27+
@user_has_permissions(ServicePermission.VIEW_ACTIVITY, ServicePermission.SEND_MESSAGES, allow_org_user=True)
2828
def old_service_dashboard(service_id):
2929
return redirect(url_for(".service_dashboard", service_id=service_id))
3030

3131

3232
@main.route("/services/<uuid:service_id>")
33-
@user_has_permissions()
33+
@user_has_permissions(allow_org_user=True)
3434
def service_dashboard(service_id):
3535

3636
if session.get("invited_user_id"):
@@ -84,7 +84,7 @@ def job_is_finished(job_dict):
8484

8585

8686
@main.route("/services/<uuid:service_id>/daily-stats.json")
87-
@user_has_permissions()
87+
@user_has_permissions(allow_org_user=True)
8888
def get_daily_stats(service_id):
8989
date_range = get_stats_date_range()
9090
days = date_range["days"]
@@ -148,7 +148,7 @@ def get_local_daily_stats_for_last_x_days(stats_utc, user_timezone, days):
148148

149149

150150
@main.route("/services/<uuid:service_id>/daily-stats-by-user.json")
151-
@user_has_permissions()
151+
@user_has_permissions(allow_org_user=True)
152152
def get_daily_stats_by_user(service_id):
153153
date_range = get_stats_date_range()
154154
days = date_range["days"]
@@ -166,7 +166,7 @@ def get_daily_stats_by_user(service_id):
166166

167167

168168
@main.route("/services/<uuid:service_id>/template-usage")
169-
@user_has_permissions(ServicePermission.VIEW_ACTIVITY)
169+
@user_has_permissions(ServicePermission.VIEW_ACTIVITY, allow_org_user=True)
170170
def template_usage(service_id):
171171
year, current_financial_year = requested_and_current_financial_year(request)
172172
stats = template_statistics_client.get_monthly_template_usage_for_service(

app/main/views/history.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212

1313
@main.route("/services/<uuid:service_id>/history")
14-
@user_has_permissions(ServicePermission.MANAGE_SERVICE)
14+
@user_has_permissions(ServicePermission.MANAGE_SERVICE, allow_org_user=True)
1515
def history(service_id):
1616
events = _get_events(current_service.id, request.args.get("selected"))
1717

app/main/views/jobs.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727

2828
@main.route("/services/<uuid:service_id>/jobs")
29-
@user_has_permissions()
29+
@user_has_permissions(allow_org_user=True)
3030
def view_jobs(service_id):
3131
return redirect(
3232
url_for(
@@ -37,7 +37,7 @@ def view_jobs(service_id):
3737

3838

3939
@main.route("/services/<uuid:service_id>/jobs/<uuid:job_id>")
40-
@user_has_permissions()
40+
@user_has_permissions(allow_org_user=True)
4141
def view_job(service_id, job_id):
4242
job = Job.from_id(job_id, service_id=current_service.id)
4343
if job.cancelled:
@@ -83,7 +83,7 @@ def view_job(service_id, job_id):
8383

8484

8585
@main.route("/services/<uuid:service_id>/jobs/<uuid:job_id>.csv")
86-
@user_has_permissions(ServicePermission.VIEW_ACTIVITY)
86+
@user_has_permissions(ServicePermission.VIEW_ACTIVITY, allow_org_user=True)
8787
def view_job_csv(service_id, job_id):
8888
job = Job.from_id(job_id, service_id=service_id)
8989
filter_args = parse_filter_args(request.args)
@@ -111,14 +111,14 @@ def view_job_csv(service_id, job_id):
111111

112112

113113
@main.route("/services/<uuid:service_id>/jobs/<uuid:job_id>", methods=["POST"])
114-
@user_has_permissions(ServicePermission.SEND_MESSAGES)
114+
@user_has_permissions(ServicePermission.SEND_MESSAGES, allow_org_user=True)
115115
def cancel_job(service_id, job_id):
116116
Job.from_id(job_id, service_id=service_id).cancel()
117117
return redirect(url_for("main.service_dashboard", service_id=service_id))
118118

119119

120120
@main.route("/services/<uuid:service_id>/jobs/<uuid:job_id>/status.json")
121-
@user_has_permissions()
121+
@user_has_permissions(allow_org_user=True)
122122
def view_job_status_poll(service_id, job_id):
123123
from app.notify_client.job_api_client import job_api_client
124124

@@ -147,7 +147,7 @@ def view_job_status_poll(service_id, job_id):
147147

148148

149149
@main.route("/services/<uuid:service_id>/jobs/<uuid:job_id>/notifications-table")
150-
@user_has_permissions()
150+
@user_has_permissions(allow_org_user=True)
151151
def view_job_notifications_table(service_id, job_id):
152152
"""Endpoint that returns only the notifications table HTML fragment."""
153153
job = Job.from_id(job_id, service_id=current_service.id)

app/main/views/manage_users.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def manage_users(service_id):
4444
@main.route(
4545
"/services/<uuid:service_id>/users/invite/<uuid:user_id>", methods=["GET", "POST"]
4646
)
47-
@user_has_permissions(ServicePermission.MANAGE_SERVICE)
47+
@user_has_permissions(ServicePermission.MANAGE_SERVICE, allow_org_user=True)
4848
def invite_user(service_id, user_id=None):
4949
form_class = InviteUserForm
5050
form = form_class(
@@ -116,7 +116,7 @@ def invite_user(service_id, user_id=None):
116116

117117

118118
@main.route("/services/<uuid:service_id>/users/<uuid:user_id>", methods=["GET", "POST"])
119-
@user_has_permissions(ServicePermission.MANAGE_SERVICE)
119+
@user_has_permissions(ServicePermission.MANAGE_SERVICE, allow_org_user=True)
120120
def edit_user_permissions(service_id, user_id):
121121
service_has_email_auth = current_service.has_permission(
122122
ServicePermission.EMAIL_AUTH
@@ -169,7 +169,7 @@ def edit_user_permissions(service_id, user_id):
169169

170170

171171
@main.route("/services/<uuid:service_id>/users/<uuid:user_id>/delete", methods=["POST"])
172-
@user_has_permissions(ServicePermission.MANAGE_SERVICE)
172+
@user_has_permissions(ServicePermission.MANAGE_SERVICE, allow_org_user=True)
173173
def remove_user_from_service(service_id, user_id):
174174
try:
175175
service_api_client.remove_user_from_service(service_id, user_id)
@@ -192,7 +192,7 @@ def remove_user_from_service(service_id, user_id):
192192
"/services/<uuid:service_id>/users/<uuid:user_id>/edit-email",
193193
methods=["GET", "POST"],
194194
)
195-
@user_has_permissions(ServicePermission.MANAGE_SERVICE)
195+
@user_has_permissions(ServicePermission.MANAGE_SERVICE, allow_org_user=True)
196196
def edit_user_email(service_id, user_id):
197197
user = current_service.get_team_member(user_id)
198198
user_email = user.email_address
@@ -225,7 +225,7 @@ def edit_user_email(service_id, user_id):
225225
"/services/<uuid:service_id>/users/<uuid:user_id>/edit-email/confirm",
226226
methods=["GET", "POST"],
227227
)
228-
@user_has_permissions(ServicePermission.MANAGE_SERVICE)
228+
@user_has_permissions(ServicePermission.MANAGE_SERVICE, allow_org_user=True)
229229
def confirm_edit_user_email(service_id, user_id):
230230
user = current_service.get_team_member(user_id)
231231
session_key = "team_member_email_change-{}".format(user_id)
@@ -263,7 +263,7 @@ def confirm_edit_user_email(service_id, user_id):
263263
"/services/<uuid:service_id>/users/<uuid:user_id>/edit-mobile-number",
264264
methods=["GET", "POST"],
265265
)
266-
@user_has_permissions(ServicePermission.MANAGE_SERVICE)
266+
@user_has_permissions(ServicePermission.MANAGE_SERVICE, allow_org_user=True)
267267
def edit_user_mobile_number(service_id, user_id):
268268
user = current_service.get_team_member(user_id)
269269
user_mobile_number = redact_mobile_number(user.mobile_number)
@@ -293,7 +293,7 @@ def edit_user_mobile_number(service_id, user_id):
293293
"/services/<uuid:service_id>/users/<uuid:user_id>/edit-mobile-number/confirm",
294294
methods=["GET", "POST"],
295295
)
296-
@user_has_permissions(ServicePermission.MANAGE_SERVICE)
296+
@user_has_permissions(ServicePermission.MANAGE_SERVICE, allow_org_user=True)
297297
def confirm_edit_user_mobile_number(service_id, user_id):
298298
user = current_service.get_team_member(user_id)
299299
if "team_member_mobile_change" in session:
@@ -331,7 +331,7 @@ def confirm_edit_user_mobile_number(service_id, user_id):
331331
"/services/<uuid:service_id>/cancel-invited-user/<uuid:invited_user_id>",
332332
methods=["GET"],
333333
)
334-
@user_has_permissions(ServicePermission.MANAGE_SERVICE)
334+
@user_has_permissions(ServicePermission.MANAGE_SERVICE, allow_org_user=True)
335335
def cancel_invited_user(service_id, invited_user_id):
336336
current_service.cancel_invite(invited_user_id)
337337

@@ -350,7 +350,7 @@ def cancel_invited_user(service_id, invited_user_id):
350350
"/services/<uuid:service_id>/resend-invite/<uuid:invited_user_id>",
351351
methods=["GET"],
352352
)
353-
@user_has_permissions(ServicePermission.MANAGE_SERVICE)
353+
@user_has_permissions(ServicePermission.MANAGE_SERVICE, allow_org_user=True)
354354
def resend_invite(service_id, invited_user_id):
355355
current_service.resend_invite(invited_user_id)
356356

app/main/views/notifications.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535

3636

3737
@main.route("/services/<uuid:service_id>/notification/<uuid:notification_id>")
38-
@user_has_permissions(ServicePermission.VIEW_ACTIVITY, ServicePermission.SEND_MESSAGES)
38+
@user_has_permissions(ServicePermission.VIEW_ACTIVITY, ServicePermission.SEND_MESSAGES, allow_org_user=True)
3939
def view_notification(service_id, notification_id, error_message=None):
4040
if error_message:
4141
flash(error_message)
@@ -108,7 +108,7 @@ def view_notification(service_id, notification_id, error_message=None):
108108

109109

110110
@main.route("/services/<uuid:service_id>/notification/<uuid:notification_id>.json")
111-
@user_has_permissions(ServicePermission.VIEW_ACTIVITY, ServicePermission.SEND_MESSAGES)
111+
@user_has_permissions(ServicePermission.VIEW_ACTIVITY, ServicePermission.SEND_MESSAGES, allow_org_user=True)
112112
def view_notification_updates(service_id, notification_id):
113113
return jsonify(
114114
**get_single_notification_partials(
@@ -149,7 +149,7 @@ def get_all_personalisation_from_notification(notification):
149149

150150

151151
@main.route("/services/<uuid:service_id>/download-notifications.csv")
152-
@user_has_permissions(ServicePermission.VIEW_ACTIVITY)
152+
@user_has_permissions(ServicePermission.VIEW_ACTIVITY, allow_org_user=True)
153153
def download_notifications_csv(service_id):
154154
set_timezone()
155155
filter_args = parse_filter_args(request.args)

app/main/views/organizations.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,10 @@ def get_services_dashboard_data(organization, year):
241241
if sms_sent > 0 or sms_remainder > 0:
242242
if sms_cost > 0:
243243
usage_parts.append(
244-
f"{sms_sent:,} sms ({sms_remainder:,} remaining, ${sms_cost:,.2f})"
244+
f"{sms_sent:,} sms ({sms_remainder:,} message parts remaining, ${sms_cost:,.2f})"
245245
)
246246
else:
247-
usage_parts.append(f"{sms_sent:,} sms ({sms_remainder:,} remaining)")
247+
usage_parts.append(f"{sms_sent:,} sms ({sms_remainder:,} message parts remaining)")
248248

249249
service["usage"] = ", ".join(usage_parts) if usage_parts else "No usage"
250250

0 commit comments

Comments
 (0)