29 Commits

Author SHA1 Message Date
Aarni Halinen 44e63b6105 Fix tests 2022-10-24 21:46:08 +03:00
Aarni Halinen dae78ee976 Add tests 2022-10-24 21:43:29 +03:00
Aarni Halinen f813eaf9bf Update node to v16 in CI 2022-10-24 21:43:29 +03:00
Aarni Halinen 8baea20824 Add .nvmrc 2022-10-24 21:43:29 +03:00
Aarni Halinen 393ee997d9 Add delete path for SignupViewSet 2022-10-24 21:43:29 +03:00
Aarni Halinen f67ce55d60 Fix webapp test as module 2022-10-24 21:42:41 +03:00
Ojakoo 5e1390ab6b Changes to kaehmy categories 2022-10-05 14:18:28 +03:00
Ojakoo 99348dc297 Update dparse 2022-10-05 12:58:29 +03:00
Ojakoo 715b309c89 Added new categories for kaehmy 2022-10-05 12:43:52 +03:00
Ojakoo 70676d5203 Lint 2022-09-23 20:53:25 +03:00
Ojakoo 037e4ae6e8 Use html templates for kaehmy emails. No translations for now. 2022-09-23 20:30:08 +03:00
Ojakoo 8d6f13b61d Update privacy policy link 2022-09-23 17:57:36 +03:00
Ojakoo 03982ee620 Update kaehmy dates and change header to html instead of picture. 2022-09-23 17:51:01 +03:00
Ojakoo a8923b63d6 wrap private key 2022-09-13 13:31:58 +03:00
Ojakoo 19975877cb Remove debug stuff 2022-09-13 09:59:55 +03:00
Ojakoo 2e0fad4bb2 Use POSIX format for source 2022-09-12 22:42:01 +03:00
Ojakoo f0179c1840 Change google creds format. Ugly but works. 2022-09-12 22:38:18 +03:00
Ojakoo 37a9750d4d Add group key and dev secrets to stack compose 2022-09-05 13:38:26 +03:00
Ojakoo 5575186570 lint 2022-09-05 12:03:31 +03:00
Ojakoo 9e179d5e06 Added error handling for incorrectly formatted google creds 2022-09-05 10:40:29 +03:00
Ojakoo ea9a732803 Modified paths 2022-08-17 23:00:11 +03:00
Ojakoo 0026b788b2 juuh eli 2022-08-16 23:00:36 +03:00
Ojakoo da3a484f6c wbn? 2022-08-16 22:24:20 +03:00
Ojakoo a310d51f5e or not 2022-08-16 21:43:04 +03:00
Ojakoo 6732e30213 #14 fix paths 2022-08-16 21:26:55 +03:00
Ojakoo 4e59eee200 Enable GOOGLE_SERVICE_ACCOUNT, should work now.. 2022-08-16 20:59:19 +03:00
Aarni Halinen bb0b2a2628 Fix kaehmy form 2022-08-11 11:28:30 +03:00
Aarni Halinen 32d636d3ee Disable GOOGLE_SERVICE_ACCOUNT for debugging 2022-08-11 09:52:58 +03:00
Ojakoo c91b99cdb1 lol 2022-08-09 21:44:01 +03:00
35 changed files with 1511 additions and 1364 deletions
+1 -1
View File
@@ -10,4 +10,4 @@ DB_HOST=db
DB_PORT=5432
EMAIL_API_KEY=
GROUP_KEY=
GOOGLE_CREDS_JSON='{}'
GOOGLE_CREDS='{}'
+3 -3
View File
@@ -7,7 +7,7 @@ stages:
- deploy
install:
image: node:14
image: node:16
stage: setup
script:
- npm ci
@@ -57,14 +57,14 @@ lint:py:
- black --check .
lint:js:
image: node:14
image: node:16
stage: lint
needs: ["install"]
script:
- npm run lint:js
lint:md:
image: node:14
image: node:16
stage: lint
needs: ["install"]
script:
+1 -1
View File
@@ -4,7 +4,7 @@
PURPLE='\033[0;35m'
NC='\033[0m' # No Color
source "${VIRTUAL_ENV}/bin/activate"
. "${VIRTUAL_ENV}/bin/activate"
if [ $? -ne 0 ]
then
+1 -1
View File
@@ -4,7 +4,7 @@
PURPLE='\033[0;35m'
NC='\033[0m' # No Color
source "${VIRTUAL_ENV}/bin/activate"
. "${VIRTUAL_ENV}/bin/activate"
if [ $? -ne 0 ]
then
+1
View File
@@ -0,0 +1 @@
16
+4 -4
View File
@@ -6,15 +6,15 @@ from kaehmy.models import PresetRole, CustomRole, Application, Comment, BaseRole
class CheckboxSelectMultiple(forms.widgets.CheckboxSelectMultiple):
option_template_name = "kaehmy/checkbox_option.html"
option_template_name = "checkbox_option.html"
def create_option(
self, name, value, label, selected, index, subindex=None, attrs=None
self, name, formIterator, label, selected, index, subindex=None, attrs=None
):
dic = super(CheckboxSelectMultiple, self).create_option(
name, value, label, selected, index, subindex, attrs
name, formIterator, label, selected, index, subindex, attrs
)
description = PresetRole.objects.get(id=value).description
description = PresetRole.objects.get(id=formIterator.value).description
dic["description"] = description
return dic
+4 -1
View File
@@ -13,6 +13,7 @@ class BaseRole(models.Model):
is_board = models.BooleanField(_("Board member"))
CATEGORIES = (
("board", _("Board")),
("corporate", _("Corporate affairs")),
("freshman", _("Freshmen")),
("international", _("International")),
@@ -20,11 +21,13 @@ class BaseRole(models.Model):
("media", _("Media")),
("tech", _("Technology")),
("wellbeing", _("Wellbeing")),
("elepaja", _("Elepaja")),
("sikpaja", _("Sik-paja")),
("ceremonies", _("Ceremonies")),
("studies", _("Studies")),
("sosso", _("Sössö magazine")),
("pota", _("PoTa")),
("alumni", _("Alumni relations")),
("n", _("N")),
("others", _("Others")),
)
category = models.CharField(
+4 -6
View File
@@ -5,12 +5,6 @@
margin-right: auto;
}
body {
max-width: 1000px;
margin-left: auto !important;
margin-right: auto !important;
}
div.tooltip-inner {
max-width: 25rem;
}
@@ -28,6 +22,10 @@ div.tooltip-inner {
.kaehmy-content {
padding-left: 0.5rem;
padding-right: 0.5rem;
max-width: 1000px;
width: 100%;
margin-left: auto;
margin-right: auto;
}
p {
+2 -5
View File
@@ -3,13 +3,9 @@
}
footer {
/* position: absolute; */
bottom: 0;
width: 100%;
height: 60px; /* Set the fixed height of the footer here */
/* line-height: 60px; /* Vertically center the text there */
margin-top: 2rem;
margin-bottom: 1rem;
margin: 1rem;
}
footer .container .col .nav .nav-item {
@@ -26,6 +22,7 @@ footer .container .col .nav .nav-item {
.lang-select {
width: 10rem;
margin-bottom: 1rem;
display: inline-block;
}
+18 -27
View File
@@ -1,37 +1,28 @@
.header-content {
.kaehmy-header {
background-color: #0c2938;
}
.header-content .logo {
.kaehmy-header-content {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
}
.header-content .logo img {
display: block;
height: auto;
margin: auto;
}
.kaehmy-banner {
max-width: 1000px;
width: 100%;
margin-left: auto;
margin-right: auto;
}
@media screen and (min-width: 1000px) {
.kaehmy_header-content {
position: absolute;
left: 0;
top: 0;
background-color: #0c2938;
width: 100%;
}
.kaehmy_header {
margin-bottom: 331px;
}
}
.kaehmy-banner-image {
width: 100%;
max-height: 10rem;
max-width: 100%;
}
.heading {
display: flex;
place-content: center;
flex-direction: column;
text-align: center;
margin: 1rem;
}
+7 -3
View File
@@ -1,11 +1,15 @@
.kaehmy_navigation {
margin-bottom: 10px;
}
.navbar-border {
border-bottom: 2px solid #282b3b;
}
.navbar-light .navbar-nav .nav-link {
color: black;
}
.navbar {
max-width: 1000px;
width: 100%;
margin-left: auto;
margin-right: auto;
}
+10 -10
View File
@@ -4,6 +4,7 @@ from django.views.decorators.http import require_http_methods
from django.views.decorators.csrf import ensure_csrf_cookie
from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django.template.loader import render_to_string
import logging
from sikweb.settings import URL
@@ -64,14 +65,15 @@ def comment(request, *args, **kwargs):
if form.is_valid():
comment = form.save()
name = comment.name
url = f"https://{URL}/kaehmy"
to_email = comment.parent.email
subject = "Kaehmyysi tai kommenttiisi on vastattu!"
email_body = (
f"{name.capitalize()} on vastannut kaehmyhakemukseesi tai kommenttiisi kaehmypalvelussa.\r\n\r\n"
"Käy lukemassa viesti osoitteessa https://{URL}/kaehmy"
message = render_to_string(
"kaehmy/email_comment.html", {"name": name, "url": url}
)
send_email(to=to_email, subject=subject, body=email_body)
send_email(to=to_email, subject=subject, body=message, html=True)
logging.debug(f"Sent kaehmy comment email to recipient <{to_email}>")
return redirect("/kaehmy")
@@ -129,16 +131,14 @@ def submit(request, *args, **kwargs):
url = f"https://{URL}/kaehmy"
name = form.cleaned_data.get("name", "Anonymous")
email_body = (
f"Moikka {name}!\r\n\r\nHienoa, että kilta kiinnostaa! Kaehmysi on vastaanotettu.\r\n"
"Mahdollisista kommenteista tulee ilmoitus sähköpostitse.\r\n\r\n"
"Käy katsomassa kaehmytilanne osoitteessa {url}"
)
to_email = form.cleaned_data.get("email", "")
subject = "Arwokas kirjattu kirje mahdolliselle tulewalle kiltahenkilölle"
message = render_to_string(
"kaehmy/email_kaehmy.html", {"name": name, "url": url}
)
send_email(to_email, subject, email_body)
send_email(to=to_email, subject=subject, body=message, html=True)
logging.debug(f"Sent kaehmy email to recipient <{to_email}>")
processHooks(message=f"Uusi New kaehmy! {name} -> {url}", eventType="kaehmy")
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Generated
+5 -8
View File
@@ -241,14 +241,14 @@ Django = ">=3.2"
[[package]]
name = "django-phonenumber-field"
version = "6.3.0"
version = "6.4.0"
description = "An international phone number field for django models."
category = "main"
optional = false
python-versions = ">=3.7"
[package.dependencies]
Django = ">=2.2"
Django = ">=3.2"
phonenumbers = {version = ">=7.0.2", optional = true, markers = "extra == \"phonenumbers\""}
[package.extras]
@@ -314,7 +314,7 @@ test = ["cryptography", "pytest-cov", "pytest-django", "pytest-xdist", "pytest",
[[package]]
name = "dparse"
version = "0.5.1"
version = "0.6.2"
description = "A parser for Python dependency files"
category = "dev"
optional = false
@@ -322,11 +322,11 @@ python-versions = ">=3.5"
[package.dependencies]
packaging = "*"
pyyaml = "*"
toml = "*"
[package.extras]
pipenv = ["pipenv"]
conda = ["pyyaml"]
[[package]]
name = "et-xmlfile"
@@ -1093,10 +1093,7 @@ djangorestframework-simplejwt = [
{file = "djangorestframework_simplejwt-5.2.0-py3-none-any.whl", hash = "sha256:bcc4cb74dcb637ca1e17eed35276bd618ab19491f8c53e65dee6271177c355e8"},
{file = "djangorestframework_simplejwt-5.2.0.tar.gz", hash = "sha256:a60b09afb27d91ad1d7ac904cc632bd52cecead8f389f0fa1532ceb0fb757a74"},
]
dparse = [
{file = "dparse-0.5.1-py3-none-any.whl", hash = "sha256:e953a25e44ebb60a5c6efc2add4420c177f1d8404509da88da9729202f306994"},
{file = "dparse-0.5.1.tar.gz", hash = "sha256:a1b5f169102e1c894f9a7d5ccf6f9402a836a5d24be80a986c7ce9eaed78f367"},
]
dparse = []
et-xmlfile = [
{file = "et_xmlfile-1.1.0-py3-none-any.whl", hash = "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"},
{file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"},
+17 -2
View File
@@ -10,8 +10,23 @@ fi
if test -f "$DB_PASSWD_FILE"; then
export DB_PASSWD=$(cat $DB_PASSWD_FILE)
fi
if test -f "$GOOGLE_CREDS_JSON"; then
export GOOGLE_CREDS_JSON=$(cat $GOOGLE_CRED_JSON_FILE)
if test -f "$G_PRIVATE_KEY_ID_FILE"; then
export G_PRIVATE_KEY_ID=$(cat $G_PRIVATE_KEY_ID_FILE)
fi
if test -f "$G_PRIVATE_KEY_FILE"; then
export G_PRIVATE_KEY="$(cat $G_PRIVATE_KEY_FILE)"
fi
if test -f "$G_CLIENT_EMAIL_FILE"; then
export G_CLIENT_EMAIL=$(cat $G_CLIENT_EMAIL_FILE)
fi
if test -f "$G_CLIENT_ID_FILE"; then
export G_CLIENT_ID=$(cat $G_CLIENT_ID_FILE)
fi
if test -f "$G_CLIENT_URL_FILE"; then
export G_CLIENT_URL=$(cat $G_CLIENT_URL_FILE)
fi
if test -f "$GROUP_KEY_FILE"; then
export GROUP_KEY=$(cat $GROUP_KEY_FILE)
fi
# Collect static files
+13 -1
View File
@@ -82,7 +82,19 @@ DATABASES = {
# Google api settings
GROUP_KEY = os.getenv("GROUP_KEY", "")
GOOGLE_SERVICE_ACCOUNT = json.loads(os.getenv("GOOGLE_CREDS_JSON", "{}"))
GOOGLE_CREDS = {
"type": "service_account",
"project_id": "web2-backend",
"private_key_id": os.getenv("G_PRIVATE_KEY_ID", ""),
"private_key": os.getenv("G_PRIVATE_KEY", ""),
"client_email": os.getenv("G_CLIENT_EMAIL", ""),
"client_id": os.getenv("G_CLIENT_ID", ""),
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": os.getenv("G_CLIENT_URL", ""),
}
# JWT authentication
SIMPLE_JWT = {
+24
View File
@@ -29,15 +29,39 @@ services:
- FRONTEND_URL=dev.sahkoinsinoorikilta.fi
- DEBUG=True
- EMAIL_API_KEY_FILE=/run/secrets/DJANGO_EMAIL_API_KEY
- G_PRIVATE_KEY_ID_FILE=/run/secrets/BACKEND_G_PRIVATE_KEY_ID
- G_PRIVATE_KEY_FILE=/run/secrets/BACKEND_G_PRIVATE_KEY
- G_CLIENT_EMAIL_FILE=/run/secrets/BACKEND_G_CLIENT_EMAIL
- G_CLIENT_ID_FILE=/run/secrets/BACKEND_G_CLIENT_ID
- G_CLIENT_URL_FILE=/run/secrets/BACKEND_G_CLIENT_URL
- GROUP_KEY_FILE=/run/secrets/BACKEND_GROUP_KEY
- DB_HOST=db
- DB_PORT=5432
secrets:
- DJANGO_EMAIL_API_KEY
- BACKEND_G_PRIVATE_KEY_ID
- BACKEND_G_PRIVATE_KEY
- BACKEND_G_CLIENT_EMAIL
- BACKEND_G_CLIENT_ID
- BACKEND_G_CLIENT_URL
- BACKEND_GROUP_KEY
secrets:
DJANGO_EMAIL_API_KEY:
external: true
BACKEND_G_PRIVATE_KEY_ID:
external: true
BACKEND_G_PRIVATE_KEY:
external: true
BACKEND_G_CLIENT_EMAIL:
external: true
BACKEND_G_CLIENT_ID:
external: true
BACKEND_G_CLIENT_URL:
external: true
BACKEND_GROUP_KEY:
external: true
volumes:
dbdata:
+25 -4
View File
@@ -34,13 +34,24 @@ services:
- SECRET_KEY_FILE=/run/secrets/BACKEND_SECRET_KEY
- DB_PASSWD_FILE=/run/secrets/BACKEND_DB_PASSWD
- EMAIL_API_KEY_FILE=/run/secrets/BACKEND_EMAIL_API_KEY
- GOOGLE_CREDS_JSON=/run/secrets/GOOGLE_CREDS_JSON
- G_PRIVATE_KEY_ID_FILE=/run/secrets/BACKEND_G_PRIVATE_KEY_ID
- G_PRIVATE_KEY_FILE=/run/secrets/BACKEND_G_PRIVATE_KEY
- G_CLIENT_EMAIL_FILE=/run/secrets/BACKEND_G_CLIENT_EMAIL
- G_CLIENT_ID_FILE=/run/secrets/BACKEND_G_CLIENT_ID
- G_CLIENT_URL_FILE=/run/secrets/BACKEND_G_CLIENT_URL
- GROUP_KEY_FILE=/run/secrets/BACKEND_GROUP_KEY
secrets:
- BACKEND_SECRET_KEY
- BACKEND_DB_PASSWD
- BACKEND_EMAIL_API_KEY
- GOOGLE_CREDS_JSON
- BACKEND_G_PRIVATE_KEY_ID
- BACKEND_G_PRIVATE_KEY
- BACKEND_G_CLIENT_EMAIL
- BACKEND_G_CLIENT_ID
- BACKEND_G_CLIENT_URL
- BACKEND_GROUP_KEY
secrets:
BACKEND_SECRET_KEY:
external: true
@@ -48,5 +59,15 @@ secrets:
external: true
BACKEND_EMAIL_API_KEY:
external: true
GOOGLE_CREDS_JSON:
EXTERNAL: true
BACKEND_G_PRIVATE_KEY_ID:
external: true
BACKEND_G_PRIVATE_KEY:
external: true
BACKEND_G_CLIENT_EMAIL:
external: true
BACKEND_G_CLIENT_ID:
external: true
BACKEND_G_CLIENT_URL:
external: true
BACKEND_GROUP_KEY:
external: true
+1 -1
View File
@@ -13,7 +13,7 @@
{% block body %}
{% block header %}
<div class="kaehmy_header">
<div class="kaehmy-header">
{% include "kaehmy/header.html" %}
</div>
{% endblock header %}
+10
View File
@@ -0,0 +1,10 @@
{% load i18n %}
<p>
Hei!
</p>
<p>
{{ name }} on vastannut kaehmyhakemukseesi tai kommenttiisi kaehmypalvelussa.
Käy lukemassa viesti
<a href={{ url }}>täältä.</a>
</p>
+13
View File
@@ -0,0 +1,13 @@
{% load i18n %}
<p>
Moikka {{ name }}!
</p>
<p>
Hienoa, että kilta kiinnostaa! Kaehmysi on vastaanotettu.
Mahdollisista kommenteista tulee ilmoitus sähköpostitse.
</p>
<p>
Käy katsomassa kaehmytilanne
<a href={{ url }}>täältä.</a>
</p>
+1 -1
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "kaehmy/base.html" %}
{% load static %}
{% load i18n %}
+9 -2
View File
@@ -1,7 +1,14 @@
{% load i18n %}
<div class="kaehmy_header-content">
<div class="kaehmy-header-content center">
<div class="kaehmy-banner logo">
<a href="/kaehmy"><img class="kaehmy-banner-image" src="/static/kaehmy/img/kaehmy_banner.png" alt="Aalto-yliopiston Sähköinsinöörikilta ry"></a>
<a href="/kaehmy">
<img class="kaehmy-banner-image" src="https://static.sahkoinsinoorikilta.fi/logot-ja-grafiikka/web/side/SIK_RGB_W_side.png" alt="Aalto-yliopiston Sähköinsinöörikilta ry">
</a>
</div>
<div class="kaehmy-banner heading">
<p style="color:#D57A2D; font-size:2rem">{% blocktrans %}Kähmyt ovat auki!{% endblocktrans %}</p>
<p style="color:#BFDBD9; font-size:1rem">{% blocktrans %}Haku hallitukseen 24.10. mennessä ja toimihenkilöksi 18.11 mennessä.{% endblocktrans %}</p>
<p style="color:#BFDBD9; font-size:1.5rem">{% blocktrans %}Hae nyt!{% endblocktrans %}</p>
</div>
</div>
+7 -5
View File
@@ -28,10 +28,12 @@
</p>
<h5>{% trans "Päivämääriä & deadlineja" %}</h5>
<ul>
<li><strong>25.10.</strong> {% blocktrans %}Vaalikokous, osa 1 (puheenjohtajan valinta) ja hallitustyrkkypaneeli{% endblocktrans %}</li>
<li><strong>01.11.</strong> {% blocktrans %}Vaalikokous, osa 2 (hallituksen valinta){% endblocktrans %}</li>
<li><strong>09.11.</strong> {% blocktrans %}Toimikunta-appro{% endblocktrans %}</li>
<li><strong>17.11.</strong> {% blocktrans %}Vaalikokous, osa 3 (toimarien valinta){% endblocktrans %}</li>
<li><strong>11.10.</strong> {% blocktrans %}Toimikuntamessut @OK20{% endblocktrans %}</li>
<li><strong>24.10.</strong> {% blocktrans %}Deadline hallitusvirkoihin hakemiselle.{% endblocktrans %}</li>
<li><strong>25.10.</strong> {% blocktrans %}Vaalikokous, osa 1 (puheenjohtajan valinta) ja hallitustyrkkypaneeli{% endblocktrans %}</li>
<li><strong>07.11.</strong> {% blocktrans %}Vaalikokous, osa 2 (hallituksen valinta){% endblocktrans %}</li>
<li><strong>18.11.</strong> {% blocktrans %}Deadline toimivirkoihin hakemiselle.{% endblocktrans %}</li>
<li><strong>24.11.</strong> {% blocktrans %}Vaalikokous, osa 3 (toimarien valinta){% endblocktrans %}</li>
</ul>
<form name="kaehmyForm" action="/kaehmy/submit/" method="post" class="form">{% csrf_token %}
{% bootstrap_field form.name %}
@@ -75,7 +77,7 @@
<input type="checkbox" required name="gdpr" value="1">
<span>{% blocktrans %}
Hyväksyn <a href="https://static.sahkoinsinoorikilta.fi/GDPR/Tietosuojaseloste%20%23U2013%20Toimihenkil%23U00f6ksi%20hakemisen%20rekisteri.pdf" target="_blank">tietosuojaselosteen</a> ja tietojeni tallentamisen.
Hyväksyn <a href="https://static.sahkoinsinoorikilta.fi/GDPR/Tietosuojaseloste%20%E2%80%93%20Toimihenkil%C3%B6ksi%20hakemisen%20rekisteri.pdf" target="_blank">tietosuojaselosteen</a> ja tietojeni tallentamisen.
{% endblocktrans %}
</span>
{% buttons %}
+1 -1
View File
@@ -2,7 +2,7 @@
<div class="card" style="margin-top: 0.5rem; margin-bottom: 0">
<div class="card-block">
<h4>{{ message.name }}</h4>
<h4>{{ message.name }}</h4>
<p>{{ message.message|linebreaks|urlize }}</p>
<h6 class="card-subtitle mb-2 text-muted">{{ message.timestamp }}</h6>
+2 -2
View File
@@ -1,8 +1,8 @@
{% load i18n %}
{% load static %}
<div class="kaehmy_navigation">
<nav class="navbar-border navbar navbar-toggleable-md navbar-light bg-faded">
<div class="kaehmy_navigation bg-faded">
<nav class="navbar navbar-toggleable-md navbar-light">
<div class="navbar-nav">
<a class="nav-item nav-link" href="/kaehmy">{% trans "List kaehmys" %}</a>
<a class="nav-item nav-link" href="/kaehmy/new">{% trans "New kaehmy" %} <span class="sr-only">(current)</span></a>
+1 -1
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "members/base.html" %}
{% load static %}
{% load i18n %}
View File
+22 -6
View File
@@ -22,6 +22,13 @@ class SignupTestCase(APITestCase):
self.signup1 = createSignupObject("1", self.signupForm, ALL_QUESTION_TYPES)
self.signup2 = createSignupObject("2", self.signupForm, ALL_QUESTION_TYPES)
self.signup_admin_delete = createSignupObject(
"3", self.signupForm, ALL_QUESTION_TYPES
)
self.signup_user_delete = createSignupObject(
"4", self.signupForm, ALL_QUESTION_TYPES
)
self.signup_count = 4
username, password = "test_admin", "password123"
self.authClient = User.objects.create_superuser(
@@ -49,17 +56,17 @@ class SignupTestCase(APITestCase):
new = createSignupRequest("asd", self.signupForm.id, ALL_QUESTION_TYPES_ANSWER)
response = self.client.post(URL, new, format="json")
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(Signup.objects.count(), 3)
self.assertEqual(Signup.objects.count(), self.signup_count + 1)
# Can signup to a hidden form
def test_create_signup_hidden(self):
new = createSignupRequest("asd", self.hiddenForm.id, ALL_QUESTION_TYPES_ANSWER)
response = self.client.post(URL, new, format="json")
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(Signup.objects.count(), 3)
self.assertEqual(Signup.objects.count(), self.signup_count + 1)
def test_delete_as_admin(self):
id = self.signup1.id
id = self.signup_admin_delete.id
no_auth_response = self.client.delete(f"{URL}{id}/", format="json")
self.assertEqual(no_auth_response.status_code, status.HTTP_401_UNAUTHORIZED)
self.client.force_authenticate(user=self.authClient)
@@ -81,9 +88,18 @@ class SignupTestCase(APITestCase):
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(Signup.objects.get(id=id).answer["-naY2R1-h"], "Edited Testi")
@skip("NotImplemented")
def test_delete_signup_token(self):
pass
def test_delete_as_user(self):
bad_uuid = "d5a98794-8330-45b4-8ed4-cdb84198649b"
id = self.signup_user_delete.id
uuid = self.signup_user_delete.uuid
no_auth_response = self.client.delete(f"{URL}{id}/delete/?uuid={bad_uuid}")
self.assertEqual(no_auth_response.status_code, status.HTTP_404_NOT_FOUND)
self.assertEqual(Signup.objects.get(id=id).deleted, False)
response = self.client.delete(f"{URL}{id}/delete/?uuid={uuid}")
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(Signup.objects.get(id=id).deleted, True)
# TODO: Use some mocking library and check that sendgrid is actually called
def test_signupee_sendemail(self):
+13 -2
View File
@@ -25,7 +25,7 @@ from sikweb.settings import (
DEFAULT_EMAIL_FROM_ADDR,
ENABLE_AUTOMATIC_EMAILS,
GROUP_KEY,
GOOGLE_SERVICE_ACCOUNT,
GOOGLE_CREDS,
)
from datetime import timedelta
@@ -136,7 +136,7 @@ def add_to_mailinglist(email: str):
# create credentials, with subject is used to impersonate admin account
# jas_manager has groups editor rights in google admin
credentials = service_account.Credentials.from_service_account_info(
info=GOOGLE_SERVICE_ACCOUNT, scopes=SCOPES
info=GOOGLE_CREDS, scopes=SCOPES
).with_subject("jas_manager@sahkoinsinoorikilta.fi")
service = build("admin", "directory_v1", credentials=credentials)
@@ -157,3 +157,14 @@ def add_to_mailinglist(email: str):
)
send_email(to, subject, body)
except ValueError as err:
logging.exception("Formatting of google credentials is incorrect")
if DEPLOY_ENV == "production":
to = "ilari.ojakorpi@sahkoinsinoorikilta.fi"
subject = "Web error: Failed adding to google groups"
body = "Google credential formatted incorretly\nEmail that was not added: {}\n\nAdd user manually to jäsenet groups.".format(
email
)
send_email(to, subject, body)
+21 -1
View File
@@ -200,7 +200,13 @@ class SignupViewSet(ModelViewSet):
serializer_class = SignupSerializer
permission_classes = [SignupPermission]
@action(detail=True, methods=["get", "put"], permission_classes=[AllowAny])
@action(
url_path="edit",
url_name="edit",
detail=True,
methods=["get", "put"],
permission_classes=[AllowAny],
)
def edit(self, request, pk=None, *args, **kwargs):
uuid = request.query_params.get("uuid", None)
queryset = self.filter_queryset(self.get_queryset())
@@ -211,6 +217,20 @@ class SignupViewSet(ModelViewSet):
elif request.method == "PUT":
return self.partial_update(request, *args, **kwargs)
@action(
url_path="delete",
url_name="delete",
detail=True,
methods=["delete"],
permission_classes=[AllowAny],
)
def user_delete(self, request, pk=None, *args, **kwargs):
uuid = request.query_params.get("uuid", None)
queryset = self.filter_queryset(self.get_queryset())
filter = {"pk": pk, "uuid": uuid}
get_object_or_404(queryset, **filter)
return self.destroy(request, *args, **kwargs)
def create(self, request, *args, **kwargs):
id = request.data["signupForm_id"]
try: