4 Commits

Author SHA1 Message Date
matthias@matsewe.de
e227792f08 Incorporate Choriosity CI 2024-07-02 11:59:10 +02:00
matthias@matsewe.de
ff92ff3020 Fix voting if ajax request fails 2024-06-27 21:18:01 +02:00
matthias@matsewe.de
78d964455c fix 2024-06-25 13:20:55 +02:00
matthias@matsewe.de
6cd1064f1d Adapt for oauth by traefik 2024-06-25 11:46:31 +02:00
7 changed files with 136 additions and 59 deletions

View File

@@ -1,6 +1,6 @@
from typing import Annotated from typing import Annotated
from fastapi import HTTPException, Cookie, status from fastapi import HTTPException, Cookie, status, Request
from fastapi.security import SecurityScopes from fastapi.security import SecurityScopes
from jose import JWTError, jwt from jose import JWTError, jwt
from pydantic import ValidationError from pydantic import ValidationError
@@ -10,9 +10,6 @@ import os
# to get a string like this run: # to get a string like this run:
# openssl rand -hex 32 # openssl rand -hex 32
ALGORITHM = "HS512"
SECRET_KEY = os.environ['SECRET_KEY']
scopes_db = { scopes_db = {
os.environ['ADMIN_EMAIL'] : ["admin"] os.environ['ADMIN_EMAIL'] : ["admin"]
} }
@@ -23,18 +20,17 @@ credentials_exception = HTTPException(
) )
async def get_current_user( async def get_current_user(
security_scopes: SecurityScopes, access_token: Annotated[str, Cookie()] = "" security_scopes: SecurityScopes, request: Request
): ):
try: try:
payload = jwt.decode(access_token, SECRET_KEY, algorithms=[ALGORITHM]) username: str = request.headers.get("x-auth-request-user") # type: ignore
username: str = payload.get("sub") # type: ignore
if username is None: if username is None:
raise credentials_exception raise credentials_exception
email: str = payload.get("email") # type: ignore email: str = request.headers.get("x-auth-request-email") # type: ignore
except (JWTError, ValidationError): except (JWTError, ValidationError):
raise credentials_exception raise credentials_exception
scopes = scopes_db.get(email) scopes = scopes_db.get(email, [])
for scope in security_scopes.scopes: for scope in security_scopes.scopes:
if scope not in scopes: if scope not in scopes:
raise credentials_exception raise credentials_exception
return payload | {"internal_scopes" : scopes} return {"sub" : username, "email" : email, "internal_scopes" : scopes}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,8 +1,55 @@
:root {
--color-white-100: white;
--color-white-90: #e6e6e6;
--color-white-80: #cccccc;
--color-white-70: #b3b3b3;
--color-white-10: #191919;
--color-choriosity-red: #be0519;
--color-choriosity-red--medium: #990514;
--color-choriosity-red--darker: #66030d;
--color-choriosity-red--rgba: 190, 5, 25;
--color-choriosity-red--light: #faeaea;
--color-background: #fffffa;
--color-tap: var(--color-choriosity-red--darker);
--color-callout-bg: var(--color-background);
}
@font-face {
font-family: 'Fira Sans';
src: url(FiraSans-Regular.woff2) format("woff2");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Fira Sans';
src: url(FiraSans-Italic.woff2) format("woff2");
font-weight: 400;
font-style: italic;
}
@font-face {
font-family: 'Fira Sans';
src: url(FiraSans-Medium.woff2) format("woff2");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'Fira Sans';
src: url(FiraSans-SemiBold.woff2) format("woff2");
font-weight: 600;
font-style: normal;
}
* { * {
box-sizing: border-box; box-sizing: border-box;
margin: 0; margin: 0;
padding: 0; padding: 0;
font-family: sans-serif; font-family: Fira Sans, Helvetica, Arial, sans-serif;
} }
.vote-buttons, .vote-buttons,
@@ -31,6 +78,7 @@
padding: 0.3em; padding: 0.3em;
margin-bottom: 0.7em; margin-bottom: 0.7em;
display: inline-block; display: inline-block;
font-size: 1.25rem;
} }
.clear { .clear {
@@ -38,13 +86,13 @@
} }
.song { .song {
background-color: #f0f0f0; background-color: var(--color-choriosity-red--light);
padding: 0.4em; padding: 0.4em;
border-radius: 0.5em; border-radius: 0.5em;
width: 30em; width: 30em;
font-family: sans-serif;
margin-bottom: 1rem; margin-bottom: 1rem;
margin-left: 0.5em; margin-left: 0.5em;
float: left;
} }
@@ -225,21 +273,28 @@
} }
h1 { h1 {
font-family: sans-serif;
padding: 0.1em; padding: 0.1em;
padding-left: 0.2em; padding-left: 0.2em;
margin-bottom: 1rem; margin-bottom: 1rem;
font-size: 1.5em; font-size: 1.25rem;
background-color: var(--color-choriosity-red);
color: white;
/*border-bottom: 0.3rem solid var(--color-choriosity-red--light);*/
clear: both;
}
#songs h1 .color {
border: 0.2rem solid color-mix(in srgb, hsl(calc(var(--hue) * 360), 100%, 40%) 50%, white);
background-color: hsl(calc(var(--hue) * 360), 100%, 40%);
border-radius: 0.5em;
margin-right: 1em;
} }
#songs h1 { #songs h1 {
background-color: color-mix(in srgb, hsl(calc(var(--hue) * 360), 100%, 40%) 50%, transparent); border-left: 0.3em solid white;
border-bottom: 0.3rem solid hsl(calc(var(--hue) * 360), 100%, 40%); box-shadow: -1em 0px 0px 0px hsl(calc(var(--hue) * 360), 100%, 40%);
} margin-left: 1em;
padding-left: 0.3em;
body>h1 {
background-color: color-mix(in srgb, hsl(0, 0%, 40%) 50%, transparent);
border-bottom: 0.3rem solid hsl(0, 0%, 40%);
} }
#yt-player, #yt-player,
@@ -279,3 +334,18 @@ body>h1 {
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
width: 1.5em; width: 1.5em;
} }
#title {
margin-top: 1em;
font-size: 2rem;
/*line-height: 2rem;*/
}
#title-logo {
margin-top: -0.7em;
margin-bottom: -0.8em;
vertical-align: middle;
height: 3em;
filter: drop-shadow(0 0 1px var(--color-choriosity-red--medium));
margin-right: 1em;
}

