Skip to content
Snippets Groups Projects
Commit 4660624b authored by Weblate's avatar Weblate
Browse files

Merge remote-tracking branch 'origin/master'

parents a337ea64 0d39d5f5
No related branches found
No related tags found
1 merge request!1004Translations update from Weblate
Pipeline #68255 passed with warnings
......@@ -26,12 +26,16 @@ Fixed
* Due to a merge error, the once removed account menu in the sidenav appeared again.
* Scheduled notifications were shown on dashboard before time.
* Remove broken notifications menu item in favor of item next to account menu.
* [OAuth2] Resources which are protected with client credentials
allowed access if no scopes were allowed.
* The site logo could overlap with the menu for logos with an unexpected aspect ratio.
Changed
~~~~~~~
* [Dev] ActionForm now checks permissions on objects before executing
* [Dev] ActionForm now returns a proper return value from the executed action
* Pin version of javascript dependencies
2.8.1`_ - 2022-03-13
--------------------
......
......@@ -561,20 +561,20 @@ MEDIA_ROOT = _settings.get("media.root", os.path.join(BASE_DIR, "media"))
NODE_MODULES_ROOT = _settings.get("node_modules.root", os.path.join(BASE_DIR, "node_modules"))
YARN_INSTALLED_APPS = [
"cleave.js",
"@fontsource/roboto",
"jquery",
"@materializecss/materialize",
"material-design-icons-iconfont",
"select2",
"select2-materialize",
"paper-css",
"jquery-sortablejs",
"sortablejs",
"@sentry/tracing",
"luxon",
"@iconify/iconify",
"@iconify/json",
"cleave.js@^1.6.0",
"@fontsource/roboto@^4.5.5",
"jquery@^3.6.0",
"@materializecss/materialize@~1.0.0",
"material-design-icons-iconfont@^6.6.0",
"select2@^4.1.0-rc.0",
"select2-materialize@^0.1.8",
"paper-css@^0.4.1",
"jquery-sortablejs@^1.0.1",
"sortablejs@^1.15.0",
"@sentry/tracing@^6.19.6",
"luxon@^2.3.2",
"@iconify/iconify@^2.2.1",
"@iconify/json@^2.1.30",
]
merge_app_settings("YARN_INSTALLED_APPS", YARN_INSTALLED_APPS, True)
......
......@@ -115,17 +115,15 @@ main {
/* SIDENAV */
/***********/
ul.sidenav.sidenav-fixed li.logo {
margin-top: 32px;
margin-bottom: 50px;
}
ul.sidenav.sidenav-fixed .brand-logo {
margin: 0;
height: 100%;
}
.logo img {
width: 250px;
width: 268px;
margin-block: 1em;
vertical-align: middle;
}
.sidenav a:not(.collapsible-header) {
......
import base64
from django.contrib.auth import get_user_model
import pytest
from aleksis.core.models import Group, Person
from aleksis.core.models import Group, OAuthApplication, Person
pytestmark = pytest.mark.django_db
from django.http import HttpResponse
from django.test import override_settings
from django.urls import path, reverse
from django.views.generic import View
def test_all_settigns_registered():
......@@ -82,3 +88,61 @@ def test_reassign_user_to_person():
assert user2.groups.count() == 1
assert user1.groups.first().name == "Group 2"
assert user2.groups.first().name == "Group 1"
@override_settings(ROOT_URLCONF="aleksis.core.tests.regression.view_oauth")
def test_no_access_oauth2_client_credentials_without_allowed_scopes(client):
"""Tests that ClientProtectedResourceMixin doesn't allow access if no allowed scopes are set.
https://edugit.org/AlekSIS/official/AlekSIS-Core/-/issues/688
"""
wrong_application = OAuthApplication.objects.create(
name="Test Application",
allowed_scopes=[],
authorization_grant_type=OAuthApplication.GRANT_CLIENT_CREDENTIALS,
client_type=OAuthApplication.CLIENT_CONFIDENTIAL,
redirect_uris=["http://localhost:8000/"],
)
wrong_application_2 = OAuthApplication.objects.create(
name="Test Application",
allowed_scopes=["read"],
authorization_grant_type=OAuthApplication.GRANT_CLIENT_CREDENTIALS,
client_type=OAuthApplication.CLIENT_CONFIDENTIAL,
redirect_uris=["http://localhost:8000/"],
)
correct_application = OAuthApplication.objects.create(
name="Test Application",
allowed_scopes=["write"],
authorization_grant_type=OAuthApplication.GRANT_CLIENT_CREDENTIALS,
client_type=OAuthApplication.CLIENT_CONFIDENTIAL,
redirect_uris=["http://localhost:8000/"],
)
url = reverse("client_protected_resource_mixin_test")
auth_header = (
"Basic "
+ base64.b64encode(
f"{wrong_application.client_id}:{wrong_application.client_secret}".encode()
).decode()
)
r = client.get(url, HTTP_AUTHORIZATION=auth_header)
assert r.status_code == 403
auth_header = (
"Basic "
+ base64.b64encode(
f"{wrong_application_2.client_id}:{wrong_application_2.client_secret}".encode()
).decode()
)
r = client.get(url, HTTP_AUTHORIZATION=auth_header)
assert r.status_code == 403
auth_header = (
"Basic "
+ base64.b64encode(
f"{correct_application.client_id}:{correct_application.client_secret}".encode()
).decode()
)
r = client.get(url, HTTP_AUTHORIZATION=auth_header)
assert r.status_code == 200
from django.http import HttpResponse
from django.test import override_settings
from django.urls import path, reverse
from django.views.generic import View
from oauth2_provider.views.mixins import ScopedResourceMixin
from aleksis.core.util.auth_helpers import ClientProtectedResourceMixin
class TestViewClientProtectedResourceMixin(ScopedResourceMixin, ClientProtectedResourceMixin, View):
required_scopes = ["write"]
def get(self, request):
return HttpResponse("OK")
urlpatterns = [
path(
"client_protected_resource_mixin_test/",
TestViewClientProtectedResourceMixin.as_view(),
name="client_protected_resource_mixin_test",
),
]
......@@ -134,6 +134,10 @@ class ClientProtectedResourceMixin(_ClientProtectedResourceMixin):
# Verify scopes of configured application
# The OAuth request was enriched with a reference to the Application when using the
# validator above.
if not oauth_request.client.allowed_scopes:
# If there are no allowed scopes, the client is not allowed to access this resource
return False
required_scopes = set(self.get_scopes() or [])
allowed_scopes = set(AppScopes().get_available_scopes(oauth_request.client) or [])
return required_scopes.issubset(allowed_scopes)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment