Skip to content

Commit 13076e3

Browse files
MadsNyleriskjelharuixuEster2109LeMiTam
authored
MID MARCH UPDATE (#954)
* Feat(kontres)/add image to bookable item (#785) * added optional image to bookable item model * added update method in serializer to handle new images * linting * remove update method for images * Feat(kontres)/add approved by (#786) * added approved by field * endpoint will now set approved by * serializer will return full user object in approved_by_detail * created test for approved by * migration * remove unnecessary code * removed write-only field in approved-by context * Create minutes for Codex (#787) * init * format * Feat(minute)/viewset (#788) * added richer reponse on post and put * added to admin panel * added filter for minute * Feat(kontres)/add notification (#790) * created methods for sending notification to admin and user * endpoint will now send notification if needed * add migrations for new notification types * Memberships with fines activated (#791) init * Feat(user)/user bio (#758) * Created model, serializer and view for user-bio * Created user bio model and made migrations * Created user bio serializer + viewsets + added new endpoint * Tested create method + added bio serializer to user serializer * Format * Created update method and started testing * Debugging test failures in user retrieve * fixed model error * Created user_bio_factory + started testing put method * Created fixture for UserBio * Created custom excpetion for duplicate user bio * Added permissions and inherited from BaseModel * Modularized serializer for bio * Use correct serializers in viewset + added destroy method * Finished testing bio viewset integration + format * Changed environent file to .env to avoid pushing up keys * Fix: Flipped assertion statement in test, since user bio should not be deleted * skiped buggy test from kontres * added mark to pytest.skip * Moved keys to .env file and reverted docker variables * Skip buggy kontres test * format * Added str method to user_bio * Removed unused imports * format * Changed user relation to a OneToOne-field (same affect as ForeignKey(unique=True) + removed check for duplicate bio in serializer * Migrations + changed assertion status code in duplicate bio test (could try catch in serializer to produce 400 status code) * format * format * Changed limit for description 50 -> 500 + migrations * Migrate * added id to serializer * merged leaf nodes in migrations * format --------- Co-authored-by: Ester2109 <[email protected]> Co-authored-by: Mads Nylund <[email protected]> Co-authored-by: Mads Nylund <[email protected]> Co-authored-by: Tam Le <[email protected]> * Update CHANGELOG.md * added filter for allowed photos for user (#794) added filter for allowed photos * Upped payment time when coming from waiting list (#796) * fixed paymenttime saved to db (#798) * fixed bug (#800) * Disallow users to unregister when payment is done (#802) added 400 status code for deleting paid registration * update changelog * Added serializer for category in event (#804) added serializer for category in event * Permission middelware (#806) * added a check for existing user and id on request * format * Permission refactor of QR Codes (#807) * added permissions to qr code and refactored viewset * format * removed unused imports * Permissions for payment orders (#808) * added read permissions * added permissions for payment order and tests * format * chore(iac): updated docs and force https (#810) chore: updated docs and force https * feat(iac): add terraform guardrails so index don't nuke our infra (#811) feat: add guardrails so index don't fup * Automatic registration for new users with Feide (#809) * started on feide registration endpoint * made endpoint for creating user with Feide * added test for parse group * finished * format * removes three years if in digtrans * changelog update * Feide env variables Terraform (#814) added feid env variables * added delete endpoint for file (#815) * added delete endpoint for file * Trigger Build * changed workflow to checkout v4 * changed from docker-compose to docker compose * Update CHANGELOG.md * format * format * fixed permission for committee leaders for group forms * updated csv for forms (#818) * Permission for group forms and news (#820) added permission for committees to create news, and all leaders of groups to create group forms * Update reservation_seralizer.py (#822) * Update reservation_seralizer.py * Fixed linting * Put a band aid on it *smack* * Removed blank line.. * ???? * Group ownership of Minutes (#847) * Refactor MinuteFactory to include group field, and added validation for checkin group access * added validation for POST request * Changed endpoint response (#846) * Changed endpoint response * Fixed test * Update test_reservation_integration.py --------- Co-authored-by: Mads Nylund <[email protected]> * updated changelog.md * finished events now appear in the correct order (newest first) (#849) * finished events now appear in the correct order (newest first) * added description of change in changelog * fixed formatting * updated method to use Django ORM instead of using python methods * Implement Swagger (#858) * started on removing choiceenums * refactored cheatsheet and membership * refacotered strike enum * refactored Groups enum * removed AppModel choiceenum * added swagger * Swagger GitHub Action (#860) * added github action for checking if Swagger is up * new action * try another * tried implementing check for container * added curl to docker image * added check if swagger is up * test if swagger does not get status code 200 * added ?format=openai to trigger error * checking that the request is working * updated CHANGELOG.md * Add new app (#862) * added script for adding new app to Lepton * added command to Makefile * Upgrade all dependencies to latest (#857) * Add endpoint to create new group as admin Signed-off-by: Tmpecho <[email protected]> * Upgrade all dependencies to latest Signed-off-by: Tmpecho <[email protected]> * remove bad exception handling in serializers/group.py * fix inheritance ordering in views/group.py * refactored group integration test, added non_public_groups to enums * fix linting * reformat files * remove unused import in groups/views/group.py * Upgrade dependency "black" Signed-off-by: Tmpecho <[email protected]> * Upgrade dependency "sentry-sdk" Signed-off-by: Tmpecho <[email protected]> * Upgrade dependency "azure-storage-blob" and remove outdated comment in requirements.txt Signed-off-by: Tmpecho <[email protected]> * Upgrade all non-django dependencies Signed-off-by: Tmpecho <[email protected]> * Upgrade dependency "Django" Signed-off-by: Tmpecho <[email protected]> * Upgrade dependencies and remove ignored version from docker-compose.yml Signed-off-by: Tmpecho <[email protected]> --------- Signed-off-by: Tmpecho <[email protected]> Co-authored-by: 1Cezzo <[email protected]> * Allow HS members to create a new group (#864) * Add endpoint to create new group as admin Signed-off-by: Tmpecho <[email protected]> * remove bad exception handling in serializers/group.py * fix inheritance ordering in views/group.py * refactored group integration test, added non_public_groups to enums * fix linting * reformat files * remove unused import in groups/views/group.py --------- Signed-off-by: Tmpecho <[email protected]> Co-authored-by: 1Cezzo <[email protected]> * App Script Fix (#875) added serializers dir to script * Event registration payment orders (#876) * added list of payment orders for registrations * update CHANGELOG.md * chore(deps): update python-dotenv requirement from ~=0.21.1 to ~=1.0.1 (#871) Updates the requirements on [python-dotenv](https://github.com/theskumar/python-dotenv) to permit the latest version. - [Release notes](https://github.com/theskumar/python-dotenv/releases) - [Changelog](https://github.com/theskumar/python-dotenv/blob/main/CHANGELOG.md) - [Commits](theskumar/python-dotenv@v0.21.1...v1.0.1) --- updated-dependencies: - dependency-name: python-dotenv dependency-type: direct:production ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mads Nylund <[email protected]> * Chore(deps): Bump sentry-sdk from 1.14.0 to 2.8.0 (#866) Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 1.14.0 to 2.8.0. - [Release notes](https://github.com/getsentry/sentry-python/releases) - [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md) - [Commits](getsentry/sentry-python@1.14.0...2.8.0) --- updated-dependencies: - dependency-name: sentry-sdk dependency-type: direct:production ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mads Nylund <[email protected]> * Codex Course (#852) * added models for course and registration, and viewset for course and tests * added validation for date checking for courses * added viewset for registration for codex courses * removed unused fields from course model * removed unused imports * added API error mixins as mother clas * fixed error mixin * refactored to event model * fixed wrong import * fixed tests * format * skipped broken tests, must be refactored * updated CHANGELOG.md * format * fixed filtering of groups and made tests * fixed list endpoint for cheatsheets * trigger * format * Endpoint for sending email (#883) * fix formatting * created tests for send_email endpoint * Fix code scanning alert no. 45: Information exposure through an exception Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * fixed errors in send_email and in tests * lint * added tests for empty lists and for sending mail to multiple users --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * chore(deps): bump black from 24.3.0 to 24.8.0 (#869) Bumps [black](https://github.com/psf/black) from 24.3.0 to 24.8.0. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](psf/black@24.3.0...24.8.0) --- updated-dependencies: - dependency-name: black dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mads Nylund <[email protected]> * chore(deps): Bump azure-storage-blob from 12.13.1 to 12.23.1 (#885) Bumps [azure-storage-blob](https://github.com/Azure/azure-sdk-for-python) from 12.13.1 to 12.23.1. - [Release notes](https://github.com/Azure/azure-sdk-for-python/releases) - [Changelog](https://github.com/Azure/azure-sdk-for-python/blob/main/doc/esrp_release.md) - [Commits](Azure/azure-sdk-for-python@azure-storage-blob_12.13.1...azure-storage-blob_12.23.1) --- updated-dependencies: - dependency-name: azure-storage-blob dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mads Nylund <[email protected]> * Added admin.py to root in new app, and added app dir to tests (#892) added admin.py to root in new app, and added app dir to tests * Description to forms (#894) added description to form * Bug report system (#865) * Created New App named Index * created model * Refactor: Change admin file * admin * added serializer and viewsets for list * fixed typing error for permission_classes * Started on the create serializer for feedback * Made tests for create feedback * Implemented update serializer for feedback * made destroy method and testing create method as member * Made destroy method and tests * Fixed linting * Fixed linting --------- Co-authored-by: Tam Le <[email protected]> Co-authored-by: Josefine Arntsen <[email protected]> Co-authored-by: Mads Nylund <[email protected]> Co-authored-by: Mads Nylund <[email protected]> * Renaming of index app to feedback (#901) renamed index app to feedback * chore(deps): bump django from 4.2.16 to 5.1.1 (#889) Bumps [django](https://github.com/django/django) from 4.2.16 to 5.1.1. - [Commits](django/django@4.2.16...5.1.1) --- updated-dependencies: - dependency-name: django dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mads Nylund <[email protected]> * Event registration race condition (#902) * started on fixing race condition * fixed race condition * upadted CHANGELOG.md * Feat(registration)/filter participants (#895) * filtering by year and study * linting fix * added allergy filter * added filter by allergies and participants with allergy count to event. * Lint fix * Add new fixture for admin user * Start testing filtering + finished allergy filter test * Added integration test for participants filtering * lint fix * removed unused import * Update changelog * merge with dev and more filters * Fixed has_paid filter and added filter combination test * ran linting script --------- Co-authored-by: Harry Linrui XU <[email protected]> Co-authored-by: Mads Nylund <[email protected]> * Feat(registration)/filter participants (#915) * filtering by year and study * linting fix * added allergy filter * added filter by allergies and participants with allergy count to event. * Lint fix * Add new fixture for admin user * Start testing filtering + finished allergy filter test * Added integration test for participants filtering * lint fix * removed unused import * Update changelog * merge with dev and more filters * Fixed has_paid filter and added filter combination test * ran linting script * fixed has allergy count bug, and has_paid bug * post linting --------- Co-authored-by: Harry Linrui XU <[email protected]> Co-authored-by: Mads Nylund <[email protected]> * Fix issue where full error is exposed to external users (#914) Signed-off-by: Tmpecho <[email protected]> * chore(deps): Bump sentry-sdk from 2.8.0 to 2.14.0 (#893) Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 2.8.0 to 2.14.0. - [Release notes](https://github.com/getsentry/sentry-python/releases) - [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md) - [Commits](getsentry/sentry-python@2.8.0...2.14.0) --- updated-dependencies: - dependency-name: sentry-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mads Nylund <[email protected]> * Refactor/minor code cleanup (#884) * Prefix unused variable names with underscore, remove redundant parenthesis, split long lines into several, rename functions to snake_case, Signed-off-by: Tmpecho <[email protected]> * Update CHANGELOG.md Signed-off-by: Tmpecho <[email protected]> * Make constant uppercase Signed-off-by: Tmpecho <[email protected]> * Empty-Commit --------- Signed-off-by: Tmpecho <[email protected]> Co-authored-by: Mads Nylund <[email protected]> * Add default detail to custom exceptions (#916) Signed-off-by: Tmpecho <[email protected]> Co-authored-by: Mads Nylund <[email protected]> * chore(deps): bump uvicorn from 0.30.6 to 0.32.0 (#908) Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.30.6 to 0.32.0. - [Release notes](https://github.com/encode/uvicorn/releases) - [Changelog](https://github.com/encode/uvicorn/blob/master/CHANGELOG.md) - [Commits](encode/uvicorn@0.30.6...0.32.0) --- updated-dependencies: - dependency-name: uvicorn dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mads Nylund <[email protected]> * chore(deps): Bump pre-commit from 3.8.0 to 4.0.1 (#899) Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.8.0 to 4.0.1. - [Release notes](https://github.com/pre-commit/pre-commit/releases) - [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md) - [Commits](pre-commit/pre-commit@v3.8.0...v4.0.1) --- updated-dependencies: - dependency-name: pre-commit dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mads Nylund <[email protected]> * Feat(registration)/filter participants (#917) Fixed bugs introduced in an earlier pr --------- Co-authored-by: Harry Linrui XU <[email protected]> Co-authored-by: Mads Nylund <[email protected]> Co-authored-by: haruixu <[email protected]> * Upload files (#906) * Create files app to manage user uploaded files Signed-off-by: Tmpecho <[email protected]> * created serializers for file and gallery * Move file upload endpoint from content/ to files/, create file and gallery views, add file and gallery model methods Signed-off-by: Tmpecho <[email protected]> * updating progress, needed to rename 'Gallery' to 'UserGallery' as a Gallery model already exists * finished mvp for file project * updating progress * mvp for file uploading/deletion * forgot changelog, oopsie * fixed error in permissions from allowing non-admins to delete files, fixed 'security threat' * Minor fixes to file serializer Signed-off-by: Tmpecho <[email protected]> * Fix whitespace Signed-off-by: Tmpecho <[email protected]> * Add custom exeption with mixins for files class Signed-off-by: Tmpecho <[email protected]> * Update custom file exceptions, set max gallery size as global constant, throw custom exceptions Signed-off-by: Tmpecho <[email protected]> * create test for creating file when not having a gallery, format * removed duplicate method * small refactoring and removed 'url' from file model, changed it to 'OptionalFile' * fix lint --------- Signed-off-by: Tmpecho <[email protected]> Co-authored-by: Tmpecho <[email protected]> Co-authored-by: Mads Nylund <[email protected]> Co-authored-by: Johannes Aamot-Skeidsvoll <[email protected]> * Refactor/ Fixed sorting in albums (#910) * Created factory for album * Fixed the order method in albums * Fixed linting * run migrations --------- Co-authored-by: Mads Nylund <[email protected]> * made it possible for members and leader of the organizing group to add members to event (#921) Co-authored-by: Mads Nylund <[email protected]> * Fix feeedback serializer on list (#927) added description to serializer for feedback list * added description to serializer for bug and idea * Move file upload and deletion to content from files (#928) Signed-off-by: Tmpecho <[email protected]> Co-authored-by: Mads Nylund <[email protected]> * Feedback V2 (#926) * started on V2 of feedback * Made more tests for retrieveing feedback details * Started working on the filtering for status and status for feedback * started on fix for filter * fixed filtering * format * format * trigger --------- Co-authored-by: Tam Le <[email protected]> * removed max limit from group description (#934) * format * removed duplicat fixture * Added description to group list serializer * Feat(vipps)/check payment (#943) * format * small fix * Finished vipps confimation * Fixed linting * Fixed linting again * change endpoint url, add permission check for endpoint * Fix enum spelling * fixed permission check, added test to make sure it works as it should * fix linting * added tests that verify only index members and members of the organizing group can update an order * changed response key from 'is_true' to detail, and made the description more explanatory * fikset skrivefeil --------- Co-authored-by: 1Cezzo <[email protected]> * Added a new blob storage to Azure * Sort galleries (#947) * Update in progress * Update in progress * Update album filtering * Updae branch name --------- Co-authored-by: Josefine Arntsen <[email protected]> Co-authored-by: Mads Nylund <[email protected]> * added write_all auth to order model (#952) * Feat(submissions)/deletion of form submission (#951) * Update the Submission model with a destroy method() * Update the Submission model with imports * Created an endpoint in the view * Update submissions * Updated serializer and view for deleting a submission with reason * Removed unsued import of mail * Added missing imports * Fixed format in files --------- Co-authored-by: Josefine Arntsen <[email protected]> Co-authored-by: Mads Nylund <[email protected]> * fixed csv download bugs (#953) * fixed csv download bugs * changelog --------- Signed-off-by: Tmpecho <[email protected]> Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: Erik Skjellevik <[email protected]> Co-authored-by: haruixu <[email protected]> Co-authored-by: Ester2109 <[email protected]> Co-authored-by: Tam Le <[email protected]> Co-authored-by: martcl <[email protected]> Co-authored-by: Frikk Balder <[email protected]> Co-authored-by: Emil Johnsen <[email protected]> Co-authored-by: Johannes Aamot-Skeidsvoll <[email protected]> Co-authored-by: 1Cezzo <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: Josefine Arntsen <[email protected]> Co-authored-by: Josefine Arntsen <[email protected]> Co-authored-by: Yazan Zarka <[email protected]> Co-authored-by: Harry Linrui XU <[email protected]> Co-authored-by: Emil Johnsen <[email protected]> Co-authored-by: Tmpecho <[email protected]> Co-authored-by: LeMiTam <[email protected]>
1 parent 41b5491 commit 13076e3

File tree

15 files changed

+227
-14
lines changed

15 files changed

+227
-14
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@
1515

1616
## Neste versjon
1717

18+
## Versjon 2025.03.10
19+
- 🦟 **CSV spørreskjema svar**. Nedlasting av spørreskjema svar er nå fikset.
20+
-**Sletting av spørreskjema svar for admin**. Admin kan nå slette svar på spørreskjema.
21+
-**Sortering av galleri**. Man kan nå sortere gallerier etter oppretelsesdato og siste arrangement.
22+
-**Statussjekk av Vipps**. Man kan nå sjekke statusen til en Vipps betaling og oppdatere den automatisk.
23+
1824
## Versjon 2024.12.26
1925
-**Filopplasting**. Det er nå mulig for admin brukere å laste opp- og slette filer.
2026
-**Mail endepunkt**. Det er nå laget et endepunkt for å sende mailer.

app/files/serializers/file.py

-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ def create(self, validated_data):
4747

4848

4949
class UpdateFileSerializer(BaseModelSerializer):
50-
5150
class Meta:
5251
model = File
5352
fields = (

app/forms/csv_writer.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66

77
class SubmissionsCsvWriter:
8-
field_names = [
8+
base_field_names = [
99
"first_name",
1010
"last_name",
1111
"full_name",
@@ -18,6 +18,7 @@ def __init__(self, queryset=None):
1818
if queryset is None:
1919
queryset = []
2020
self.queryset = queryset
21+
self.field_names = self.base_field_names.copy()
2122

2223
def write_csv(self):
2324
response = HttpResponse(content_type="text/csv")
@@ -64,9 +65,9 @@ def get_answer_text(self, answer):
6465
)
6566
return ", ".join(answer_text)
6667

67-
return answer.answer_text
68+
return answer.answer_text.replace('\n', ' ').replace('\r', ' ')
6869

6970
def write_rows(self, response, result):
70-
writer = csv.DictWriter(response, fieldnames=self.field_names)
71+
writer = csv.DictWriter(response, fieldnames=self.field_names, quoting=csv.QUOTE_ALL)
7172
writer.writeheader()
7273
writer.writerows(result)

app/forms/serializers/submission.py

+14
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,17 @@ class SubmissionGDPRSerializer(SubmissionInRegistrationSerializer):
8989
class Meta:
9090
model = SubmissionInRegistrationSerializer.Meta.model
9191
fields = SubmissionInRegistrationSerializer.Meta.fields
92+
93+
94+
class SubmissionDestroySerializer(serializers.Serializer):
95+
reason = serializers.CharField(required=True, allow_blank=False)
96+
97+
class Meta:
98+
fields = ["reason"]
99+
100+
def validate_reason(self, value):
101+
if not value.strip():
102+
raise serializers.ValidationError(
103+
"Grunnen kan ikke være tom eller kun inneholde mellomrom."
104+
)
105+
return value

app/forms/views/submission.py

+30-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from django.conf import settings
2+
from django.core.mail import send_mail
13
from rest_framework import status
24
from rest_framework.decorators import action
35
from rest_framework.generics import get_object_or_404
@@ -13,7 +15,10 @@
1315
from app.forms.enums import NativeEventFormType as EventFormType
1416
from app.forms.mixins import APIFormErrorsMixin
1517
from app.forms.models.forms import EventForm, Form, Submission
16-
from app.forms.serializers.submission import SubmissionSerializer
18+
from app.forms.serializers.submission import (
19+
SubmissionDestroySerializer,
20+
SubmissionSerializer,
21+
)
1722

1823

1924
class SubmissionViewSet(APIFormErrorsMixin, BaseViewSet):
@@ -71,3 +76,27 @@ def create(self, request, *args, **kwargs):
7176
def download(self, _request, *_args, **_kwargs):
7277
"""To return the response as csv, include header 'Accept: text/csv."""
7378
return SubmissionsCsvWriter(self.get_queryset()).write_csv()
79+
80+
@action(detail=True, methods=["delete"])
81+
def destroy_with_reason(self, request, *args, **kwargs):
82+
submission = self.get_object()
83+
serializer = SubmissionDestroySerializer(data=request.data)
84+
85+
if not serializer.is_valid():
86+
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
87+
88+
reason = serializer.validated_data.get("reason", "Ingen grunn oppgitt.")
89+
90+
send_mail(
91+
subject="Ditt svar på spørreskjemaet har blitt slettet",
92+
message=f"Ditt svar på spørreskjemaet {submission.form.title} har blitt slettet av en administrator. Grunnen er: {reason}",
93+
from_email=settings.DEFAULT_FROM_EMAIL,
94+
recipient_list=[submission.user.email],
95+
)
96+
97+
submission.delete()
98+
99+
return Response(
100+
{"detail": "Skjemaet er slettet og brukeren er varslet."},
101+
status=status.HTTP_200_OK,
102+
)

app/gallery/filters/album.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
1-
from django_filters.rest_framework import FilterSet
1+
from django_filters.rest_framework import FilterSet, OrderingFilter
22

33
from app.gallery.models.album import Album
44

55

66
class AlbumFilter(FilterSet):
7+
"""Filter and sort albums by date or event."""
8+
9+
ordering = OrderingFilter(
10+
fields=(
11+
"created_at",
12+
"updated_at",
13+
"event__title",
14+
)
15+
)
16+
717
class Meta:
818
model = Album
9-
fields = ["event"]
19+
fields = [
20+
"event",
21+
]

app/payment/models/order.py

+25-3
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,22 @@
22

33
from django.db import models
44

5-
from app.common.enums import Groups
5+
from app.common.enums import AdminGroup, Groups
66
from app.common.permissions import (
77
BasePermissionModel,
88
check_has_access,
99
is_admin_user,
1010
)
1111
from app.content.models.event import Event
1212
from app.content.models.user import User
13+
from app.group.models.membership import Membership
1314
from app.payment.enums import OrderStatus
1415
from app.util.models import BaseModel
1516

1617

1718
class Order(BaseModel, BasePermissionModel):
1819
read_access = (Groups.TIHLDE,)
20+
update_access = (AdminGroup.INDEX,)
1921

2022
order_id = models.UUIDField(
2123
auto_created=True, default=uuid.uuid4, primary_key=True, serialize=False
@@ -40,6 +42,22 @@ def __str__(self):
4042

4143
@classmethod
4244
def has_update_permission(cls, request):
45+
if check_has_access(cls.update_access, request):
46+
return True
47+
48+
order_id = request.parser_context.get("kwargs", {}).get("pk")
49+
50+
if order_id:
51+
try:
52+
order = Order.objects.get(order_id=order_id)
53+
54+
if order.event.organizer and order.event.organizer.slug:
55+
return Membership.objects.filter(
56+
user=request.user, group=order.event.organizer
57+
).exists()
58+
except Order.DoesNotExist:
59+
return False
60+
4361
return False
4462

4563
@classmethod
@@ -75,8 +93,12 @@ def has_list_permission(cls, request):
7593
def has_read_all_permission(cls, request):
7694
return is_admin_user(request)
7795

78-
def has_object_update_permission(self, _request):
79-
return False
96+
@classmethod
97+
def has_write_all_permission(cls, request):
98+
return is_admin_user(request)
99+
100+
def has_object_update_permission(self, request):
101+
return self.has_update_permission(request)
80102

81103
def has_object_destroy_permission(self, _request):
82104
return False

app/payment/serializers/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
VippsOrderSerialzer,
55
OrderListSerializer,
66
OrderUpdateSerializer,
7+
CheckPaymentSerializer,
78
)

app/payment/serializers/order.py

+5
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ class Meta:
4343
fields = ("status",)
4444

4545

46+
class CheckPaymentSerializer(BaseModelSerializer):
47+
class Meta:
48+
fields = ("event_id", "user_id")
49+
50+
4651
class OrderCreateSerializer(BaseModelSerializer):
4752
class Meta:
4853
model = Order

app/payment/urls.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
from django.urls import include, re_path
1+
from django.urls import include, path, re_path
22
from rest_framework import routers
33

44
from app.payment.views.order import OrderViewSet
55
from app.payment.views.vipps import VippsViewSet
6+
from app.payment.views.vipps_util import check_vipps_payment
67

78
router = routers.DefaultRouter()
89

@@ -11,4 +12,7 @@
1112
r"v2/payments/(?P<order_id>[0-9a-f-]+)", VippsViewSet, basename="payment"
1213
)
1314

14-
urlpatterns = [re_path(r"", include(router.urls))]
15+
urlpatterns = [
16+
re_path(r"", include(router.urls)),
17+
path("check-payment/", check_vipps_payment),
18+
]

app/payment/views/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from app.payment.views.vipps_util import check_vipps_payment
2+
from app.payment.serializers import CheckPaymentSerializer

app/payment/views/vipps_util.py

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from rest_framework import status
2+
from rest_framework.decorators import api_view
3+
from rest_framework.response import Response
4+
5+
from app.payment.models import Order
6+
from app.payment.serializers import CheckPaymentSerializer
7+
from app.payment.util.payment_utils import get_payment_order_status
8+
9+
10+
@api_view(["POST"])
11+
def check_vipps_payment(self, request, *args, **kwargs):
12+
has_changed = False
13+
14+
serializer = CheckPaymentSerializer(data=request.data)
15+
serializer.is_valid(raise_exception=True)
16+
17+
event_id = serializer.validated_data["event_id"]
18+
user_id = serializer.validated_data["user_id"]
19+
20+
orders = self.queryset.filter(user_id=user_id, event_id=event_id)
21+
22+
if not orders.exists():
23+
return Response(
24+
{"detail": "Ingen ordre funnet for bruker og arrangement."},
25+
status=status.HTTP_404_NOT_FOUND,
26+
)
27+
28+
if not Order.has_update_permission(self.request):
29+
return Response(
30+
{"detail": "Du har ikke tilgang til å oppdatere denne ordren."},
31+
status=status.HTTP_403_FORBIDDEN,
32+
)
33+
34+
for order in orders:
35+
order_status = get_payment_order_status(order.order_id)
36+
if order_status != order.status:
37+
has_changed = True
38+
order.status = order_status
39+
order.save()
40+
41+
if has_changed(order):
42+
return Response(
43+
{"detail": "Ordrestatusen var feil og har blitt endret."},
44+
status=status.HTTP_200_OK,
45+
)
46+
return Response(
47+
{"detail": "Ordrestatusen er korrekt og har ikke blitt endret."},
48+
status=status.HTTP_200_OK,
49+
)

app/tests/payment/test_order_integration.py

+53-2
Original file line numberDiff line numberDiff line change
@@ -117,16 +117,67 @@ def test_update_order_as_member(member, order):
117117

118118

119119
@pytest.mark.django_db
120-
@pytest.mark.parametrize("group_name", [*AdminGroup.admin()])
120+
@pytest.mark.parametrize("group_name", [AdminGroup.INDEX])
121+
def test_update_order_as_index_user(member, order, group_name):
122+
"""An index user should be able to update an order."""
123+
add_user_to_group_with_name(member, group_name)
124+
client = get_api_client(user=member)
125+
data = {"status": OrderStatus.SALE}
126+
response = client.put(get_orders_url_detail(order.order_id), data=data)
127+
assert response.status_code == status.HTTP_200_OK
128+
129+
130+
@pytest.mark.django_db
131+
@pytest.mark.parametrize(
132+
"group_name", [AdminGroup.HS, AdminGroup.KOK, AdminGroup.SOSIALEN]
133+
)
121134
def test_update_order_as_admin_user(member, order, group_name):
122-
"""An index and HS user should not be able to update an order."""
135+
"""Members of admin groups other than index should not be able to update an order."""
123136
add_user_to_group_with_name(member, group_name)
124137
client = get_api_client(user=member)
125138
data = {"status": OrderStatus.SALE}
126139
response = client.put(get_orders_url_detail(order.order_id), data=data)
127140
assert response.status_code == status.HTTP_403_FORBIDDEN
128141

129142

143+
@pytest.mark.django_db
144+
def test_update_order_as_organizer(member, event, order):
145+
"""Test that members of the organizing group (e.g., SOSIALEN) can update an order."""
146+
organizer_group = GroupFactory(name=AdminGroup.SOSIALEN)
147+
add_user_to_group_with_name(member, organizer_group.name)
148+
149+
event.organizer = organizer_group
150+
event.save()
151+
152+
order.event = event
153+
order.save()
154+
155+
data = {"status": OrderStatus.SALE}
156+
client = get_api_client(user=member)
157+
158+
response = client.put(get_orders_url_detail(order.order_id), data=data)
159+
assert response.status_code == status.HTTP_200_OK
160+
161+
162+
@pytest.mark.django_db
163+
def test_update_order_as_non_organizer(member, event, order):
164+
"""Test that members not in the organizing group do not have permission to update an order."""
165+
organizer_group = GroupFactory(name=AdminGroup.SOSIALEN)
166+
add_user_to_group_with_name(member, AdminGroup.NOK)
167+
168+
event.organizer = organizer_group
169+
event.save()
170+
171+
order.event = event
172+
order.save()
173+
174+
data = {"status": OrderStatus.SALE}
175+
client = get_api_client(user=member)
176+
177+
response = client.put(get_orders_url_detail(order.order_id), data=data)
178+
assert response.status_code == status.HTTP_403_FORBIDDEN
179+
180+
130181
@pytest.mark.django_db
131182
def test_list_all_orders_for_event_as_organizer(member, event):
132183
"""

infrastructure/storage.tf

+16
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,19 @@ resource "azurerm_storage_account" "lepton" {
1313
prevent_destroy = true
1414
}
1515
}
16+
17+
// Storage for Drift backups
18+
resource "azurerm_storage_account" "backup" {
19+
name = "driftbackups${var.enviroment}"
20+
resource_group_name = azurerm_resource_group.lepton.name
21+
location = azurerm_resource_group.lepton.location
22+
account_tier = "Standard"
23+
account_replication_type = "GRS"
24+
min_tls_version = "TLS1_2"
25+
26+
tags = local.common_tags
27+
28+
lifecycle {
29+
prevent_destroy = false
30+
}
31+
}

main.tf

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ terraform {
1515

1616
provider "azurerm" {
1717
features {}
18+
19+
skip_provider_registration = true
1820
}
1921

2022
module "infrastructure" {

0 commit comments

Comments
 (0)