View File

@@ -19,6 +19,7 @@
border-radius: 0.2em; border-radius: 0.2em;
padding: 0.1em; padding: 0.1em;
} }
.not_singable { .not_singable {
background-color: color-mix(in srgb, #e1412f 30%, #f0f0f0); background-color: color-mix(in srgb, #e1412f 30%, #f0f0f0);
} }
@@ -124,6 +125,12 @@
} }
function vote(song_id, vote) { function vote(song_id, vote) {
$.ajax({
url: "/songs/" + song_id + "/vote?" + $.param({ session_id: session_id, vote: vote }),
method: "POST",
success: function (data, textStatus) {
no_button = $("#song-" + song_id).find(".button-no") no_button = $("#song-" + song_id).find(".button-no")
yes_button = $("#song-" + song_id).find(".button-yes") yes_button = $("#song-" + song_id).find(".button-yes")
neutral_button = $("#song-" + song_id).find(".button-neutral") neutral_button = $("#song-" + song_id).find(".button-neutral")
@@ -155,10 +162,12 @@
break; break;
} }
$.ajax({ }
url: "/songs/" + song_id + "/vote?" + $.param({ session_id: session_id, vote: vote }), });
method: "POST"
})
} }
{% if veto_mode %} {% if veto_mode %}
@@ -176,11 +185,12 @@
<body> <body>
{% if veto_mode %} {% if veto_mode %}
<h1>Vorschau Modus</h1> <h1>Vorschau Modus</h1>
<div class="text">Du kannst ungeeignete Vorschläge durch eine Nein-Stimme markieren und Kommentare zu allen Liedern abgeben. <div class="text">Du kannst ungeeignete Vorschläge durch eine Nein-Stimme markieren und Kommentare zu allen Liedern
abgeben.
</div> </div>
{% else %} {% else %}
<h1>Hallo :)</h1> <h1 id="title"><img id="title-logo" src="https://choriosity.de/assets/images/logo-choriosity_weiss.svg"> Liederwahl</h1>
<div class="text">Du kannst die Liederwahl jederzeit unterbrechen und zu einem späteren Zeitpunkt weitermachen. <div class="text">Du kannst die Liederwahl jederzeit unterbrechen und zu einem späteren Zeitpunkt weitermachen. Mit einem Klick auf das Thumbnail kannst du das Lied abspielen.
</div> </div>
{% endif %} {% endif %}
<div id="songs"> <div id="songs">
@@ -222,7 +232,8 @@
{% if veto_mode %} {% if veto_mode %}
<input type="text" class="comment" <input type="text" class="comment"
value="{% if song.vote_comment %}{{ song.vote_comment }}{% else %}{% endif %}" value="{% if song.vote_comment %}{{ song.vote_comment }}{% else %}{% endif %}"
placeholder="{% if song.comment %}{{ song.comment }}{% else %}Kommentar{% endif %}" onchange="updateComment({{ song.id }}, this);"> placeholder="{% if song.comment %}{{ song.comment }}{% else %}Kommentar{% endif %}"
onchange="updateComment({{ song.id }}, this);">
{% endif %} {% endif %}
</div> </div>
{% endfor %} {% endfor %}