Skip to content

Commit

Permalink
guard views/dashboard by tugraz_authenticated
Browse files Browse the repository at this point in the history
  • Loading branch information
martinobersteiner committed Jul 8, 2024
1 parent 923d4e8 commit 4b8d5be
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (C) 2024 Graz University of Technology.
//
// invenio-theme-tugraz is free software; you can redistribute it and/or modify it
// under the terms of the MIT License; see LICENSE file for more details.

import $ from "jquery";

async function generateForm() {
// get email from `/api/me`
let email = "???";
const response = await fetch("/api/me");
if (response.ok) {
const json = await response.json();
email = json?.email || "???";
}

// show form
$.getScript("https://ub-support.tugraz.at/assets/form/form.js", () => {
$("#anchor-unlock-form").ZammadForm({
attributes: [
{},
{ defaultValue: email },
{
defaultValue: `Could you unlock my account (${email}) for research-uploads?`,
// TODO: add to defaultValue once policy on how to get accepted is decided...
},
],
modal: false,
});

// focus first entry of now-shown form
document.getElementById("zammad-form-name-inline").focus();
});
}

$(function () {
// called when DOM is ready
const generateFormElement = document.getElementById("generate-unlock-form");
if (generateFormElement) {
generateFormElement.onclick = generateForm;
}
});
30 changes: 29 additions & 1 deletion invenio_theme_tugraz/ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@

"""invenio module for TUGRAZ theme."""

from flask_login import login_required
from invenio_i18n import lazy_gettext as _
from invenio_records_marc21.ui.theme import current_identity_can_view

from . import config
from .views import index, locked
from .views import index, locked, require_tugraz_authenticated


class InvenioThemeTugraz(object):
Expand Down Expand Up @@ -48,6 +49,7 @@ def init_config(self, app):
def finalize_app(app):
"""Finalize app."""
modify_user_dashboard(app)
guard_view_functions(app)


def modify_user_dashboard(app):
Expand All @@ -66,3 +68,29 @@ def modify_user_dashboard(app):
_("My dashboard"),
order=1,
)


def guard_view_functions(app):
"""Guard view-functions against unauthenticated access."""
endpoints_to_guard = [
"invenio_app_rdm_users.communities",
"invenio_app_rdm_users.requests",
"invenio_app_rdm_users.uploads",
]

for endpoint in endpoints_to_guard:
view_func = app.view_functions.get(endpoint)
if not view_func:
continue

# decorate view-func
# same as if view-func were defined with:
# @login_required
# @require_tugraz_authenticated_user
view_func = login_required(
require_tugraz_authenticated(
view_func,
),
)

app.view_functions[endpoint] = view_func
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
{%- set active_dashboard_menu_item = "overview" %}
{%- set title = _("Overview") %}

{% block javascript %}
{{ super() }}
{{ webpack['invenio-theme-tugraz-unlock.js'] }}
{% endblock javascript %}

{%- block page_body %}
{%- block user_dashboard_header %}
{% include "invenio_app_rdm/users/header.html" %}
Expand All @@ -19,8 +24,9 @@
<div class="ui container rel-mt-2">
<h2>Overview</h2>


<div class="ui five column stackable grid overview">
{% if is_tugraz_authenticated %}
{# 3 columns: Research-Uploads, Communities, and Requests #}
<div class="column">
<div class="ui segment" style="height: 480px">
<h2>{{ _("Research Results") }}</h2>
Expand Down Expand Up @@ -54,6 +60,46 @@ <h2>{{ _("Requests") }}</h2>
</div>
</div>
</div>
{% else %} {# not is_tugraz_authenticated #}
{# 1 column: greyed out Research-Uploads #}
<div class="column">
{# a modal's HTML can be placed anywhere, so I placed it here, right before it's used #}
<div class="ui small modal" id="tugraz-unlock-modal">
<div class="header">{{ _("On unlocking research uploads") }}</div>
<div class="content">
<p>
{{ _('To ensure a well-curated repository, new users need to get unlocked
before being allowed to upload. Once unlocked, you can upload your research,
request its inclusion in a community, generate a DOI for it, and publish it.') }}
{# TODO: extra lines on policy about who gets accepted how for Research-Uploads #}
</p>
<div id="anchor-unlock-form"> {# will be replaced with ZammadForm when generating it #}
<button class="ui fluid button" onclick="
$('#tugraz-unlock-modal')
.modal('hide')"
>Got it!</button>
<button id="generate-unlock-form" class="ui fluid button">
{{ _("Request unlocking") }}
</button>
</div>
</div>
</div>

{# actual column contents start here #}
<div class="ui disabled segment" style="height: 480px">
<h2>{{ _("Research Results") }}</h2>
<div class="ui left floated image" style="cursor: pointer" onclick="
$('#tugraz-unlock-modal')
.modal('show')"
>
<img width="400px" alt="Research Results" src="{{ url_for("static", filename="images/diamond.svg") }}">
</div>
<div class="ui right floated text">
{{ _("Overview: Description for research results") }}
</div>
</div>
</div>
{% endif %}
{% if can_view_marc21 %}
<div class="column">
<div class="ui segment" style="height: 480px">
Expand Down
32 changes: 31 additions & 1 deletion invenio_theme_tugraz/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@

"""invenio module for TUGRAZ theme."""

from functools import wraps
from typing import Dict

from flask import Blueprint, g, render_template
from flask import Blueprint, g, redirect, render_template, url_for
from flask_login import current_user, login_required
from invenio_rdm_records.proxies import current_rdm_records
from invenio_records_global_search.resources.serializers import (
GlobalSearchJSONSerializer,
)
Expand All @@ -28,15 +30,43 @@
)


def current_identity_is_tugraz_authenticated() -> bool:
"""Checks whether current identity has tugraz-authentication.
NOTE: Default permission-policy has no field for `tugraz_authenticated`.
Should the field not exist, the service checks against admin-permissions instead.
You probably meant to configure a custom permission-policy.
"""
rdm_service = current_rdm_records.records_service
return rdm_service.check_permission(g.identity, "tugraz_authenticated")


def require_tugraz_authenticated(view_func):
"""Decorator for guarding view-functions against unauthenticated users.
Redirects un-authenticated users to their personal dashboard's overview.
"""

@wraps(view_func)
def decorated_view(*args, **kwargs):
if not current_identity_is_tugraz_authenticated():
return redirect(url_for("invenio_theme_tugraz.overview"))
return view_func(*args, **kwargs)

return decorated_view


@blueprint.route("/me/overview")
@login_required
def overview():
"""Overview."""
url = current_user_resources.users_service.links_item_tpl.expand(
g.identity, current_user
)["avatar"]
is_tugraz_authenticated = current_identity_is_tugraz_authenticated()
return render_template(
"invenio_theme_tugraz/overview.html",
is_tugraz_authenticated=is_tugraz_authenticated,
user_avatar=url,
)

Expand Down
3 changes: 2 additions & 1 deletion invenio_theme_tugraz/webpack.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
entry={
"invenio-theme-tugraz-theme": "./less/invenio_theme_tugraz/theme.less",
"invenio-theme-tugraz-js": "./js/invenio_theme_tugraz/theme.js",
"invenio-theme-tugraz-unlock": "./js/invenio_theme_tugraz/unlock.js",
},
dependencies={
# add any additional npm dependencies here...
"jquery": "^3.2.1", # zammad-form, semantic-ui's modals
},
)
},
Expand Down

0 comments on commit 4b8d5be

Please sign in to comment.