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

CSV Download Form Update #819

Merged
merged 34 commits into from
Aug 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
6aeef42
Feat(kontres)/add image to bookable item (#785)
eriskjel Mar 23, 2024
c9b5975
Feat(kontres)/add approved by (#786)
eriskjel Apr 6, 2024
28067fa
Create minutes for Codex (#787)
MadsNyl Apr 8, 2024
9e4ff76
Feat(minute)/viewset (#788)
MadsNyl Apr 8, 2024
0544b2f
Feat(kontres)/add notification (#790)
eriskjel Apr 10, 2024
ae483dd
Memberships with fines activated (#791)
MadsNyl Apr 12, 2024
95ef58c
fixed merge
MadsNyl Apr 13, 2024
bfa2299
Feat(user)/user bio (#758)
haruixu Apr 16, 2024
3f56496
Update CHANGELOG.md
MadsNyl Apr 16, 2024
064da8a
added filter for allowed photos for user (#794)
MadsNyl Apr 17, 2024
81a3c5e
Upped payment time when coming from waiting list (#796)
MadsNyl Apr 17, 2024
a583c45
fixed paymenttime saved to db (#798)
MadsNyl Apr 17, 2024
0f24085
fixed bug (#800)
MadsNyl Apr 17, 2024
8a3cfd4
fixed mergeconflict
MadsNyl Apr 17, 2024
e597268
Disallow users to unregister when payment is done (#802)
MadsNyl May 1, 2024
3b84765
update changelog
MadsNyl May 1, 2024
f21e0ab
Added serializer for category in event (#804)
MadsNyl May 2, 2024
e30f102
fixed merge
MadsNyl May 2, 2024
64d717c
Permission middelware (#806)
MadsNyl Jun 9, 2024
ed57afc
Permission refactor of QR Codes (#807)
MadsNyl Jun 9, 2024
ab3cf15
Permissions for payment orders (#808)
MadsNyl Jun 10, 2024
062193d
chore(iac): updated docs and force https (#810)
martcl Jul 26, 2024
23b310a
feat(iac): add terraform guardrails so index don't nuke our infra (#811)
martcl Jul 26, 2024
fa31096
Automatic registration for new users with Feide (#809)
MadsNyl Jul 30, 2024
bef294d
changelog update
MadsNyl Jul 30, 2024
4db63b5
Merge branch 'dev' of https://github.com/TIHLDE/Lepton into dev
MadsNyl Jul 30, 2024
fcce5e8
Feide env variables Terraform (#814)
MadsNyl Jul 31, 2024
514a26b
added delete endpoint for file (#815)
MadsNyl Aug 4, 2024
d3e8e9a
Update CHANGELOG.md
MadsNyl Aug 4, 2024
a02af01
merge conflict
MadsNyl Aug 4, 2024
c9bf357
format
MadsNyl Aug 4, 2024
1a7dff4
format
MadsNyl Aug 4, 2024
f086ac2
fixed permission for committee leaders for group forms
MadsNyl Aug 18, 2024
ec03558
updated csv for forms (#818)
MadsNyl Aug 18, 2024
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
24 changes: 12 additions & 12 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
steps:

- name: Checkout Code Repository
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Set up Python 3.9
uses: actions/setup-python@v2
Expand All @@ -35,7 +35,7 @@ jobs:
steps:

- name: Checkout Code Repository
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Set up .env file
run: |
Expand All @@ -44,35 +44,35 @@ jobs:
echo "VIPPS_MERCHANT_SERIAL_NUMBER=${{ secrets.VIPPS_MERCHANT_SERIAL_NUMBER }}" >> .env

- name: Build the Stack
run: docker-compose build
run: docker compose build

- name: Run the Stack
run: docker-compose up -d
run: docker compose up -d

- name: Make DB Migrations
run: docker-compose run --rm web python manage.py migrate
run: docker compose run --rm web python manage.py migrate

- name: Run Django Tests
run: docker-compose run --rm web pytest --cov=app
run: docker compose run --rm web pytest --cov=app

- name: Tear down the Stack
run: docker-compose down
run: docker compose down

check-migrations:
runs-on: ubuntu-latest
steps:

- name: Checkout Code Repository
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Build the Stack
run: docker-compose build
run: docker compose build

- name: Run the Stack
run: docker-compose up -d
run: docker compose up -d

- name: Check for unstaged migrations
run: docker-compose run --rm web python manage.py makemigrations --check --no-input
run: docker compose run --rm web python manage.py makemigrations --check --no-input

- name: Tear down the Stack
run: docker-compose down
run: docker compose down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ celerybeat-schedule

.terraform
*.tfvars
.terraform.lock.hcl
2 changes: 2 additions & 0 deletions .terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

## Versjon 2024.07.30
- ✨ **Feide**. Man kan nå registrere bruker automatisk med Feide.
- ✨ **Fillagring**. Man kan nå slette en fil fra Azure basert på container navn og fil navn.

## Versjon 2024.05.01
- ⚡**Arrangement**. Et arrangement vil nå få kategori sendt som navn på kategori istedenfor kun id.
Expand Down
2 changes: 1 addition & 1 deletion app/common/file_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def getContainerNameFromBlob(self):
return (
"".join(e for e in self.blob.content_type if e.isalnum())
if self.blob.content_type
else None
else "default"
)

def checkBlobSize(self):
Expand Down
6 changes: 6 additions & 0 deletions app/content/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,12 @@ def is_leader_of(self, group):
group=group, membership_type=MembershipType.LEADER
).exists()

@property
def is_leader_of_committee(self):
return self.memberships.filter(
group__type=GroupType.COMMITTEE, membership_type=MembershipType.LEADER
).exists()

def has_unanswered_evaluations(self):
return self.get_unanswered_evaluations().exists()

Expand Down
23 changes: 10 additions & 13 deletions app/content/serializers/user.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
from django.contrib.auth.hashers import make_password
from rest_framework import serializers
from rest_framework.exceptions import ValidationError

from django.contrib.auth.hashers import make_password

from dry_rest_permissions.generics import DRYGlobalPermissionsField

from app.communication.notifier import Notify
from app.communication.enums import UserNotificationSettingType
from app.common.enums import GroupType, Groups
from app.common.enums import Groups, GroupType
from app.common.serializers import BaseModelSerializer
from app.communication.enums import UserNotificationSettingType
from app.communication.notifier import Notify
from app.content.exceptions import FeideUserExistsError
from app.content.models import User
from app.content.serializers.user_bio import UserBioSerializer
from app.group.models import Group, Membership
from app.content.util.feide_utils import (
generate_random_password,
get_feide_tokens,
get_feide_user_groups,
parse_feide_groups,
generate_random_password,
get_study_year,
get_feide_user_info_from_jwt,
get_study_year,
parse_feide_groups,
)
from app.content.exceptions import FeideUserExistsError
from app.group.models import Group, Membership


class DefaultUserSerializer(BaseModelSerializer):
Expand Down Expand Up @@ -168,9 +167,7 @@ def add_user_to_study(self, user, slug):
study = Group.objects.filter(type=GroupType.STUDY, slug=slug).first()
study_year = get_study_year(slug)
class_ = Group.objects.get_or_create(
name=study_year,
type=GroupType.STUDYYEAR,
slug=study_year
name=study_year, type=GroupType.STUDYYEAR, slug=study_year
)

if not study or not class_:
Expand Down
4 changes: 3 additions & 1 deletion app/content/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@
UserCalendarEvents,
UserViewSet,
accept_form,
upload,
delete,
register_with_feide,
upload,
)

router = routers.DefaultRouter()
Expand Down Expand Up @@ -52,6 +53,7 @@
re_path(r"", include(router.urls)),
path("accept-form/", accept_form),
path("upload/", upload),
path("delete-file/<str:container_name>/<str:blob_name>/", delete),
path("feide/", register_with_feide),
re_path(r"users/(?P<user_id>[^/.]+)/events.ics", UserCalendarEvents()),
]
27 changes: 13 additions & 14 deletions app/content/util/feide_utils.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import jwt
import requests
import secrets
import string
from datetime import datetime

import jwt
import requests
from requests.auth import HTTPBasicAuth
from datetime import datetime

from app.content.exceptions import (
FeideGetTokenError,
FeideGetUserGroupsError,
FeideParseGroupsError,
FeideTokenNotFoundError,
FeideUsedUserCode,
FeideUserGroupsNotFoundError,
FeideUserInfoNotFoundError,
FeideUsernameNotFoundError,
)
from app.settings import (
FEIDE_CLIENT_ID,
FEIDE_CLIENT_SECRET,
Expand All @@ -14,17 +24,6 @@
FEIDE_USER_GROUPS_INFO_URL,
)

from app.content.exceptions import (
FeideTokenNotFoundError,
FeideGetTokenError,
FeideUserInfoNotFoundError,
FeideUsernameNotFoundError,
FeideUserGroupsNotFoundError,
FeideParseGroupsError,
FeideGetUserGroupsError,
FeideUsedUserCode,
)


def get_feide_tokens(code: str) -> tuple[str, str]:
"""Get access and JWT tokens for signed in Feide user"""
Expand Down
2 changes: 1 addition & 1 deletion app/content/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from app.content.views.news import NewsViewSet
from app.content.views.page import PageViewSet
from app.content.views.short_link import ShortLinkViewSet
from app.content.views.upload import upload
from app.content.views.upload import upload, delete
from app.content.views.strike import StrikeViewSet
from app.content.views.toddel import ToddelViewSet
from app.content.views.qr_code import QRCodeViewSet
Expand Down
7 changes: 5 additions & 2 deletions app/content/views/feide.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from rest_framework.decorators import api_view
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response

from app.content.serializers import FeideUserCreateSerializer, DefaultUserSerializer
from app.content.exceptions import FeideError
from app.content.serializers import (
DefaultUserSerializer,
FeideUserCreateSerializer,
)


@api_view(["POST"])
Expand Down
22 changes: 22 additions & 0 deletions app/content/views/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,25 @@
{"detail": str(value_error)},
status=status.HTTP_400_BAD_REQUEST,
)


@api_view(["DELETE"])
@permission_classes([IsMember])
def delete(request, container_name, blob_name):
"""Method for deleting files from Azure Blob Storage, only allowed for members"""
try:
handler = AzureFileHandler()
handler.blobName = blob_name
handler.containerName = container_name

handler.deleteBlob()
return Response(
{"detail": "Filen ble slettet"},
status=status.HTTP_200_OK,
)

except ValueError as value_error:
return Response(
{"detail": str(value_error)},

Check warning

Code scanning / CodeQL

Information exposure through an exception Medium

Stack trace information
flows to this location and may be exposed to an external user.
status=status.HTTP_400_BAD_REQUEST,
)
16 changes: 14 additions & 2 deletions app/forms/csv_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@


class SubmissionsCsvWriter:
field_names = ["first_name", "last_name", "email"]
field_names = [
"first_name",
"last_name",
"full_name",
"email",
"study",
"studyyear",
]

def __init__(self, queryset=None):
if queryset is None:
Expand All @@ -27,7 +34,12 @@ def write_csv(self):
def create_row(self, result, submission):
user = submission.user
row = OrderedDict(
first_name=user.first_name, last_name=user.last_name, email=user.email
first_name=user.first_name,
last_name=user.last_name,
full_name=f"{user.first_name} {user.last_name}",
email=user.email,
study=user.study.group.name,
studyyear=user.studyyear.group.name,
)
for answer in submission.answers.all().prefetch_related(
"selected_options", "field"
Expand Down
6 changes: 4 additions & 2 deletions app/forms/models/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,10 @@ def has_write_permission(cls, request):
form = GroupForm.objects.filter(id=form_id).first()
group = form.group if form else None
return (
group and group.has_object_group_form_permission(request)
) or check_has_access(cls.write_access, request)
(group and group.has_object_group_form_permission(request))
or check_has_access(cls.write_access, request)
or request.user.is_leader_of_committee
)

@classmethod
def has_list_permission(cls, request):
Expand Down
1 change: 0 additions & 1 deletion app/tests/kontres/test_reservation_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ def test_reservation_creation_fails_without_sober_watch(member, bookable_item):
)

assert response.status_code == 400
print(response.data)
expected_error_message = "Du må velge en edruvakt for reservasjonen."
actual_error_messages = response.data.get("non_field_errors", [])
assert any(
Expand Down
40 changes: 40 additions & 0 deletions infrastructure/containers.tf
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,26 @@ resource "azurerm_container_app" "lepton-api" {
name = "VIPPS_ORDER_URL"
value = var.vipps_order_url
}
env {
name = "FEIDE_CLIENT_ID"
value = var.feide_client_id
}
env {
name = "FEIDE_CLIENT_SECRET"
value = var.feide_client_secret
}
env {
name = "FEIDE_TOKEN_URL"
value = var.feide_token_url
}
env {
name = "FEIDE_USER_GROUPS_INFO_URL"
value = var.feide_user_groups_info_url
}
env {
name = "FEIDE_REDIRECT_URL"
value = var.feide_redirect_url
}
env {
name = var.enviroment == "pro" ? "PROD" : "DEV"
value = "true"
Expand Down Expand Up @@ -337,6 +357,26 @@ resource "azurerm_container_app" "celery" {
name = "VIPPS_ORDER_URL"
value = var.vipps_order_url
}
env {
name = "FEIDE_CLIENT_ID"
value = var.feide_client_id
}
env {
name = "FEIDE_CLIENT_SECRET"
value = var.feide_client_secret
}
env {
name = "FEIDE_TOKEN_URL"
value = var.feide_token_url
}
env {
name = "FEIDE_USER_GROUPS_INFO_URL"
value = var.feide_user_groups_info_url
}
env {
name = "FEIDE_REDIRECT_URL"
value = var.feide_redirect_url
}
}
}

Expand Down
Loading
Loading