Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hub api fixes #19

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
11 changes: 11 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"python.testing.unittestArgs": [
"-v",
"-s",
"./qgis-app",
"-p",
"test_*.py"
],
"python.testing.pytestEnabled": false,
"python.testing.unittestEnabled": true
}
5 changes: 3 additions & 2 deletions qgis-app/api/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 4.2.16 on 2024-09-12 07:16
# Generated by Django 4.2.16 on 2024-11-18 03:02

from django.conf import settings
from django.db import migrations, models
Expand All @@ -22,7 +22,8 @@ class Migration(migrations.Migration):
('is_blacklisted', models.BooleanField(default=False)),
('is_newly_created', models.BooleanField(default=False)),
('description', models.CharField(blank=True, help_text="Describe this token so that it's easier to remember where you're using it.", max_length=512, null=True, verbose_name='Description')),
('last_used_on', models.DateTimeField(blank=True, null=True, verbose_name='Last used on')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
('last_used_at', models.DateTimeField(blank=True, null=True, verbose_name='Last used at')),
('token', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='token_blacklist.outstandingtoken')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
Expand Down
8 changes: 6 additions & 2 deletions qgis-app/api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@ class UserOutstandingToken(models.Model):
blank=True,
null=True,
)
last_used_on = models.DateTimeField(
verbose_name=_("Last used on"),
created_at = models.DateTimeField(
verbose_name=_("Created at"),
auto_now_add=True,
)
last_used_at = models.DateTimeField(
verbose_name=_("Last used at"),
blank=True,
null=True
)
35 changes: 35 additions & 0 deletions qgis-app/api/permissions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
from rest_framework import permissions
from rest_framework.permissions import BasePermission
from rest_framework_simplejwt.authentication import JWTAuthentication
from django.contrib.auth.models import User
from rest_framework_simplejwt.exceptions import InvalidToken, TokenError
from rest_framework_simplejwt.token_blacklist.models import BlacklistedToken, OutstandingToken
import datetime
from api.models import UserOutstandingToken

MANAGER_GROUP = "Style Managers"

Expand All @@ -21,3 +28,31 @@ def has_object_permission(self, request, view, obj):
is_manager = user.groups.filter(name=MANAGER_GROUP).exists()

return user == obj.creator or user.is_staff or is_manager

class HasValidToken(BasePermission):
def has_permission(self, request, view):
auth_token = request.META.get("HTTP_AUTHORIZATION")
if not str(auth_token).startswith('Bearer'):
return False

# Validate JWT token
authentication = JWTAuthentication()
try:
validated_token = authentication.get_validated_token(auth_token[7:])
user_id = validated_token.payload.get('user_id')
jti = validated_token.payload.get('refresh_jti')
token_id = OutstandingToken.objects.get(jti=jti).pk
is_blacklisted = BlacklistedToken.objects.filter(token_id=token_id).exists()
if not user_id or is_blacklisted:
return False

user = User.objects.get(pk=user_id)
if not user:
return False
user_token = UserOutstandingToken.objects.get(token__pk=token_id, user=user)
user_token.last_used_at = datetime.datetime.now()
user_token.save()
request.user_token = user_token
return True
except (InvalidToken, TokenError):
return False
4 changes: 2 additions & 2 deletions qgis-app/api/templates/user_token_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ <h2 class="title is-4">{% trans "My Tokens" %}</h2>
{% for user_token in object_list %}
<tr>
<td class="has-text-centered">{{ user_token.description|default:"-" }}</td>
<td class="has-text-centered">{{ user_token.token.created_at }} UTC</td>
<td class="has-text-centered">{{ user_token.last_used_on|default:"-" }}{% if user_token.last_used_on %} UTC{% endif %}</td>
<td class="has-text-centered">{{ user_token.created_at }} UTC</td>
<td class="has-text-centered">{{ user_token.last_used_at|default:"-" }}{% if user_token.last_used_at %} UTC{% endif %}</td>
<td class="has-text-centered">
<a class="button is-success is-outlined is-small" href="{% url "user_token_update" user_token.pk %}"
title="{% trans "Edit description" %}"><span class="icon"><i class="fas fa-pencil-alt"></i></span></a>&nbsp;
Expand Down
Loading