summaryrefslogtreecommitdiff
path: root/20-implementierungsheft/sections/changes.tex
diff options
context:
space:
mode:
Diffstat (limited to '20-implementierungsheft/sections/changes.tex')
-rw-r--r--20-implementierungsheft/sections/changes.tex241
1 files changed, 241 insertions, 0 deletions
diff --git a/20-implementierungsheft/sections/changes.tex b/20-implementierungsheft/sections/changes.tex
new file mode 100644
index 0000000..20df017
--- /dev/null
+++ b/20-implementierungsheft/sections/changes.tex
@@ -0,0 +1,241 @@
+\newenvironment{urlParameter}
+{
+ \newcommand{\urlParamItem}[2]
+ {
+ \rowcolor{\methodLightColor} ##1 & ##2 \\
+ }
+ \newcommand{\noUrlParameter}[1]
+ {
+ \small{\textit{##1}}
+ }
+ %\vspace{-0.61em}
+
+ \arrayrulecolor{\methodColor}
+
+ \begin{tabularx}{\textwidth}{X}
+ \rowcolor{\methodLightColor!20}
+ \textbf{URL-Parameter} \\ \hline
+ \end{tabularx}
+
+ \tabularx{\textwidth}{l X}
+}
+
+\newenvironment{pathParameter}
+{
+ \newcommand{\pathParamItem}[2]
+ {
+ \rowcolor{\methodLightColor} ##1 & ##2 \\
+ }
+ \newcommand{\noPathParameter}[1]
+ {
+ \small{\textit{##1}}
+ }
+ %\vspace{-0.61em}
+
+ \arrayrulecolor{\methodColor}
+
+ \begin{tabularx}{\textwidth}{X}
+ \rowcolor{\methodLightColor!20}
+ \textbf{Pfad-Parameter} \\ \hline
+ \end{tabularx}
+
+ \tabularx{\textwidth}{l X}
+}
+
+\newenvironment{jsonKeys}
+{
+ \newcommand{\jsonKeyItem}[2]
+ {
+ \rowcolor{\methodLightColor} ##1 & ##2 \\
+ }
+ \newcommand{\nojsonKeys}[1]
+ {
+ \small{\textit{##1}}
+ }
+ %\vspace{-0.61em}
+
+ \arrayrulecolor{\methodColor}
+
+ \begin{tabularx}{\textwidth}{X}
+ \rowcolor{\methodLightColor!20}
+ \textbf{Json-Keys} \\ \hline
+ \end{tabularx}
+
+ \tabularx{\textwidth}{l X}
+}
+
+
+\section{Änderungen zum Entwurfsheft}
+
+Im Folgenden werden die Änderungen zum Entwurfsheft aufgelistet und erläutert warum diese
+Änderungen gemacht wurden.
+
+
+\subsection{Kompatibilität mit \Glspl{podcatcher}}
+
+Um die Kompatibilität mit \Glspl{podcatcher} - insbesondere AntennaPod und Kasts - sicherzustellen, mussten einige Änderungen vorgenommen werden.
+
+\subsubsection*{Speicherung von Benutzernamen und E-Mail-Adressen}
+
+AntennaPod erlaubt bei der Verknüpfung mit einem Synchronisations-Server nur die Anmeldung mit einem Benutzername, der keine E-Mail-Adresse ist.
+Deshalb werden nun sowohl ein Benutzername als auch eine E-Mail-Adresse für jeden Nutzer gespeichert.
+Der Benutzername wird dabei unverschlüsselt gespeichert.
+Er wird zur Authentifizierung sowie für die Zuordnung der Anfragen verwendet.
+Die E-Mail-Adresse hingegen, wird vor der Speicherung mit einem festen Geheimschlüssel gesalted und anschließend gehashed.
+Sie existiert lediglich um bei einer Passwort-vergessen-Anfrage denjenigen Nutzer zu finden, zu dem die übergebene E-Mail-Adresse gehört, beziehungsweise dessen Existenz zu überprüfen.
+Diese Änderung impliziert eine Anpassung des Formats, in dem Registrierungsanfragen als \GLS{json}-Payload übergeben werden.
+Wie in der folgenden aktualisierten Spezifikation zu sehen existiert nun ein zusätzliches \GLS{json}-Attribut namens \enquote{username}.
+\newline
+
+\begin{apiRoute}{post}{/api/2/auth/register.json}
+ {Registriert einen Nutzer mit einer E-Mail-Adresse und Passwort.
+
+ Versendet E-Mail mit Bestätigungslink an die angegebene E-Mail-Adresse.}
+ \begin{routeRequest}{application/json}
+ \begin{routeRequestBody}
+{
+ "username": "jeff",
+ "email": "jeff@example.com",
+ "password": "MyNameIsJeff"
+}
+ \end{routeRequestBody}
+ \end{routeRequest}
+ \begin{routeResponse}{application/json}
+ \begin{routeResponseItem}{200}
+ {OK: Nutzer wurde erfolgreich angelegt und E-Mail versendet.}
+ \end{routeResponseItem}
+
+ \begin{routeResponseItem}{400}
+ {Bad Request: Fehler beim Parsen oder Eingabe nicht anforderungsgemäß.}
+ \end{routeResponseItem}
+ \end{routeResponse}
+\end{apiRoute}
+
+\subsubsection*{Device API}
+
+Beim Einrichten eines Synchronisations-Servers rufen sowohl AntennaPod als auch Kasts statt einem anfänglichen Login sofort den List-Devices-Endpunkt der \gls{gpodder}.net API auf.
+Dieser Endpunkt wurde entsprechend hinzugefügt.
+Da jedoch explizit keine Unterscheidung von Geräten bei der Synchronisation unterstützt wird, wird dieser intern wie ein Login-Aufruf behandelt.
+\newline
+
+\begin{apiRoute}{get}{/api/2/devices/\{username\}.json}
+ {Gegebenen Nutzer des gegebenen Geräts mithilfe HTTP Basic Auth einloggen oder Gültigkeit des im \enquote{sessionid} \Gls{cookie} gespeicherten JWTs bestätigen.
+
+ Gibt außerdem eine Liste mit einem Dummy-Device zurück, damit die Einrichtung der Synchronisation mit AntennaPod und Kasts möglich ist.}
+ \begin{pathParameter}
+ \pathParamItem{username}{Nutzername des einzuloggenden Nutzers}
+ \end{pathParameter}
+ \begin{routeResponse}{application/json}
+ \begin{routeResponseItem}{200}
+ {OK: Der Benutzer wurde erfolgreich mittles HTTP Basic Auth oder JWT eingeloggt und das \enquote{sessionid} Cookie wurde auf ein gültiges JWT gesetzt.}
+ \newline
+ \begin{routeResponseItemBody}
+[
+ {
+ "id": "dummy",
+ "caption": "device",
+ "type": "other",
+ "subscriptions": 0
+ }
+]
+ \end{routeResponseItemBody}
+ \end{routeResponseItem}
+
+ \begin{routeResponseItem}{401}
+ {Unauthorized: Es liegen falsche Anmeldedaten oder ein ungültiges JWT vor.}
+ \end{routeResponseItem}
+ \end{routeResponse}
+ \begin{jsonKeys}
+ \jsonKeyItem{id}{Geräte-ID}
+ \jsonKeyItem{caption}{Ein für Menschen lesbarer Name für das Gerät}
+ \jsonKeyItem{type}{Typ des Geräts - mögliche Typen: desktop, laptop, mobile, server, other}
+ \jsonKeyItem{subscriptions}{Anzahl der Subscriptions auf dem Gerät}
+ \end{jsonKeys}
+\end{apiRoute}
+
+\newpage
+\subsection{Verifizierung der E-Mail-Adresse}
+
+Dieser Endpunkt wurde zur Verifizierung der bei der Registrierung angegebenen E-Mail-Adresse hinzugefügt.
+Nach der Registrierung wird dem Benutzer eine E-Mail mit der URL dieses Endpunkts (inklusive Benutzernamen und JWT)
+zugesendet. Klickt der Benutzer auf den Link wird die Anfrage im Backend verarbeitet und der Nutzer automatisch
+zum Webfrontend weitergeleitet. Erst nach der Verifizierung der E-Mail-Adresse ist die Registrierung vollständig
+abgeschlossen und der Account aktiviert - nun kann sich der Nutzer anmelden.
+\newline
+
+\begin{apiRoute}{get}{/api/2/auth/\{username\}/verify.json}
+ {Verifiziere die bei der Registrierung angegebene E-Mail-Adresse durch diese, per E-Mail versendete, URL.}
+ \begin{pathParameter}
+ \pathParamItem{username}{Nutzername des betreffenden Nutzers}
+ \end{pathParameter}
+ \begin{urlParameter}
+ \urlParamItem{token}{JSON-Web-Token (24h gültig)}
+ \end{urlParameter}
+ \begin{routeResponse}{application/json}
+ \begin{routeResponseItem}{200}
+ {OK: Der Benutzer wurde erfolgreich aktiviert und kann sich nun anmelden.}
+ \end{routeResponseItem}
+
+ \begin{routeResponseItem}{400}
+ {Bad Request: Der Nutzer mit dem angegebenen Namen ist bereits verifiziert. }
+ \end{routeResponseItem}
+
+ \begin{routeResponseItem}{401}
+ {Unauthorized: Der JWT ist ungültig. }
+ \end{routeResponseItem}
+
+ \begin{routeResponseItem}{404}
+ {Not Found: Es exisitiert kein Nutzer mit dem angegebenen Benutzernamen. }
+ \end{routeResponseItem}
+ \end{routeResponse}
+\end{apiRoute}
+
+
+\newpage
+\subsection{RSSParser}
+
+Das primäre Ziel beim Entwurf des RSSParsers war es den Rest der Anwendung nicht
+aufzuhalten, da das fetchen und parsen länger dauert. Daher soll der RSSParser asynchron
+ausgeführt werden.
+Damit das für die Implementierung verwendete Framework \Gls{spring} dies unterstützt müssen
+mehr Bedingungen erfüllt sein als im Entwurf berücksichtigt wurden, weshalb dieser abgeändert werden musste.
+
+Unter anderem können nur Komponenten die von \Gls{spring} verwaltet werden asynchron ausgeführt werden.
+Weiter können nur öffentliche Methoden von \Gls{spring} als asynchron erkannt werden und bei
+dem Aufruf einer asynchronen Methode muss die Klasse gewechselt werden damit diese asynchron
+ausgeführt wird.
+
+Um diese Bedingungen zu erfüllen ruft der SubscriptionService oder der EpisodeActionService
+die Validate Methode des RSSParsers mit der Subscription die überprüft werden
+soll auf. Dies geschieht asynchron nach dem \enquote{Fire and Forget} Prinzip. Daher können
+die Services unmittelbar weiter arbeiten und dem Nutzer so möglichst schnell eine Antwort
+liefern.
+
+Die Validate Methode fragt den aktuellen \GLS{rss}-Feed der Subscription ab und parsed diesen.
+Erfüllt der Feed die von Apple und Google für \Glspl{podcast} definierten Anforderungen
+werden die Informationen aus dem Feed gespeichert. Dabei werden nur die \Glspl{episode} gespeichert,
+die von mindestens einem Nutzer gehört wurden. Ist der Feed der Subscription nicht
+valide wird die Subscription gelöscht. Um das Löschen und Speichern ausführen zu können
+hält der Parser Referenzen auf das SubscriptionDao und EpisodeDao.
+
+Die im Entwurfsheft definierten Getter werden nicht mehr oder nur
+noch als private Hilfsmethoden benötigt.
+
+\subsection{Reduzierte Datenzugriffsschicht}
+
+Mithilfe von JPA Repositories können Datenbankzugriffe und Abfragen ohne weitere Logik in den DAO-Schnittstellen einfach implementiert werden.
+Wird beispielsweise nach einem \Gls{abo} anhand einer URL gesucht, so wird eine Methode der Form \textit{Optional<Subscription> findByUrl(String url)} in der SubscriptionDao deklariert.
+Um die Implementierung dieser Abfrage kümmert sich JPA.
+
+Damit fallen alle ursprünglich geplanten DAO-Implementierungen weg, was für eine bessere Übersicht in der Datenzugriffsschicht sorgt.
+\newpage
+
+\begin{landscape}
+
+\subsection{Überarbeitetes Klassendiagramm des Backends}
+Das Klassendiagramm zeigt alle den überarbeiteten Entwurf des Backends.
+Weiter zeigt das Diagramm die Aufteilung der Klassen in Pakete sowie schemenhaft dargestellte Verbindungen zu \Gls{db} und Webserver.
+
+% \input{assets/diagrams/classdiagram.latex}
+\includegraphics[width=\linewidth]{assets/diagrams/class_after}
+\end{landscape} \ No newline at end of file