Skip to content

Commit

Permalink
WD-12132-create-decorator-to-restrict-views (#13952)
Browse files Browse the repository at this point in the history
* new decorator works

* added latest reservations to dashboard

* wip, getting latest stuff

* format-python
  • Loading branch information
abhigyanghosh30 committed Jun 14, 2024
1 parent 9c3ac70 commit 1cc7940
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 3 deletions.
35 changes: 35 additions & 0 deletions templates/credentials/dashboard.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{% extends "credentials/base_cred.html" %}

{% block title %}Canonical Credentials -- Dashboard{% endblock %}

{% block meta_description %}
The Canonical Ubuntu Essentials exams certify knowledge and verify skills in general Linux,
Ubuntu Desktop, and Ubuntu Server topics.
{% endblock meta_description %}

{% block content %}

<section class="p-strip is-paper">
<table>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Starts At</th>
<th>Exam Name</th>
</tr>
</thead>
<tbody>
{% for reservation in latest_reservations %}
<tr>
<td>{{ reservation["user"]["full_name"] }}</td>
<td>{{ reservation["user"]["email"] }}</td>
<td>{{ reservation["starts_at"] }}</td>
<td>{{ reservation["ability_screen"]["display_name"] }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</section>

{% endblock %}
4 changes: 4 additions & 0 deletions webapp/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
cred_assessments,
cred_beta_activation,
cred_cancel_exam,
cred_dashboard,
cred_exam,
cred_home,
cred_redeem_code,
Expand Down Expand Up @@ -934,6 +935,9 @@ def takeovers_index():
view_func=issue_badges,
methods=["POST"],
)
app.add_url_rule(
"/credentials/dashboard", view_func=cred_dashboard, methods=["GET"]
)

app.add_url_rule(
"/credentials/get_issued_badges",
Expand Down
8 changes: 7 additions & 1 deletion webapp/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
)

COMMUNITY_TEAM = "ubuntumembers"
CREDENTIALS_TEAM = "canonical-credentials"

login_url = os.getenv("CANONICAL_LOGIN_URL", "https://login.ubuntu.com")

Expand All @@ -39,6 +40,9 @@ def user_info(user_session):
"is_community_member": (
user_session["openid"].get("is_community_member", False)
),
"is_credentials_admin": (
user_session["openid"].get("is_credentials_admin", False)
),
}
else:
return None
Expand Down Expand Up @@ -86,7 +90,7 @@ def login_handler():
extensions=[
openid_macaroon,
TeamsRequest(
query_membership=[COMMUNITY_TEAM],
query_membership=[COMMUNITY_TEAM, CREDENTIALS_TEAM],
lp_ns_uri="http://ns.launchpad.net/2007/openid-teams",
),
],
Expand Down Expand Up @@ -116,6 +120,7 @@ def after_login(resp):
return flask.redirect(login_url)

is_community_member = COMMUNITY_TEAM in resp.extensions["lp"].is_member
is_credentials_admin = CREDENTIALS_TEAM in resp.extensions["lp"].is_member

flask.session["openid"] = {
"identity_url": resp.identity_url,
Expand All @@ -124,6 +129,7 @@ def after_login(resp):
"image": resp.image,
"email": resp.email,
"is_community_member": is_community_member,
"is_credentials_admin": is_credentials_admin,
}

return flask.redirect(open_id.get_next_url())
Expand Down
4 changes: 2 additions & 2 deletions webapp/shop/api/trueability/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ def update_ability_screen(self):
pass

def get_assessment_reservation(self, uuid: str = ""):
uri = f"/api/v1//assessment_reservations/{uuid}"
uri = f"/api/v1/assessment_reservations/{uuid}"
return self.make_request("GET", uri).json()

def get_assessment_reservations(
self, ability_screen_id: int = None, page: int = 1, per_page: int = 500
self, ability_screen_id: int = None, page: int = 1, per_page: int = 50
):
params = {
"ability_screen_id": ability_screen_id,
Expand Down
17 changes: 17 additions & 0 deletions webapp/shop/cred/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
has_filed_confidentiality_agreement,
)
from webapp.shop.decorators import (
credentials_group,
shop_decorator,
canonical_staff,
get_trueability_api_instance,
Expand Down Expand Up @@ -1191,3 +1192,19 @@ def get_cue_products(ua_contracts_api, type, **kwargs):
or (type == "exam")
]
return flask.jsonify(filtered_products)


@shop_decorator(area="cred", permission="user", response="html")
@credentials_group()
def cred_dashboard(trueability_api, **_):
first_reservations = trueability_api.get_assessment_reservations(
per_page=10
)
last_page = first_reservations["meta"]["total_pages"]
latest_reservations = trueability_api.get_assessment_reservations(
page=last_page, per_page=10
)
return flask.render_template(
"credentials/dashboard.html",
latest_reservations=latest_reservations["assessment_reservations"],
)
19 changes: 19 additions & 0 deletions webapp/shop/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,25 @@ def decorated_function(*args, **kwargs):
return decorator


def credentials_group():
def decorator(func):
@wraps(func)
def decorated_function(*args, **kwargs):
sso_user = user_info(flask.session)
if (
sso_user
and sso_user.get("is_credentials_admin", False) is True
):
return func(*args, **kwargs)

message = {"error": "unauthorized"}
return flask.jsonify(message), 403

return decorated_function

return decorator


def init_badgr_session(area) -> Session:
if area != "cred":
return None
Expand Down

0 comments on commit 1cc7940

Please sign in to comment.