diff options
author | Emmanuel Benoist <emmanuel.benoist@bfh.ch> | 2024-05-06 09:03:02 +0200 |
---|---|---|
committer | Emmanuel Benoist <emmanuel.benoist@bfh.ch> | 2024-05-06 09:04:13 +0200 |
commit | de3e3d5ebdee1d40f6fdc6d03d9072f50ee4081b (patch) | |
tree | f8738fdbbe9003ee84bf2d3b65dd599950c587b0 | |
parent | b8e0dccb6fbe62225cd4b1820321a0785be83f92 (diff) | |
download | lectures-de3e3d5ebdee1d40f6fdc6d03d9072f50ee4081b.tar.gz lectures-de3e3d5ebdee1d40f6fdc6d03d9072f50ee4081b.tar.bz2 lectures-de3e3d5ebdee1d40f6fdc6d03d9072f50ee4081b.zip |
first alpha version of the course chapter security is not finished.
Signed-off-by: Emmanuel Benoist <emmanuel.benoist@bfh.ch>
43 files changed, 4582 insertions, 0 deletions
diff --git a/ngi-rest-api/00-http/00-http-exercises.tex b/ngi-rest-api/00-http/00-http-exercises.tex new file mode 100644 index 0000000..c8be31d --- /dev/null +++ b/ngi-rest-api/00-http/00-http-exercises.tex @@ -0,0 +1,34 @@ +\documentclass{scrartcl} +\author{E. Benoist} +\title{01-HTTP : Exercises} +\usepackage{url} + +\begin{document} +\maketitle + +\section{Install CURL and WGET} + +Install \texttt{wget} and \texttt{curl} in your system. Something like \texttt{sudo apt install wget curl} should do the job. + +Read the manpages of the two softwares to learn how to generate GET and POST requests. + +\section{Send a Request for a page} +Download the page \url{https://www.taler.net} first using wget and then using curl. + + +\section{Fill out a form} +\subsection{GET Method} +We have the page \url{https://www.benoist.ch/GETxxxxxxxx.php}. That page contains a form that is sent to the page \url{https://www.benoist.ch/xxxxxxxx.php}. Use the \emph{Developper Mode} of your browser to study the request that is generated by this form. + +Use wget and curl to send the same values of the form. Send your first name as input. + +\subsection{POST Method} + +We have the page \url{https://www.benoist.ch/POSTxxxxxxxx.php}. That page contains a form that is sent to the page \url{https://www.benoist.ch/POSTxxxxxxxx.php}. Use the \emph{Developper Mode} of your browser to study the request that is generated by this form. + +Use wget and curl to send the same values of the form. Send your first name as input. + +\subsection{Python} +Write a Python script that contacts the server by sending GET and POST requests to the previous URLs. + +\end{document} diff --git a/ngi-rest-api/00-http/00-http.pdf b/ngi-rest-api/00-http/00-http.pdf Binary files differnew file mode 100644 index 0000000..e12f3ec --- /dev/null +++ b/ngi-rest-api/00-http/00-http.pdf diff --git a/ngi-rest-api/00-http/00-http.tex b/ngi-rest-api/00-http/00-http.tex new file mode 100644 index 0000000..893ff6c --- /dev/null +++ b/ngi-rest-api/00-http/00-http.tex @@ -0,0 +1,937 @@ +\documentclass[aspectratio=169,t]{beamer} +\input ../texinputs/taler-macros +% +% Anonymity lecture. Part of the NGI TALER lecture series. +% Copyright (C) 2024 Emmanuel Benoist +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see <http://www.gnu.org/licenses/>. +% + +% *Especially* edit these... +%\setbeameroption{show notes on second screen=right} % Both + +\newcommand{\SPEAKER}{Emmanuel Benoist} +\newcommand{\DATE}{31.05.2024} + + +\newcommand{\TITLE}{NEXT \\ GENERATION \\ INTERNET} +\newcommand{\SUB}{REST API - HyperText Transfer Protocol} +\newcommand{\AUTHOR}{Emmanuel Benoist} +\newcommand{\INST}{Bern University of Applied Sciences} + +% Do not edit this part +\title{\TITLE} +\subtitle{\SUB} +\date{\DATE} +\author[\SPEAKER]{\AUTHOR} +\institute{\INST} + +\usepackage{amsmath} +\usepackage{multimedia} +\usepackage[percent]{overpic} +\usepackage{url} +\usepackage{pifont} +\usepackage[absolute,overlay]{textpos} +\usepackage{listings} + +\lstset{language=PHP} + +\begin{document} + + +\frame{\maketitle +} + + +\begin{frame} +\frametitle{HyperText Transfer Protocol} +\tableofcontents +\end{frame} + +\section{Web} +\begin{frame}{HTTP is the Cornerstone of World Wide Web (I)} + + \begin{block}{HyperText Transfer Protocol} + \end{block} + \begin{block}{Used to download HTML pages} + \end{block} + \begin{block}{Used also to download other types of documents} + \begin{itemize} + \item Cascading style sheets (CSS), + \item JavaScript (JS), + \item Images (JPEG, PNG, GIF, SVG, ...) + \item \dots + \end{itemize} + \end{block} + +\end{frame} + + + +\begin{frame}{HTTP is the Cornerstone of World Wide Web (II)} + + \begin{block}{Used to upload information onto the server} + \begin{itemize} + \item Formulars containing data, + \item files uploaded to the server, + \end{itemize} + \end{block} + +\end{frame} + +\begin{frame}{HTTP for Client Server Communication (I)} + \begin{block}{HTTP is ``sessionless''} + \begin{itemize} + \item connection is broken at the end of the exchange, + \item or after a few exchanges. + \end{itemize} + \end{block} + \begin{block}{Client sends a request} + \begin{itemize} + \item to access some information / to send some information to the server + \item contains information about the client itself (type of + browser, accepted formats or accepted languages), + \item info about the requested document, + \item if information is sent, meta info about this (type and size + for instance). + \end{itemize} + \end{block} + +\end{frame} + +\begin{frame}{HTTP for Client Server Communication (II)} + \begin{block}{Server gives a response} + \begin{itemize} + \item Contains the requested document (HTML / CSS / JS), + \item meta information about the document (type, size, \dots), + \item meta information about the server (date, server, programs + used, \dots). + \end{itemize} + \end{block} + +\end{frame} + +\begin{frame}{Example of an HTTP exchange} + \begin{block}{HTTP Request} + \begin{itemize} + \item Sent by the browser, + \item Open a TCP IP Connection to the port 80 or the server\footnote{Or more + realistically, a secure connection to port 443}, + \item Asks for a resource (a page for instance). + \end{itemize} + \end{block} + \begin{block}{HTTP Response} + \begin{itemize} + \item Gives the document back (the HTML document), + \item Says that it is a html document and its size, + \item Gives some details about the server (which server is used, + which version of PHP has been used for instance). + \end{itemize} + \end{block} + +\end{frame} + +\begin{frame}{Another example} + \begin{block}{HTTP Request} + \begin{itemize} + \item Browser needs an image, + \item The image is already in its cache (locally stored from a + previous request), + \item The browser asks for the image, but only if newer. + \end{itemize} + \end{block} + \begin{block}{HTTP Response} + \begin{itemize} + \item Server answers that the image in cache is still valide. + \end{itemize} + \end{block} + +\end{frame} + + +\section{Headers} +\begin{frame}{Syntax HTTP Request} + \begin{block}{HTTP Request Header} + \begin{itemize} + \item First line (Query string) = Method URI Protocol + \item Header lines = header : value + \item End of header = an empty line + \end{itemize} + \end{block} + \begin{block}{HTTP Request Body} + \begin{itemize} + \item Depending on the method\footnote{details on methods + presented later} can contain information sent to the server + \end{itemize} + \end{block} + +\end{frame} + +\begin{frame}[containsverbatim]{Example : HTTP Request for a page} + +\lstset{basicstyle=\footnotesize} +\begin{lstlisting} +GET /fr/ HTTP/2 +Host: www.taler.net +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0 +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 +Accept-Language: fr-FR,fr-CH;q=0.9,fr;q=0.7,en-US;q=0.6,en;q=0.4,de-DE;q=0.3,de-CH;q=0.1 +Accept-Encoding: gzip, deflate, br +DNT: 1 +Sec-GPC: 1 +Connection: keep-alive +Upgrade-Insecure-Requests: 1 +Sec-Fetch-Dest: document +Sec-Fetch-Mode: navigate +Sec-Fetch-Site: none +Sec-Fetch-User: ?1 +TE: trailers +\end{lstlisting} + +\end{frame} + +\section{Methods (I)} +\begin{frame}{HTTP Methods} + \begin{block}{GET to download resource} + \begin{itemize} + \item Access to a page or + \item Download any resource + \item Form sending small information + \item URL contains URL-encoded parameters + \item HTTP Body remains empty + \item Result can be cached. + \end{itemize} + \end{block} + +\end{frame} + +\section{Methods (II)} +\begin{frame}{HTTP Methods} + \begin{block}{POST to send information } + \begin{itemize} + \item Used by forms to send info to the server (for large information) + \item Data is written in the body of the request + \item Can not be cached. + \end{itemize} + \end{block} + +\end{frame} + + + +\section{Principles} + +\frame[containsverbatim]{ +\frametitle{HTTP} + +\begin{block}{Request} + +\begin{itemize} +\item Request for a page (giving its URL) +\item for an image or any file +\item contains the input of a form +\item contains some settings of the browser +\end{itemize} +\end{block} + +\begin{block}{Response} + +\begin{itemize} +\item The file (html or any file) +\item Contains properties of the document +\item Can lead to another URL +\end{itemize} +\end{block} + +} + +\section{Request} +\frame[containsverbatim]{ +\frametitle{Request} + +\begin{block}{Syntax} +\lstset{basicstyle=\footnotesize} +\begin{lstlisting} +METHODE URI PROTOCOL +HEADER1: VALUE +... +HEADERn: VALUE + +BODY OF THE MESSAGE +\end{lstlisting} +\end{block} + +\begin{block}{Example} +Very minimalistic : the only header that is obligatory is host name. +\lstset{basicstyle=\footnotesize} +\begin{lstlisting} +GET / HTTP/1.1 +host: www.taler.net +\end{lstlisting} +\end{block} + +} +\frame[containsverbatim]{ +\frametitle{Request} + + +\begin{block}{A not so simple example} +\footnotesize +\begin{verbatim} +GET / HTTP/2 +Host: www.taler.net +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:124.0) Gecko/20100101 Firefox/124.0 +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 +Accept-Language: fr-FR,fr-CH;q=0.9,fr;q=0.7,en-US;q=0.6,en;q=0.4,de-DE;q=0.3,de-CH;q=0.1 +Accept-Encoding: gzip, deflate, br +DNT: 1 +Sec-GPC: 1 +Connection: keep-alive +Upgrade-Insecure-Requests: 1 +Sec-Fetch-Dest: document +Sec-Fetch-Mode: navigate +Sec-Fetch-Site: none +Sec-Fetch-User: ?1 +TE: trailers +\end{verbatim} +\end{block} +} +\subsection{Request Headers} +\frame[containsverbatim]{ +\frametitle{Request Headers (I)} + +\begin{block}{Description of the client} + +\begin{itemize} +\item \texttt{User-Agent:} browser and OS description +\item \texttt{Accept:} which documents mime-types are accepted +\note[item] \texttt{Accept:} The line contains numbers corresponding +to the preference. The higher the number is the preferred the mime-type is. +\item \texttt{Accept-Language} idem for the languages +\note[item] \texttt{Accept-Language}: the server can send the page in the desired language +\item \texttt{Accept-Encoding} which encoding can be used +content +\note[item] \texttt{Accept-Encoding} can be compressed to save bandwidth +\item \texttt{\dots} +\end{itemize} +\end{block} + + +} + +\frame[containsverbatim]{ +\frametitle{Request Headers (II)} + +\begin{block}{Description of the request} +\begin{itemize} +\item \texttt{Host} usefull for virtual servers +\item \texttt{Proxy-Connection: keep-alive} Allows more than one + request in one connexion +\item \texttt{Keep-Alive: 300} set the time-out +\item \texttt{Referer:} Which page contains the link that created the + request +\note[item] \texttt{Referer:} can be a page that referes to another +page, or a page that contains different resources (in this case each +request for a resource contains the page as a ``referer''). +\end{itemize} +\end{block} +} +\subsection{GET requests} +\frame[containsverbatim]{ +\frametitle{Send information to the server} + +\textbf{Forms in HTML} + +Example: +\begin{verbatim} +<form method="POST" action="http://localhost/test.php"> +<input type="text" name="text1"> +<input type="hidden" name="text2" value="80"> +<input type="submit" value="OK"> +</form> + +<form method="GET" action="http://localhost/test.php"> +<input type="text" name="text1"> +<input type="hidden" name="text2" value="80"> +<input type="submit" value="OK"> +</form> +\end{verbatim} + +} +\frame[containsverbatim]{ +\frametitle{Method for forms: GET} + +\begin{block}{Method = GET} +\begin{itemize} +\item For GETTING a page +\item Used for URL typed in the address bar +\item Used for links +\item Can send a small set of information +\item The information MUST not reach the server +\item It can be cached +\end{itemize} +\end{block} +} +\frame[containsverbatim]{ +\frametitle{Method for forms: POST} + +\begin{block}{Method = POST} +\begin{itemize} +\item For POSTING information to the server +\item Can contain large data +\item Must arrive to the server +\item Can not be cached +\end{itemize} +\end{block} + +} +\frame[containsverbatim]{ +\frametitle{The GET Method} +\begin{block}{The GET request} + +\begin{itemize} +\item The following is a GET request +\item There is no content, +\item The values are sent in the URL (they are URLEncoded) +\end{itemize} +\end{block} +\lstset{basicstyle=\footnotesize} +\begin{lstlisting} +GET /tmp/example-forms.html?text1=Hello+Taler&text2=80 HTTP/3 +Host: www.taler.net +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:124.0) Gecko/20100101 Firefox/124.0 +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 +Accept-Language: fr-FR,fr-CH;q=0.9,fr;q=0.7,en-US;q=0.6,en;q=0.4,de-DE;q=0.3,de-CH;q=0.1 +Accept-Encoding: gzip, deflate, br +Referer: https://www.taler.net/tmp/example-forms.html +... +\end{lstlisting} +\note{The import in this slide is the Query String where values are + encoded : + + \begin{itemize} + \item Text1 = Hello Taler + \item Text2 = 80 (was a hidden value in the form) + \end{itemize} +} + +} +\frame[containsverbatim]{ +\frametitle{URL encoding (I)} + +\begin{block}{Coding} + +A URL can only contain alphanumerical characters plus the following +ones : +\begin{itemize} +\item \verb,?, marks the end of the resource and the start of + parameters +\item \verb,=, to separate a parameter name and its value +\item \verb,&, to separate parameters +\item \verb,+, to represent spaces +\end{itemize} +\end{block} +\begin{block}{Automatically encoded in the FORM} + + +\begin{itemize} +\item Couple : (variable, value). + +\end{itemize} +\end{block} +} + +\frame[containsverbatim]{ +\frametitle{URL encoding (II)} +\footnotesize +\begin{block}{Links in a page} + +\begin{itemize} +\item A link in a page executes a \texttt{GET} method +\item You can set values for links too. You can insert any parameter + in the URL: $<$a href="example.php?name=toto"$>$ +\end{itemize} +\end{block} + +\begin{block}{Any GET URL} + \begin{itemize} + \item Any GET request may contain some parameters + \item Generated from a form + \item Implemented statically inside the document + \item Generated in JavaScript inside the DOM + \item Generated by any program. + \end{itemize} +\end{block} +} + +\subsection{The POST Request} +\frame[containsverbatim]{ +\frametitle{The POST request} + + +\begin{block}{The following is the request generated by Firefox on a + GNU-Linux Platform.} +\end{block} +\begin{block}{The content type is ``\texttt{urlencoded}''} +\end{block} +\begin{block}{The values are sent in the body of the request} +\end{block} +\begin{block}{There is a description of the \texttt{content} (\texttt{Content-type:}, \texttt{Content-length:})} +\end{block} + +} +\frame[containsverbatim]{ +\frametitle{The POST request} +\lstset{basicstyle=\small} +\begin{lstlisting} +POST /tmp/example-forms.html HTTP/3 +Host: www.taler.net +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:124.0) Gecko/20100101 Firefox/124.0 +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 +Accept-Language: fr-FR,fr-CH;q=0.9,fr;q=0.7,en-US;q=0.6,en;q=0.4,de-DE;q=0.3,de-CH;q=0.1 +Accept-Encoding: gzip, deflate, br +Referer: https://www.taler.net/tmp/example-forms.html +Content-Type: application/x-www-form-urlencoded +Content-Length: 26 +Origin: https://www.taler.net +DNT: 1 +Sec-GPC: 1 +Connection: keep-alive +... + +text1=Hello+Taler&text2=80 +\end{lstlisting} + + + +} +\section{Response} +\frame[containsverbatim]{ +\frametitle{Response} + + +\begin{block}{From the server to the client} + \begin{itemize} + \item Is a response for the question contained in the + \texttt{request} + \end{itemize} +\end{block} +\begin{block}{Contains a status} + + \begin{itemize} + \item Document OK, moved permanently, does not exist (404), the + version in cache is still ok, ... + \end{itemize} +\end{block} +\begin{block}{And the desired document or information} + + \begin{itemize} + \item The body contains the document (html, gif, + jpeg,...) + + + \item The header contains meta information (date of production, + validity, language, ...) + \end{itemize} +\end{block} + +} + + + +\frame[containsverbatim]{ +\frametitle{Response, Example} +\lstset{basicstyle=\footnotesize} +\begin{lstlisting} +HTTP/2 200 +server: nginx +date: Wed, 17 Apr 2024 05:27:59 GMT +content-type: text/html +last-modified: Mon, 15 Apr 2024 20:18:46 GMT +vary: Accept-Encoding +etag: W/"661d8ba6-3e21" +... +content-encoding: gzip +X-Firefox-Spdy: h2 + +<!DOCTYPE html> +<html lang="fr"> + <head> + <title>GNU Taler</title> +... +\end{lstlisting} +\note[item]{The header is finished with two End of Lines markers, +which is seen as an ``empty line''. } + +} +\frame[containsverbatim]{ +\frametitle{Response (Syntax)} + +\begin{block}{Syntax} + +\begin{verbatim} +STATUS-LINE +HEADER1: value +HEADER2: value +HEADER3: value + +BODY OF THE DOCUMENT +\end{verbatim} +\note{Repeat the same a second time : The header is finished with two End of Lines markers, +which is seen as an ``empty line''. } +\end{block} +} +\subsection{Status} +\frame[containsverbatim]{ + +\frametitle{Status Line} +\begin{block}{Format} + +\begin{verbatim} +Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF +\end{verbatim} +\end{block} +\begin{block}{Status-Code:} + +The Status-Code element is a 3-digit integer +result code of the attempt to understand and satisfy the request. +\end{block} +\begin{block}{Reason-Phrase} + +The Reason-Phrase is intended to give a short textual description of +the Status-Code. The Status-Code is intended for use by automata and +the Reason-Phrase is intended for the human user. +\end{block} +\begin{block}{Examples} +\begin{verbatim} +HTTP/1.1 200 OK +HTTP/1.1 404 Not Found +HTTP/1.1 501 Method Not Implemented +\end{verbatim} +\end{block} + +} +\frame[containsverbatim]{ +\frametitle{Status Code} + +\begin{block}{1xx: Informational - Request received, continuing process} +\end{block} +\begin{block}{2xx: Success - The action was successfully received, + understood, and accepted} +\end{block} +\begin{block}{3xx: Redirection - Further action must be taken in order to + complete the request} +\end{block} +\begin{block}{4xx: Client Error - The request contains bad syntax or + cannot be fulfilled} +\end{block} +\begin{block}{5xx: Server Error - The server failed to fulfill an + apparently valid request} +\end{block} + +} +\frame[containsverbatim]{ +\frametitle{Status Code (Cont.)} + +\begin{block}{Informational} +\begin{verbatim} + "100" : Continue + "101" : Switching Protocols +\end{verbatim} +\end{block} + +\begin{block}{Success} +\begin{verbatim} + "200" : OK + "201" : Created + "202" : Accepted + "203" : Non-Authoritative Information + "204" : No Content + "205" : Reset Content + "206" : Partial Content +\end{verbatim} +\end{block} +} +\frame[containsverbatim]{ +\frametitle{Status Code (Cont.)} + +\begin{block}{Redirection} +\begin{verbatim} + "300" : Multiple Choices + "301" : Moved Permanently + "302" : Found + "303" : See Other + "304" : Not Modified + "305" : Use Proxy + "307" : Temporary Redirect +\end{verbatim} +\end{block} +} +\frame[containsverbatim]{ +\frametitle{Status Code (Cont.)} +\footnotesize +\begin{block}{Client Error} +\begin{verbatim} + "400" : Bad Request + "401" : Unauthorized + "402" : Payment Required + "403" : Forbidden + "404" : Not Found + "405" : Method Not Allowed + "406" : Not Acceptable + "407" : Proxy Authentication Required + "408" : Request Time-out + "409" : Conflict + "410" : Gone + "411" : Length Required + "412" : Precondition Failed + "413" : Request Entity Too Large + "414" : Request-URI Too Large + "415" : Unsupported Media Type + "416" : Requested range not satisfiable + "417" : Expectation Failed +\end{verbatim} +\end{block} +} +\frame[containsverbatim]{ +\frametitle{Status Code (Cont.)} + +\begin{block}{Server Error} +\begin{verbatim} + "500" : Internal Server Erro + "501" : Not Implemented + "502" : Bad Gateway + "503" : Service Unavailable + "504" : Gateway Time-out + "505" : HTTP Version not supported +\end{verbatim} +\end{block} + +} +\subsection{Typical Responses} +\frame[containsverbatim]{ + +\frametitle{Typical Responses} +\small +\begin{block}{Request to the site \url{www.taler.net}} + +\begin{verbatim} +GET /en/ HTTP/2 +Host: www.taler.net +\end{verbatim} +\end{block} +\begin{block}{Status \texttt{200 OK}} +\lstset{basicstyle=\tiny} + +\begin{lstlisting} +HTTP/2 200 +server: nginx +date: Wed, 17 Apr 2024 05:33:08 GMT +content-type: text/html +last-modified: Mon, 15 Apr 2024 20:18:46 GMT +vary: Accept-Encoding +etag: W/"661d8ba6-3d01" +strict-transport-security: max-age=63072000; includeSubDomains; preload +x-xss-protection: 1; mode=block +x-frame-options: SAMEORIGIN +x-content-type-options: nosniff +content-security-policy: default-src 'self' https://www.taler.net/dist/; img-src 'self' https://unpkg.com/ https://secure.gravatar.com/ https://git.taler.net/ data: blob:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.taler.net/dist/js/; style-src 'self' 'unsafe-inline' https://www.taler.net/dist/css/; connect-src 'self' wss://buildbot.taler.net; object-src 'self' blob:; font-src 'self' data: +referrer-policy: same-origin +content-encoding: gzip +X-Firefox-Spdy: h2 + +<!DOCTYPE html> +<html lang="fr"> + <head> + <meta charset="UTF-8"/> + <title>GNU Taler</title> + <link rel="shortcut icon" href="/favicon.ico"> +\end{lstlisting} +\end{block} +\note{ Present the Status line (200 means OK) and the most +significant headers : server, content-type, + +Do not present all headers +} + + + +} +\frame[containsverbatim]{ + +\frametitle{Typical Responses (Cont.)} +\footnotesize +\begin{block}{Request for a directory as if it were a ressource} + +\begin{verbatim} +GET /I HTTP/1.1 +Host: www.hta-bi.bfh.ch +\end{verbatim} +\end{block} +\begin{block}{Status \texttt{301 Moved Permanently}} + +\begin{verbatim} +HTTP/1.1 301 Moved Permanently +Date: Thu, 29 Jan 2004 15:44:11 GMT +Server: Apache/1.3.22 (Unix) PHP/4.0.6 +Location: http://www.hta-bi.bfh.ch/I/ +Transfer-Encoding: chunked +Content-Type: text/html; charset=iso-8859-1 + +131 +<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> +<HTML><HEAD> +... +</BODY></HTML> + +0 +\end{verbatim} +\end{block} + +} + +\begin{frame}[containsverbatim] +\frametitle{Caching} + +\begin{block}{Content of a response to a GET request can be cached (and should be)} + +\begin{itemize} +\item +The document is based on ``information'' that has a versioning. + +\item This +information can be cached to save bandwidth and time. + +\item Cache can be +local (inside the browser) but also inside reverse proxies or +Content Delivery Networks (CDNs). + +\end{itemize} +\end{block} +\begin{block}{The response contains following headers concerning caching :} + +\begin{itemize} +\item \verb,etag, : version number for the ``information'' +\item \verb,last-modified, : the date of last modification of the ``information'' +\item \verb,vary, : shows the parameters for which the cached response will + not be valid any more. + +For instance \verb,vary : accept, means that if \verb,accept, changes from + \verb,text/html, to \verb,text/csv, the page in cache is not valid anymore. +\end{itemize} +\end{block} + +\end{frame} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\frame[containsverbatim]{ + +\frametitle{Request for a cached page} + +\begin{verbatim} +GET http://cms.hta-bi.bfh.ch/typo3/md5.js HTTP/1.1 +Host: cms.hta-bi.bfh.ch +User-Agent: Mozilla/5.0 (X11; U; SunOS sun4u; en-US; rv:1.0.1) Gecko/20020920 Netscape/7.0 +Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1 +Accept-Language: fr, fr-ch;q=0.83, en;q=0.66, en-us;q=0.50, de;q=0.33, de-ch;q=0.16 +Accept-Encoding: gzip, deflate, compress;q=0.9 +Accept-Charset: ISO-8859-1, utf-8;q=0.66, *;q=0.66 +Keep-Alive: 300 +Proxy-Connection: keep-alive +Referer: http://cms.hta-bi.bfh.ch/typo3/index.php +Cookie: be_typo_user=b3636a5431b8bc82c8ab5213223d0b1f; fe_typo_user=3ca5a346fa +If-Modified-Since: Thu, 27 Jun 2002 12:45:08 GMT +If-None-Match: "1ab6f3-2709-3d1b08d4" +\end{verbatim} + + +} +\frame[containsverbatim]{ + +\frametitle{Response : Cache is still valid} + + + +\begin{block}{Status \texttt{304 Not Modified}} + +\begin{verbatim} +HTTP/1.1 304 Not Modified +Date: Thu, 29 Jan 2004 15:53:31 GMT +Server: Apache +ETag: "1ab6f3-2709-3d1b08d4" + +\end{verbatim} + +(The response has no body, since the content is in cache) +\end{block} +} + + +\begin{frame}{Conclusion} + +\begin{block}{HTTP is a Request Response protocol} + + \begin{itemize} + \item A request is sent by the client, + \item A response is generated by the server. + \end{itemize} + \end{block} + \begin{block}{HTTP is sessionless} + + \begin{itemize} + \item Unlike SSH or SFTP for instance + \end{itemize} + \end{block} + \begin{block}{HTTP GET requests can be cached} + + \begin{itemize} + \item To save time and money, the same GET request should return the + same value. + \end{itemize} +\end{block} +\begin{block}{These features will be used to build a Computer to Computer + communication architecture : REST API's} +\end{block} +\end{frame} + + +% This should be last... +\begin{frame}{Acknowledgements} + + \begin{minipage}{0.45\textwidth} \ \\ + {\tiny Funded by the European Union (Project 101135475).} + + \begin{center} + \includegraphics[width=0.5\textwidth]{../texinputs/images/bandera.jpg} + \end{center} + \end{minipage} + \hfill + \begin{minipage}{0.45\textwidth} + {\tiny Funded by SERI (HEU-Projekt 101135475-TALER).} + + \begin{center} + \includegraphics[width=0.65\textwidth]{../texinputs/images/sbfi.jpg} + \end{center} + \end{minipage} + + \vfill + + {\tiny Views and opinions expressed are however those of the author(s) only + and do not necessarily reflect those of the European Union. Neither the + European Union nor the granting authority can be held responsible for + them.} +\end{frame} + + +\end{document} diff --git a/ngi-rest-api/00-http/example-forms.html b/ngi-rest-api/00-http/example-forms.html new file mode 100644 index 0000000..416160b --- /dev/null +++ b/ngi-rest-api/00-http/example-forms.html @@ -0,0 +1,27 @@ +<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> +<html> <head> +<title></title> +</head> + +<body> +<h1>Examples for formulars in HTTP</h1> + +<h2>GET form</h2> +<form method="GET" > +<input type="text" name="text1"> +<input type="hidden" name="text2" value="80"> +<input type="submit" value="OK"> +</form> + + +<h2>POST form</h2> +<form method="POST" > +<input type="text" name="text1"> +<input type="hidden" name="text2" value="80"> +<input type="submit" value="OK"> +</form> + +<hr> +<address></address> +<!-- hhmts start -->Last modified: Tue Apr 16 17:16:46 CEST 2024 <!-- hhmts end --> +</body> </html> diff --git a/ngi-rest-api/01-introduction/01-introduction-exercise.tex b/ngi-rest-api/01-introduction/01-introduction-exercise.tex new file mode 100644 index 0000000..221fdf4 --- /dev/null +++ b/ngi-rest-api/01-introduction/01-introduction-exercise.tex @@ -0,0 +1,24 @@ +\begin{frame}[containsverbatim] +\frametitle{Exercise} + +\begin{itemize} +\item \textbf{Write a JSON structure for representing the following + list of vital signs:} +\begin{center} +\begin{tabular}{llr} +\hline +Date&Sign&Value\\ +\hline +3/03/2020&temperature&37.0\\ +4/03/2020&temperature&39.0\\ +4/03/2020&pulse&104\\ +5/03/2020&BP&159/107\\ +\hline +\end{tabular} +\end{center} +\vspace{1cm} +\item \textbf{Insert this list into the data of Johny Smith with the + key \texttt{vital\_signs}.} +\end{itemize} + +\end{frame} diff --git a/ngi-rest-api/01-introduction/01-introduction.pdf b/ngi-rest-api/01-introduction/01-introduction.pdf Binary files differnew file mode 100644 index 0000000..0761e66 --- /dev/null +++ b/ngi-rest-api/01-introduction/01-introduction.pdf diff --git a/ngi-rest-api/01-introduction/01-introduction.tex b/ngi-rest-api/01-introduction/01-introduction.tex new file mode 100644 index 0000000..5261d47 --- /dev/null +++ b/ngi-rest-api/01-introduction/01-introduction.tex @@ -0,0 +1,1265 @@ +\documentclass[aspectratio=169,t]{beamer} +\input ../texinputs/taler-macros + + + +% +% Anonymity lecture. Part of the NGI TALER lecture series. +% Copyright (C) 2024 Emmanuel Benoist +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see <http://www.gnu.org/licenses/>. +% + +% *Especially* edit these... +% \setbeameroption{show notes on second screen=right} % Both + +\newcommand{\SPEAKER}{Emmanuel Benoist} +\newcommand{\DATE}{31.05.2024} + + +\newcommand{\TITLE}{NEXT \\ GENERATION \\ INTERNET} +\newcommand{\SUB}{REST API - Introduction} +\newcommand{\AUTHOR}{Emmanuel Benoist} +\newcommand{\INST}{Bern University of Applied Sciences} + +% Do not edit this part +\title{\TITLE} +\subtitle{\SUB} +\date{\DATE} +\author[\SPEAKER]{\AUTHOR} +\institute{\INST} + +\usepackage{amsmath} +\usepackage{multimedia} +\usepackage[percent]{overpic} +\usepackage{url} +\usepackage{pifont} +\usepackage[absolute,overlay]{textpos} +\usepackage{listings} +\lstdefinelanguage{json}{ + basicstyle=\normalfont\ttfamily, + commentstyle=\color{red}, % style of comment + stringstyle=\color{blue}, % style of strings + %numbers=left, + %numberstyle=\scriptsize, + stepnumber=1, + numbersep=8pt, + showstringspaces=false, + breaklines=true, + %frame=lines, + %backgroundcolor=\color{gray}, %only if you like + string=[s]{"}{"}, + comment=[l]{:\ "}, + morecomment=[l]{:"}, + literate= + *{0}{{{\color{blue}0}}}{1} + {1}{{{\color{blue}1}}}{1} + {2}{{{\color{blue}2}}}{1} + {3}{{{\color{blue}3}}}{1} + {4}{{{\color{blue}4}}}{1} + {5}{{{\color{blue}5}}}{1} + {6}{{{\color{blue}6}}}{1} + {7}{{{\color{blue}7}}}{1} + {8}{{{\color{blue}8}}}{1} + {9}{{{\color{blue}9}}}{1} +} + +\lstset{language=PHP} + +\begin{document} + +\frame{\maketitle +} + +\frame{ +\frametitle{Introduction} +\tableofcontents + +} + + +\section{Web Architecture} +\begin{frame}{Classical Web Architecture} +\begin{center} +\includegraphics[width=0.7\textwidth]{images/web-standard-architecture.pdf} + +\vfill + +\textbf{Web pages rendered on the server} + + \vfill + +\textbf{A lot of existing frameworks} + +\end{center} +\note{ +\textbf{Web pages rendered on the server :} +\begin{itemize} +\item{Browser download one HTML page} \item{It contains + links and/or forms} +\item{User clicks or sends a form} + \item{Request is sent to the server} \item{Another web + page is generated} +\end{itemize} +\textbf{Frameworks} +\begin{itemize} + \item{PHP / Laravel} + \item{Java / Java Server Faces or Sturts} + \item{C\# / .NET} + \item{JavaScript / Node.JS \dots} + \end{itemize} + } + + +\end{frame} + +\begin{frame}{One Page Application (I)} +\begin{center} +\includegraphics[width=0.6\textwidth]{images/single-page-application.pdf} + +\vfill + +\textbf{One page application } + +\vfill + +\textbf{Runs inside the client application (browser) and communicate + with an API.} +\end{center} + +\note{ +\textbf{One page application } + \begin{itemize} + \item Browser downloads 1 page containing JavaScript + \item JavaScript downloads Data + \item JavaScript renders Data inside the Document Object Model + (DOM) + \item JavaScript modifies and resends the data to the server + \end{itemize} +\textbf{On the client} + \begin{itemize} + \item Plain JavaScript + \item Vue.JS + \item Angular + \item React \dots + \end{itemize} +} + + +\end{frame} + +\begin{frame}{One Page Application (II)} +\begin{center} +\includegraphics[width=0.7\textwidth]{images/single-page-application.pdf} +\end{center} + +\vfill + +\textbf{On the server} + \begin{itemize} + \item No HTML rendering + \item No need for a state (stored inside the browser) + \item Just a minimal interface to data + \end{itemize} +\end{frame} + +\begin{frame}{REST API} +\begin{center} +\includegraphics[width=0.5\textwidth]{images/multiple-clients.pdf} +\end{center} +\vfill + +\textbf{Why not use the same interface for other means ?} + +\vfill + + + \textbf{RESTful Application Programming Interface} + + +\note{ +\textbf{Why not use the same interface for other means ?} + \begin{itemize} + \item Mobile App ? + \item Server to Server communication ? + \end{itemize} + \textbf{RESTful Application Programming Interface} + \begin{itemize} + \item Data are available + \item Interface is open + \item Interface is stateless + \end{itemize} + +} + +\end{frame} +\section{The REST architecture} + +\begin{frame}{REST : REpresentational State Transfer (I)} + + \begin{block}{software architectural style} + \begin{itemize} + \item REST defines a set of constraints for how the architecture + of a distributed system should work. + \end{itemize} + \end{block} + \begin{block}{Developed by Roy Fielding} + \begin{itemize} + \item For his PhD Thesis : \emph{Architectural Styles and the + Design of Network-based Software + Architectures}\cite{fielding2000} TODO ADD CITATION + \end{itemize} + \end{block} +\end{frame} + +\begin{frame}{REST : REpresentational State Transfer (II)} + +\begin{block}{Goals :} + +\emph{``Throughout the HTTP standardization process, I was called on to defend the design choices of the Web. That is an extremely difficult thing to do within a process that accepts proposals from anyone on a topic that was rapidly becoming the center of an entire industry. I had comments from well over 500 developers, many of whom were distinguished engineers with decades of experience, and I had to explain everything from the most abstract notions of Web interaction to the finest details of HTTP syntax. That process honed my model down to a core set of principles, properties, and constraints that are now called REST.''} + +\hfill Roy Fielding +\end{block} +\end{frame} + + +\begin{frame}{From Web Services to RESTful services (I)} + \begin{block}{Web Services} + \begin{itemize} + \item At the beginning : Ad hoc protocols for each service + + \begin{itemize} + \item parsing necessary for each of them + \end{itemize} + \item First standards : Web Services using SOAP use HTTP as underlying protocol + + \begin{itemize} + \item SOAP works with XML + + \item Parsing is done by an XML parser + \end{itemize} + \end{itemize} + \end{block} +\end{frame} + + +\begin{frame}{From Web Services to RESTful services (II)} + \begin{block}{RESTful services} + \begin{itemize} + \item Enable interoperability of heterogenous servers, + \item Lightweight integration using JSON and HTTP, + \end{itemize} + \end{block} + \begin{block}{Main Ideas} + \begin{itemize} + \item Use URIs (Uniform Resource Identifyer) to name resources + \item Access resources using HTTP + \item Data are represented in JavaScript Object Notation (JSON) + \end{itemize} + \end{block} +\end{frame} + + +\begin{frame}[containsverbatim] +\frametitle{REST Principles (I)} + +\begin{block}{Uniform Interface} + \begin{itemize} + \item All requests for one resource are the same, + \item independant from the origin of the request, + \item app, single page application, server, \dots + \end{itemize} +\end{block} +\begin{block}{Client-server decoupling.} + \begin{itemize} + \item Application on the server does know nothing about the client. + \end{itemize} +\end{block} + +\end{frame} + +\begin{frame}[containsverbatim] +\frametitle{REST Principles (II)} +\begin{block}{State-less} + \begin{itemize} + \item Any request is self-contained. Does not need to refere to a + previous interaction. + \item It contains everything needed to treat the request + \end{itemize} +\end{block} + +\begin{block}{Caching} + \begin{itemize} + \item Caching must be possible, + \item Response contains information about caching (if possible, how + long, what, \dots) + \end{itemize} +\end{block} + +\end{frame} + +\begin{frame}[containsverbatim] +\frametitle{REST Principles (III)} + +\begin{block}{Layered architecture} + \begin{itemize} + \item In REST APIs, calls and responses pass through different + layers. + \item Don't assume that client and server applications connect directly to each other. + \end{itemize} +\end{block} +\begin{block}{On demand code (optional)} + \begin{itemize} + \item REST APIs send normally statical resources, + \item They can also send executable code (JavaScript for instance). + \end{itemize} +\end{block} + +\end{frame} +\begin{frame} + \frametitle{Anatomy of a RESTful API (I)} + \begin{block}{Resource-Based Architecture} +\begin{itemize} +\item RESTful APIs are centered around resources, which represent entities or data objects. +\item Resources are identified by unique URIs (Uniform Resource Identifiers) and can be accessed via standard HTTP methods. +\item Each resource can have multiple representations (e.g., JSON, XML) and can be manipulated using CRUD operations (Create, Read, Update, Delete). +\end{itemize} +\end{block} +\end{frame} + +\begin{frame}{Anatomy of a RESTful API (II)} +\begin{block}{HTTP Methods} +\begin{itemize} +\item HTTP methods (also known as verbs) define the actions that can be performed on resources in a RESTful API. +\item The most commonly used HTTP methods in RESTful APIs are: +\begin{itemize} +\item GET: Retrieve a resource or collection of resources. +\item POST: Create a new resource. +\item PUT: Update an existing resource. +\item PATCH : Partially update an existing resource. +\item DELETE: Delete a resource. +\end{itemize} +\item Additional methods such as HEAD, and OPTIONS may also be used for specific purposes. +\end{itemize} +\end{block} +\end{frame} + +\begin{frame}{Anatomy of a RESTful API (III)} +\begin{block}{Uniform Interface} +\begin{itemize} +\item A key principle of RESTful architecture is the uniform interface, which promotes simplicity, consistency, and scalability. +\item The uniform interface is achieved through standardization of resource URIs, HTTP methods, and representations (e.g., JSON, XML). +\item This standardization allows clients and servers to communicate effectively without the need for custom interfaces or protocols. +\end{itemize} +\end{block} +\end{frame} + +\begin{frame}{Anatomy of a RESTful API (IV)} +\begin{block}{Stateless Communication} +\begin{itemize} +\item RESTful APIs are stateless, meaning that each request from the client to the server must contain all the information necessary to understand and process the request. +\item The server does not store any client state between requests, which improves scalability, reliability, and performance. +\item Stateless communication allows RESTful APIs to be highly cacheable and resilient to failures and network interruptions. +\end{itemize} +\end{block} +\end{frame} + +\begin{frame}{Anatomy of a RESTful API (V)} +\begin{block}{Layered System} +\begin{itemize} +\item RESTful APIs are designed as layered systems, allowing intermediaries such as proxies, gateways, and caches to be inserted between clients and servers. +\item Intermediaries can improve scalability, reliability, security, and performance by handling requests and responses at different layers of the architecture. +\item The layered system architecture enables RESTful APIs to be flexible, extensible, and adaptable to changing requirements and environments. +\end{itemize} +\end{block} +\end{frame} + + +\section{JSON} +\begin{frame}[containsverbatim] +\frametitle{JavaScript Object Notation - JSON} + +\begin{block}{Designed to generate JavaScript objects and lists} + \begin{itemize} + \item Lists : sequences of elements + \item Objects : mappings key - value + \end{itemize} +\end{block} +\begin{block}{Transfer format} + \begin{itemize} + \item Between an App and a server + \item Between a Web Client side application (JavaScript in the browser) and a + server + \item Between two servers + \end{itemize} +\end{block} + +\end{frame} + +\begin{frame}[containsverbatim] +\frametitle{JSON syntax (I)} + + +\begin{block}{Strings are enclosed in double quotes} + \begin{itemize} + \item \texttt{"Hello world"} + \end{itemize} +\end{block} +\begin{block}{Lists are represented with square brackets} + \begin{itemize} + \item \texttt{["A","B'',"C","D"]} + \end{itemize} +\end{block} +\begin{block}{Objects are represented with curly brackets } + \begin{itemize} + \item \texttt{\{\}} + \end{itemize} +\end{block} + +\end{frame} + +\begin{frame}[containsverbatim] +\frametitle{JSON syntax (II)} + + + +\begin{block}{Objects contain \texttt{key : value} pairs} + \begin{itemize} + \item \texttt{\{"color":"red", "taste": "sweet", "name": "orange"\}} + \end{itemize} +\end{block} +\begin{block}{Objects and lists can be mixed} +\end{block} + +\end{frame} + +\begin{frame}[containsverbatim] +\frametitle{Example1 JSON \footnote{Source : \url{https://bitcoin.ice.bfh.ch/keys}}} +\note{An object has different properties. + +Some properties can also be +objects or arrays. + +One can generate a tree corresponding to a complex structure. +} +\lstset{language=json} +\begin{lstlisting} +{ + "version": "14:0:2", + "base_url": "https://bitcoin.ice.bfh.ch/", + "currency": "BITCOINBTC", + "master_public_key": "YCWD4QXP607YDZ47N...MTTMTAANZ6C7W00", + "reserve_closing_delay": { + "d_us": 2419200000000 + } +} +\end{lstlisting} + +\end{frame} + + + +\begin{frame}[containsverbatim] +\frametitle{Example 2 JSON \footnote{Source : \url{https://bitcoin.ice.bfh.ch/keys}}} + +\lstset{language=json} +\lstset{basicstyle=\tiny} +\begin{lstlisting} +[ + { + "stamp_expire": { + "t_s": 1732808492 + }, + "stamp_end": { + "t_s": 1795880492 + }, + "master_sig": "71W0GGF543A9...6ECTCWEXCXY3JGP10", + "key": "CN8SGF6Z4D2M549DNNM...5HYAY7ZP9Z1SP0QFT5JCNK0" + }, + { + "stamp_expire": { + "t_s": 1718293892 + }, + "stamp_end": { + "t_s": 1781365892 + }, + "master_sig": "1T8XFH64HC2SK2...VDQCDN9D9MBVJ00", + "key": "397M3FFX9F41P4TY...01WY804QXPW9W3VV6BB6G" + } + ] +}\end{lstlisting} +\note[item]{List of keys (with timestamp for their limits)} + +\note[item]{A list contains elements, it starts with a [ and terminates with +], + +elements are separated by \texttt{,}} + +\end{frame} + + + + + + + + +% \begin{frame}[containsverbatim] +% \frametitle{JavaScript} + +% \begin{itemize} +% \item \textbf{Node.js} +% \begin{itemize} +% \item Is a framework working server side +% \item Code is executed inside the server +% \item Prepares data to be send to the client +% \end{itemize} +% \item \textbf{Programming is done in JavaScript} +% \begin{itemize} +% \item JavaScript is executed Server-side, inside the server +% \end{itemize} +% \item \textbf{Node Red} +% \begin{itemize} +% \item A visual framework for programming a Node.js server +% \item Instructions are represented with nodes +% \item Nodes can be programmed and configured in JavaScript +% \item The nodes are executed inside the SERVER +% \end{itemize} +% \end{itemize} + +% \end{frame} + + +% \section{Basic JavaScript syntax} +% \begin{frame}[containsverbatim] +% \frametitle{Parsing and Serialization of JSON objects} + +% \begin{itemize} +% \item \textbf{Parse a JSON string into a JS-Object} +% \begin{itemize} +% \item \texttt{JSON.parse()} +% \end{itemize} +% \begin{lstlisting} +% str = "{'val':'12', 'foo': 'bar'}"; +% obj = JSON.parse(str); +% node.log(obj.val); // writes 12 +% \end{lstlisting} + +% \item \textbf{Serialize a JavaScript Object in JSON format} +% \begin{itemize} +% \item \texttt{JSON.stringify()} +% \end{itemize} +% \begin{lstlisting} +% var obj= new Object(); +% obj.val=34; +% obj.name='John'; +% str = JSON.stringify(obj); +% \end{lstlisting} +% \end{itemize} + +% \end{frame} + +% \begin{frame}[containsverbatim] +% \frametitle{Debug in Node Red} + +% \begin{itemize} +% \item \textbf{Use Debug Ouput} +% \begin{itemize} +% \item Insert it inside a flow of information +% \item Prints out the content of "\texttt{msg.payload}'' in the \emph{debug message} window +% \end{itemize} +% \item \textbf{Use log command} +% \begin{itemize} +% \item Inside JavaScript functions +% \item \texttt{node.log()} +% \item Output written inside the console (in our virtual machine). +% \end{itemize} +% \item \textbf{Example: (node for manipulating an input in a Web page)} +% \begin{lstlisting} +% node.log("Number ="+msg.req.query.number); +% var val = parseInt(msg.req.query.number); +% msg.req.query.number2=val*val; +% return msg; +% \end{lstlisting} +% \end{itemize} + +% \end{frame} + + + + +% \section{JSON in Node Red} +% \begin{frame}[containsverbatim] +% \frametitle{JSON in Node Red} +% \begin{itemize} +% \item \textbf{Example 1} +% \begin{itemize} +% \item We have an injection node (only for having a button) +% \item Then a function node that generates the JSON +% \item And another function node that consumes the JSON +% \item Output is then written out. +% \end{itemize} +% \end{itemize} +% % figure Node function create JSON +% \includegraphics[width=1\textwidth]{images/ex1-json.pdf} +% \end{frame} + + +% \begin{frame}[containsverbatim] +% \frametitle{Example1 create JSON in a node} + +% \begin{itemize} +% \item \textbf{Node create string:} + +% \begin{lstlisting} +% var data={"temp":37,"pulse":80}; +% node.log(typeof data); +% msg.payload = JSON.stringify(data); +% return msg; +% \end{lstlisting} +% \item \textbf{Function node creates a JSON object} +% \begin{lstlisting} +% p = JSON.parse(msg.payload); +% node.log(typeof p); +% msg.payload = p.temp; +% return msg; +% \end{lstlisting} +% \end{itemize} + +% \end{frame} + + +% \begin{frame}[containsverbatim] +% \frametitle{Example 2: Inject JSON } + +% \begin{itemize} +% \item \textbf{Use an inject Node to inject JSON as a text} +% \end{itemize} + +% \includegraphics[width=1\textwidth]{images/ex2-1-json.pdf} + +% \end{frame} + + +% \begin{frame}[containsverbatim] +% \frametitle{Example2} + +% \begin{itemize} +% \item \textbf{Text injected:} + +% \includegraphics[width=0.7\textwidth]{images/ex2-2-json.pdf} + +% \end{itemize} + +% \end{frame} + + +% \begin{frame}[containsverbatim] +% \frametitle{Example 3} + +% \begin{itemize} +% \item \textbf{We change the type generated by the injection node} +% \begin{itemize} +% \item From String to JSON +% \end{itemize} +% \item \textbf{We need to change the function node:} no need to create +% an object, payload is already an object (and not a string). +% \begin{lstlisting} +% //p = JSON.parse(msg.payload); +% p= msg.payload +% node.log(typeof p); +% msg.payload = p.temp; +% return msg; +% \end{lstlisting} +% \end{itemize} +% \end{frame} + +% \begin{frame}[containsverbatim] +% \frametitle{JSON Node} + +% \begin{itemize} +% \item \textbf{Is used to convert a JSON String to a JSON Object} +% \begin{itemize} +% \item It parses the content of \texttt{msg.payload} +% \end{itemize} +% \item \textbf{Or to convert a JSON Object into a JSON String} +% \begin{itemize} +% \item It stringifies the \texttt{msg.payload} +% \end{itemize} +% \end{itemize} + +% \end{frame} + + +% \begin{frame}[containsverbatim] +% \frametitle{Example 4, using a JSON node} + +% \begin{itemize} +% \item \textbf{We add a json node.} +% \begin{itemize} +% \item We inject a JSON object +% \item JSON node transform the object into a string +% \item In the function we have: +% \end{itemize} +% \begin{lstlisting} +% p = JSON.parse(msg.payload); +% //p= msg.payload +% node.log(typeof p); +% msg.payload = p.temp; +% return msg; +% \end{lstlisting} + +% \includegraphics[width=1\textwidth]{images/ex4-json.pdf} +% \end{itemize} + +% \end{frame} + +% \section{More complicated example} +% \begin{frame}[containsverbatim] +% \frametitle{Example 5: } + +% \begin{itemize} +% \item \textbf{Inject JSON Data is more complicated} +% \begin{lstlisting} +% { +% "topic": "test/s1", +% "data": { +% "temp":39, +% "pulse":120} +% } +% \end{lstlisting} +% \item \textbf{Function node} +% \begin{lstlisting} +% p=msg.payload; +% node.log(typeof p); +% msg.payload=p.data.temp; +% return msg; +% \end{lstlisting} +% \end{itemize} + +% \end{frame} + +% \section{The change node} +% \begin{frame}[containsverbatim] +% \frametitle{Ex6: The change node} + +% \begin{itemize} +% \item \textbf{Inject Node (same data)} +% \begin{lstlisting} +% { +% "topic": "test/s1", +% "data": { +% "temp":39, +% "pulse":120} +% } +% \end{lstlisting} +% \item \textbf{The change node} +% \begin{itemize} +% \item We select the expression +% \item and write \texttt{payload.data.temp} +% \item The payload is replaced by the temperature. +% \end{itemize} +% \end{itemize} +% \includegraphics[width=1\textwidth]{images/ex6-json.pdf} +% \end{frame} + + +% \begin{frame}[containsverbatim] +% \frametitle{Example 7: emulate a sensor} +% \footnotesize +% \begin{itemize} +% \item \textbf{We create different nodes for injecting values and a ``Max Min'' Node} +% \end{itemize} +% \lstset{basicstyle=\footnotesize} +% \begin{lstlisting} +% var data = context.get('data') || {}; +% var data2 = context.get('data2') || {}; +% var period = 5; // seconds +% var d= new Date(); +% now = d.getTime(); +% if(data2["count"]===undefined){ +% data2["count"]=0; +% } +% data["sensor_id"]="0001"; +% data["sensor_type"]="power"; +% if(data["max"]===undefined){ +% data["max"]=msg.payload; +% } +% if(data["min"]===undefined){ +% data["min"]=msg.payload; +% } +% if(data2["stime"]===undefined) +% data2["stime"]=now; +% \end{lstlisting} +% \end{frame} + + +% \begin{frame}[containsverbatim] +% \frametitle{Example 7: emulate a sensor (Cont.)} +% \lstset{basicstyle=\footnotesize} +% \begin{lstlisting} +% var count=data2.count; +% data2.count+=1; +% if(msg.payload>data.max) +% data.max=msg.payload; +% if(msg.payload<data.min) +% data.min=msg.payload; +% if((data2["stime"]+period*1000)<now){ +% var out = JSON.stringify(data); +% msg.payload = out; +% data={}; // clear the data +% context.set('data',data); +% data2={}; +% context.set('data2',data2); +% return msg; +% } +% context.set('data',data); +% context.set('data2',data2); +% return null; +% \end{lstlisting} + +% \end{frame} + + +% \begin{frame}[containsverbatim] +% \frametitle{Exercise} + +% \begin{itemize} +% \item \textbf{Import the example 7 into your system} +% \begin{itemize} +% \item Access to the example page +% \item Copy the source +% \item Menu Import: paste the source +% \end{itemize} +% \item \textbf{Modify the function to add an average} +% \end{itemize} + +% \end{frame} + +\section{Parsing JSON} +\begin{frame}[containsverbatim] +\frametitle{Parsing JSON (I)} + + +\begin{block}{PHP function \texttt{json\_decode}\footnote{Source : \url{https://www.php.net/manual/en/function.json-decode.php}}} + \begin{lstlisting} +json_decode( + string $json, + ?bool $associative = null, + int $depth = 512, + int $flags = 0 +): mixed + \end{lstlisting} +\end{block} +\end{frame} + +\begin{frame}[containsverbatim] +\frametitle{Parsing JSON (II)} + +\begin{block}{Example} + \begin{lstlisting} +<?php +$json = '{"a":1,"b":2,"c":3}'; +var_dump(json_decode($json)); +var_dump(json_decode($json, true)); +?> + \end{lstlisting}%$ +\end{block} +\end{frame} + +\begin{frame}[containsverbatim] +\frametitle{Parsing JSON (III)} + +\begin{block}{Output :} + + \begin{lstlisting} +object(stdClass)#1 (5) { + ["a"] => int(1) + ["b"] => int(2) + ["c"] => int(3) +} +array(5) { + ["a"] => int(1) + ["b"] => int(2) + ["c"] => int(3) +} + \end{lstlisting} +\end{block} + +\end{frame} +\begin{frame}[containsverbatim] +\frametitle{Examples (I)} + +\begin{block}{Access objects} + \begin{lstlisting} + <?php +$json = '{"foo-bar": 12345}'; + +$obj = json_decode($json); +print $obj->{'foo-bar'}; // 12345 +?> + \end{lstlisting} +\end{block} +\end{frame} +\begin{frame}[containsverbatim] +\frametitle{Examples (II)} + +\begin{block}{Access an array} + \begin{lstlisting} + <?php +$json = '[12345, 5678, 9012]'; + +$arr = json_decode($json); +print $arr[0]; // 12345 +?> + \end{lstlisting} +\end{block} + + +\end{frame} + +\section{Connection to a Server} +\begin{frame}[containsverbatim] +\frametitle{Principle of URI (I)} + + +\begin{block}{URI = Uniform Resource Identifier} + \begin{itemize} + \item Identify uniquely a resource + \item Can be a URL (Uniform Resource \emph{Locator}), + \item or a URN (Uniform Resource \emph{Name}. + \end{itemize} +\end{block} +\end{frame} + +\begin{frame}[containsverbatim] +\frametitle{Principle of URI (II)} +\begin{block}{Examples} + \begin{itemize} + \item URL \url{https://docs.taler.net/index.html} + +\url{ftp://ftp.is.co.za/rfc/rfc1808.txt} Location of the RFC 1808 +(defining the FTP protocol). + \item URN \url{https://docs.taler.net/taler-merchant-pos-terminal.html\#apis-and-data-formats} + + \url{urn:ietf:rfc:2396} is the identifier for the RFC~2396 + (defining the URIs). + \end{itemize} +\end{block} + +\end{frame} +\begin{frame}[containsverbatim] +\frametitle{URI Schema} + +\begin{block}{Syntax of a URI} + \begin{lstlisting} +scheme:[//authority]path[?query][#fragment] + \end{lstlisting} +\end{block} +\begin{block}{For + \url{https://docs.taler.net/taler-merchant-pos-terminal.html\#apis-and-data-formats}} + \begin{itemize} + \item scheme = \texttt{https} + \item authority = \texttt{docs.taler.net} + \item path = \texttt{taler-merchant-pos-terminal.html} + \item we do not have any query + \item fragment = \texttt{apis-and-data-formats} + \end{itemize} +\end{block} + +\end{frame} +\begin{frame}[containsverbatim] +\frametitle{URIs for REST APIs} + + +\begin{block}{Accessing a resource} + \begin{itemize} + \item A resource is one single element + \item \url{https://merchant.taler.net/products/1234} + \item Is the locator of the product 1234 + \end{itemize} +\end{block} +\begin{block}{Access a collection} + \begin{itemize} + \item A set of resources + \item \url{https://merchant.taler.net/products/} + \item Is the locator of the set of all products + \end{itemize} +\end{block} + +\end{frame} +\begin{frame}[containsverbatim] +\frametitle{Access a Resource using PHP} + + \begin{block}{Simple case : no authentication / authorization} + + \begin{lstlisting} +<?php + $url = 'https://exchange.demo.taler.net/keys'; + $response = file_get_contents($url); +?> + \end{lstlisting}%$ +\end{block} +\end{frame} + +\begin{frame}[containsverbatim] +\frametitle{Use a CURL object to generate a Request (I)} + + +\begin{block}{Example} + \begin{lstlisting} +<?php + $url = 'https://example.com/api'; + $curl = curl_init($url); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + $response = curl_exec($curl); + curl_close($curl); +?> + \end{lstlisting}%$ +\end{block} +\end{frame} + +\begin{frame}[containsverbatim] +\frametitle{Use a CURL object to generate a Request (II)} + + +\begin{block}{Details} + \begin{itemize} + \item Set options : we use the option + \texttt{CURLOPT\_RETURNTRANSFER} to download the returned string instead of + printing it out + \item We can configure any header or method for this request. + \end{itemize} +\end{block} + +\end{frame} +\begin{frame}[containsverbatim] +\frametitle{Example : } + +\begin{block}{Print out the keys of a server.} + + +\begin{lstlisting} + <?php + $url = 'https://bitcoin.ice.bfh.ch/keys'; + $curl = curl_init($url); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + $response = curl_exec($curl); + $keys = json_decode($response,true); + curl_close($curl); + var_dump(json_decode($keys); +?> +\end{lstlisting}%$ +\end{block} + +\end{frame} +\section{Direct Connection} +\begin{frame}[containsverbatim] +\frametitle{Direct Connection to a REST API} + + +\begin{block}{Wget} : + \begin{itemize} + \item to download content of a resource / collection + \end{itemize} + \begin{lstlisting} +wget https://bitcoin.ice.ti.bfh.ch/keys + \end{lstlisting} +\end{block} +\begin{block}{CURL} : + \begin{itemize} + \item to read / write data in a resource or a collection + \item headers and body can be manipulated. + \end{itemize} + \begin{lstlisting} +curl https://bitcoin.ice.bfh.ch/keys + \end{lstlisting} +\end{block} + +\end{frame} +\begin{frame}[containsverbatim] +\frametitle{Requests using CURL (I)} + +\begin{block}{GET request} + \begin{lstlisting} +curl --request GET \ + --url https://backend.demo.taler.net/private/orders \ + --header 'Authorization: Bearer secret-token:sandbox' \ + --header 'User-Agent: insomnia/8.6.1' + \end{lstlisting} +\end{block} +\end{frame} +\begin{frame}[containsverbatim] +\frametitle{Requests using CURL (II)} + +\begin{block}{POST Request} +\lstset{basicstyle=\small} + \begin{lstlisting} +curl --request POST \ + --url https://backend.demo.taler.net/private/orders \ + --header 'Authorization: Bearer secret-token:sandbox' \ + --header 'Content-Type: application/json' \ + --header 'User-Agent: insomnia/8.6.1' \ + --data '{ "order" :{ + "amount": "KUDOS:3", + "summary": "purchase for testing", + "fullfilment_message": "Thank you for your order" + }, + "create_token": false }' + \end{lstlisting} +\end{block} +\end{frame} + + +\begin{frame}[fragile,containsverbatim] +\frametitle{Using a Software (I)} + +\begin{block}{Insomnia\footnote{More info : \url{https://docs.insomnia.rest/}} is a software to generate REST requests} + \begin{itemize} + \item Can send request to a server, + \item can also generate the corresponding code in different + languages, + \item + \end{itemize} +\end{block} + +\begin{block}{Can be configure to send complex requests} + \begin{itemize} + \item All HTTP methods + \item With or without body + \item Many authentication methods + \end{itemize} +\end{block} +\note{Start a demonstration here. + +Access the resources : + +GET \url{https://backend.demo.taler.net/private/orders} + +with Bearer Token = secret-token:sandbox + +and POST to the same URL with body (type JSON). + + +% { +% "order" :{ +% "amount": "KUDOS:3", +% "summary": "purchase for testing", +% "fullfilment_message": "Thank you for your order" +% }, +% "create_token": false +% } + + +} +\end{frame} + +\begin{frame}[containsverbatim] +\frametitle{Using a Software (II)} +\begin{center} + \includegraphics[width=0.7\textwidth]{images/insomnia.png} +\end{center} +\end{frame} +\begin{frame}[containsverbatim] +\frametitle{Using a Software (III)} + +\begin{block}{Can generate code in many languages} + \begin{itemize} + \item From C to JavaScript throw Java + \item Includes variants for many frameworks + \end{itemize} +\end{block}\end{frame} + +\begin{frame}[containsverbatim] +\frametitle{Using a Software (IV)} + +\begin{center} + \includegraphics[width=0.7\textwidth]{images/insomnia-code.png} +\end{center} +\end{frame} + + + + +\section{Conclusion} +\begin{frame}[containsverbatim] +\frametitle{Conclusion} + +\begin{block}{RESTfull architecture allows reuse of software} + \begin{itemize} + \item Same piece of software can be used many times + \item from an app, from a single page application, + \item or from another software! + \end{itemize} +\end{block} + +\begin{block}{Lightweight development and deployment} + \begin{itemize} + \item Install a web server, + \item define your endpoints, + \item develop the methods you want to implement. + \item Straightforward to integrate from the client point of view. + \end{itemize} +\end{block} + +\end{frame} + +\begin{frame}[containsverbatim] +\frametitle{References} + + +\begin{block}{Taler Demo Merchant Backend} + +\url{https://backend.demo.taler.net/} +\end{block} +\begin{block}{Depolymerizer, a Taler Exchange server for Bitcoins} + +\url{https://bitcoin.ice.bfh.ch} +\end{block} + +\begin{block}{Insomnia} +\url{https://www.insomnia.rest/} +\end{block} + +\end{frame} + +% This should be last... +\begin{frame}{Acknowledgements} + + \begin{minipage}{0.45\textwidth} \ \\ + {\tiny Funded by the European Union (Project 101135475).} + + \begin{center} + \includegraphics[width=0.5\textwidth]{../texinputs/images/bandera.jpg} + \end{center} + \end{minipage} + \hfill + \begin{minipage}{0.45\textwidth} + {\tiny Funded by SERI (HEU-Projekt 101135475-TALER).} + + \begin{center} + \includegraphics[width=0.65\textwidth]{../texinputs/images/sbfi.jpg} + \end{center} + \end{minipage} + + \vfill + + {\tiny Views and opinions expressed are however those of the author(s) only + and do not necessarily reflect those of the European Union. Neither the + European Union nor the granting authority can be held responsible for + them.} +\end{frame} + + +\end{document} diff --git a/ngi-rest-api/01-introduction/images/Sans titre.png b/ngi-rest-api/01-introduction/images/Sans titre.png Binary files differnew file mode 100644 index 0000000..7958ed8 --- /dev/null +++ b/ngi-rest-api/01-introduction/images/Sans titre.png diff --git a/ngi-rest-api/01-introduction/images/ex1-json.pdf b/ngi-rest-api/01-introduction/images/ex1-json.pdf Binary files differnew file mode 100644 index 0000000..2e1ba8e --- /dev/null +++ b/ngi-rest-api/01-introduction/images/ex1-json.pdf diff --git a/ngi-rest-api/01-introduction/images/ex2-1-json.pdf b/ngi-rest-api/01-introduction/images/ex2-1-json.pdf Binary files differnew file mode 100644 index 0000000..e7c5bc5 --- /dev/null +++ b/ngi-rest-api/01-introduction/images/ex2-1-json.pdf diff --git a/ngi-rest-api/01-introduction/images/ex2-2-json.pdf b/ngi-rest-api/01-introduction/images/ex2-2-json.pdf Binary files differnew file mode 100644 index 0000000..379de95 --- /dev/null +++ b/ngi-rest-api/01-introduction/images/ex2-2-json.pdf diff --git a/ngi-rest-api/01-introduction/images/ex2-json.png b/ngi-rest-api/01-introduction/images/ex2-json.png Binary files differnew file mode 100644 index 0000000..10ec011 --- /dev/null +++ b/ngi-rest-api/01-introduction/images/ex2-json.png diff --git a/ngi-rest-api/01-introduction/images/ex4-json.pdf b/ngi-rest-api/01-introduction/images/ex4-json.pdf Binary files differnew file mode 100644 index 0000000..c0afd30 --- /dev/null +++ b/ngi-rest-api/01-introduction/images/ex4-json.pdf diff --git a/ngi-rest-api/01-introduction/images/ex6-json.pdf b/ngi-rest-api/01-introduction/images/ex6-json.pdf Binary files differnew file mode 100644 index 0000000..7e7945f --- /dev/null +++ b/ngi-rest-api/01-introduction/images/ex6-json.pdf diff --git a/ngi-rest-api/01-introduction/images/insomnia-code.png b/ngi-rest-api/01-introduction/images/insomnia-code.png Binary files differnew file mode 100644 index 0000000..f4d6680 --- /dev/null +++ b/ngi-rest-api/01-introduction/images/insomnia-code.png diff --git a/ngi-rest-api/01-introduction/images/insomnia.png b/ngi-rest-api/01-introduction/images/insomnia.png Binary files differnew file mode 100644 index 0000000..b452891 --- /dev/null +++ b/ngi-rest-api/01-introduction/images/insomnia.png diff --git a/ngi-rest-api/01-introduction/images/multiple-clients.pdf b/ngi-rest-api/01-introduction/images/multiple-clients.pdf Binary files differnew file mode 100644 index 0000000..7b9a044 --- /dev/null +++ b/ngi-rest-api/01-introduction/images/multiple-clients.pdf diff --git a/ngi-rest-api/01-introduction/images/multiple-clients.tex b/ngi-rest-api/01-introduction/images/multiple-clients.tex new file mode 100644 index 0000000..4f5a6a9 --- /dev/null +++ b/ngi-rest-api/01-introduction/images/multiple-clients.tex @@ -0,0 +1,34 @@ +\include{../../texinputs/header-drawings.tex} + +\begin{document} + +\begin{tikzpicture}[node distance=0.5cm, auto,] +\node[punkt](browser){\begin{tabular}{c}Browser\end{tabular}}; +\node[blank,below= of browser](space1){}; +\node[blank,right= of browser](spaceA){}; +\node[blank,right= of spaceA](http){\begin{tabular}{c} \end{tabular}}; +\node[below= of http](httprest){\begin{tabular}{c} \textbf{Data}\end{tabular}}; + +\node[blank,right= of http](spaceB){}; +\node[blank,right= of spaceB](server){\begin{tabular}{c}\end{tabular}}; +\node[punkt,below= of server](restapi){\begin{tabular}{c}REST API\end{tabular}}; + +\node[punkt,below= of +restapi](database){\begin{tabular}{c}Database\end{tabular}}; + +\node[punkt,below= of +space1](app){\begin{tabular}{c}Smartphone App\end{tabular}}; +\node[blank,below= of app](space2){}; +\node[punkt,below= of +space2](server2){\begin{tabular}{c}Other server\end{tabular}}; + + +%\path(browser.east) edge[<-, bend left=25] (server.west); +%\path [line] (server) -- (database); +\path [line] (browser.east) edge[<->] (restapi); +\path [line] (app.east) edge[<->] (restapi); +\path [line] (server2.east) edge[<->] (restapi); + +\path [line] (restapi) edge[<->] (database); +\end{tikzpicture} +\end{document}
\ No newline at end of file diff --git a/ngi-rest-api/01-introduction/images/single-page-application.pdf b/ngi-rest-api/01-introduction/images/single-page-application.pdf Binary files differnew file mode 100644 index 0000000..36c6765 --- /dev/null +++ b/ngi-rest-api/01-introduction/images/single-page-application.pdf diff --git a/ngi-rest-api/01-introduction/images/single-page-application.tex b/ngi-rest-api/01-introduction/images/single-page-application.tex new file mode 100644 index 0000000..b72280e --- /dev/null +++ b/ngi-rest-api/01-introduction/images/single-page-application.tex @@ -0,0 +1,22 @@ +\include{../../texinputs/header-drawings.tex} + +\begin{document} + +\begin{tikzpicture}[node distance=0.5cm, auto,] +\node[punkt](browser){\begin{tabular}{c}\textbf{Browser}\\Generates the DOM\end{tabular}}; +%\node[blank,right= of browser](space1){}; +\node[right= of browser](http){\begin{tabular}{c} HTML+JS \end{tabular}}; +\node[below= of http](httprest){\begin{tabular}{c} Data \end{tabular}}; + +%\node[blank,right= of http](space2){}; +\node[punkt,right= of http](server){\begin{tabular}{c}\textbf{Server}\\ static HTML + JS\end{tabular}}; +\node[punkt,below= of server](restapi){\begin{tabular}{c}REST API\end{tabular}}; + +\node[punkt,below= of restapi](database){\begin{tabular}{c}Database\end{tabular}}; +\path(browser.east) edge[<-, bend left=25] (server.west); +%\path [line] (server) -- (database); +\path [line] (browser.south) edge[<->,bend right=10] (restapi); + +\path [line] (restapi) edge[<->] (database); +\end{tikzpicture} +\end{document}
\ No newline at end of file diff --git a/ngi-rest-api/01-introduction/images/test-tikz.pdf b/ngi-rest-api/01-introduction/images/test-tikz.pdf Binary files differnew file mode 100644 index 0000000..5c04b82 --- /dev/null +++ b/ngi-rest-api/01-introduction/images/test-tikz.pdf diff --git a/ngi-rest-api/01-introduction/images/test-tikz.tex b/ngi-rest-api/01-introduction/images/test-tikz.tex new file mode 100644 index 0000000..86e0301 --- /dev/null +++ b/ngi-rest-api/01-introduction/images/test-tikz.tex @@ -0,0 +1,18 @@ +\documentclass[varwidth, border = 5 mm]{standalone} +\usepackage{tikz-cd} +\usetikzlibrary{shapes.geometric} +\usepackage{amsmath} + +\begin{document} + + \begin{tikzcd}[sep=large, +cells={nodes={ellipse, draw, thick, inner xsep=0pt}}, +every arrow/.append style = {-stealth, shorten > = 2pt, shorten <=2pt}, + ] +\text{1. ellipse} \ar[rd] + & & \\ + & \text{3. ellipse} \ar[r] & \text{4. ellipse} \\ +\text{2. ellipse} \ar[ru] & & + \end{tikzcd} + +\end{document}
\ No newline at end of file diff --git a/ngi-rest-api/01-introduction/images/test-tikz2.pdf b/ngi-rest-api/01-introduction/images/test-tikz2.pdf Binary files differnew file mode 100644 index 0000000..bc251c8 --- /dev/null +++ b/ngi-rest-api/01-introduction/images/test-tikz2.pdf diff --git a/ngi-rest-api/01-introduction/images/test-tikz2.tex b/ngi-rest-api/01-introduction/images/test-tikz2.tex new file mode 100644 index 0000000..e97d19a --- /dev/null +++ b/ngi-rest-api/01-introduction/images/test-tikz2.tex @@ -0,0 +1,35 @@ +\documentclass[tikz, margin=3mm]{standalone} +\usetikzlibrary{positioning} +\usetikzlibrary {shapes,matrix} + +\begin{document} + + +\begin{tikzpicture}[ +terminal/.style={ + % The shape: + ellipse, + % The size: + minimum width=2cm, + minimum height=1cm, + % The border: + very thick, + draw=blue, + % Font + font=\itshape, +}, +] +\matrix[row sep=2cm,column sep=2cm] {% + + % First row: + \node [terminal](p1) {Some text}; & & & \\ + %Second row + &\node [terminal](p3) {More text};& & \node [terminal](p4) {And more text}; \\ + % Third row: + \node [terminal](p2) {Some text}; & & &\\ +}; +\draw (p1) edge [->,>=stealth,shorten <=2pt, shorten >=2pt,thick] (p3) + (p2) edge [->,>=stealth,shorten <=2pt, shorten >=2pt, thick] (p3); +\draw (p3) edge [->,>=stealth,shorten <=2pt, shorten >=2pt,thick] (p4); +\end{tikzpicture} +\end{document}
\ No newline at end of file diff --git a/ngi-rest-api/01-introduction/images/test-tikz3.pdf b/ngi-rest-api/01-introduction/images/test-tikz3.pdf Binary files differnew file mode 100644 index 0000000..bf1d0e1 --- /dev/null +++ b/ngi-rest-api/01-introduction/images/test-tikz3.pdf diff --git a/ngi-rest-api/01-introduction/images/test-tikz3.tex b/ngi-rest-api/01-introduction/images/test-tikz3.tex new file mode 100644 index 0000000..e6ca896 --- /dev/null +++ b/ngi-rest-api/01-introduction/images/test-tikz3.tex @@ -0,0 +1,98 @@ +\documentclass[tikz, margin=3mm]{standalone} +\usetikzlibrary{positioning} +\usetikzlibrary {shapes,matrix} + +\usepackage{tikz, xcolor} +\usetikzlibrary{shapes,arrows,positioning} +\tikzset{ + %Define standard arrow tip + >=stealth', + %Define style for boxes + punkt/.style={ + rectangle, + rounded corners, + draw=black, very thick, + minimum width=3.5em, + minimum height=2em, + text centered}, + % Define arrow style + pull/.style={ + <->, + thick,draw=red, + shorten <=2pt, + shorten >=2pt,}, + % Define arrow style + pil/.style={ + ->, + thick, + shorten <=2pt, + shorten >=2pt,} +} + + +%\usepackage{tikz, xcolor} +%\usetikzlibrary{shapes,arrows} + + +\tikzstyle{decision} = [diamond, draw, text width=4.5em, + text badly centered, node distance=2cm, + inner sep=0pt] +\tikzstyle{block} = [rectangle, draw, text width=5em, + text centered, rounded corners, + minimum height=4em, node distance=3cm] +\tikzstyle{line} = [draw, -latex'] +\tikzstyle{lineeee} = [draw] +\tikzstyle{cloud} = [draw, ellipse, node distance=2.5cm, minimum height=2em] +\tikzstyle{walet} = [draw, rectangle, node distance=0.2cm, minimum height=2em] +\tikzstyle{reseau} = [node distance=0.2cm, minimum height=2em] +\tikzstyle{blank} = [node distance=1cm] + + +\begin{document} + +\begin{tikzpicture}[node distance=0.5cm, auto,] + %nodes +\node[punkt](alice){Alice}; +\node[walet,left= of alice](waletA1){\tiny\begin{tabular}{r|l}\textbf{mBTC}&\textbf{Adresse}\\50&anvjuerjHH\\8.7&NNjuURZZ\\300&UUIODG7\end{tabular}}; +\node[walet,left= of alice,node distance=-0.5cm](waletA2){\tiny\begin{tabular}{r|l}\textbf{mBTC}&\textbf{Adresse}\\50&anvjuerjHH\\8.7&NNjuURZZ\end{tabular}}; + \node[right=of alice] (dummy) {}; +\node[punkt,right= of dummy](bob){Bob}; +\node[walet,right= of bob](waletB1){\tiny\begin{tabular}{r|l}\textbf{mBTC}&\textbf{Adresse}\\~&~\end{tabular}}; +\node[walet,right= of bob](waletB2){\tiny\begin{tabular}{r|l}\textbf{mBTC}&\textbf{Adresse}\\&35UuDbjJ\end{tabular}}; +\node[walet,right= of bob](waletB3){\tiny\begin{tabular}{r|l}\textbf{mBTC}&\textbf{Adresse}\\300&35UuDbjJ\end{tabular}}; + +%\node[cloud,right= of dummy](bob){Bob}; +\node[above= of bob](grass){ cannabis.jpg}; + % \path<1-> [line] (bob) -- (alice); + +\node[above= of alice](grass2){cannabis.jpg}; + \node[blank,below=of dummy](code) {qrcode-bitcoin.png} + (bob.south) edge[pil] (code) + (code) edge[pil] (alice.south); +%\node<3-3>[below= of code]{Envoie BTC 0.03 à cette adresse}; + +\node[ below= of alice](transaction)[text width=5cm]{{\small + (0.03, UUIODG7 $\rightarrow$ 35UuDbjJ)}}; +\node[below= of dummy](dummy2){}; +\node[below= of dummy2](cloud){network-cloud-hi.png}; +%(transaction.south) edge[->, bend right=45] (cloud.west) +\path(transaction.south) edge[->, bend right=45] (cloud.west); +\node[below= of cloud,punkt](blockchain){Blockchain}; + +\node[walet,below= of blockchain](waletBC){\tiny\begin{tabular}{r|l}\textbf{mBTC}&\textbf{Adresse}\\50&anvjuerjHH\\8.7&NNjuURZZ\\0&UUIODG7 \\300&35UuDbjJ\end{tabular}}; + +\node[below= of waletB1,punkt](blockchain2){Blockchain}; + \path [line] (blockchain) -- (blockchain2); +\node[walet,below= of blockchain2](waletBC2){\tiny\begin{tabular}{r|l}\textbf{mBTC}&\textbf{Adresse}\\50&anvjuerjHH\\8.7&NNjuURZZ\\0&UUIODG7 \\300&35UuDbjJ\end{tabular}}; + \path [line] (bob) -- (alice); + + + + + +% \node<4>[below=of dummy] (d) {Données} +% (alice.east) edge[pil, bend right=45] (d) +% (d) edge[pil, bend right=45] (bob.west); +\end{tikzpicture} + +\end{document} diff --git a/ngi-rest-api/01-introduction/images/web-standard-architecture.pdf b/ngi-rest-api/01-introduction/images/web-standard-architecture.pdf Binary files differnew file mode 100644 index 0000000..44162f6 --- /dev/null +++ b/ngi-rest-api/01-introduction/images/web-standard-architecture.pdf diff --git a/ngi-rest-api/01-introduction/images/web-standard-architecture.tex b/ngi-rest-api/01-introduction/images/web-standard-architecture.tex new file mode 100644 index 0000000..56f7340 --- /dev/null +++ b/ngi-rest-api/01-introduction/images/web-standard-architecture.tex @@ -0,0 +1,16 @@ +\include{../../texinputs/header-drawings.tex} + +\begin{document} + +\begin{tikzpicture}[node distance=0.5cm, auto,] +\node[punkt](browser){\begin{tabular}{c}\textbf{Browser}\\Displays the DOM\end{tabular}}; +%\node[blank,right= of browser](space1){}; +\node[right= of browser](http){\begin{tabular}{c} HTML \\contains full DOM \end{tabular}}; +%\node[blank,right= of http](space2){}; +\node[punkt,right= of http](server){\begin{tabular}{c}\textbf{Server}\\ generates the DOM\end{tabular}}; +\node[punkt,below= of server](database){\begin{tabular}{c}Database\end{tabular}}; +\path(browser.east) edge[<->, bend right=25] (server.west); +%\path [line] (server) -- (database); +\path [line] (server) edge[<->] (database); +\end{tikzpicture} +\end{document}
\ No newline at end of file diff --git a/ngi-rest-api/02-operations/02-operations.pdf b/ngi-rest-api/02-operations/02-operations.pdf Binary files differnew file mode 100644 index 0000000..41deef8 --- /dev/null +++ b/ngi-rest-api/02-operations/02-operations.pdf diff --git a/ngi-rest-api/02-operations/02-operations.tex b/ngi-rest-api/02-operations/02-operations.tex new file mode 100644 index 0000000..fd0e982 --- /dev/null +++ b/ngi-rest-api/02-operations/02-operations.tex @@ -0,0 +1,892 @@ +\documentclass[aspectratio=169,t]{beamer} +\input ../texinputs/taler-macros + + + +% +% Anonymity lecture. Part of the NGI TALER lecture series. +% Copyright (C) 2024 Emmanuel Benoist +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see <http://www.gnu.org/licenses/>. +% + +% *Especially* edit these... +% \setbeameroption{show notes on second screen=right} % Both + +\newcommand{\SPEAKER}{Emmanuel Benoist} +\newcommand{\DATE}{Spring term 2024} + + +\newcommand{\TITLE}{NEXT \\ GENERATION \\ INTERNET} +\newcommand{\SUB}{REST API - Principles} +\newcommand{\AUTHOR}{Emmanuel Benoist} +\newcommand{\INST}{Bern University of Applied Sciences} + +% Do not edit this part +\title{\TITLE} +\subtitle{\SUB} +\date{\DATE} +\author[\SPEAKER]{\AUTHOR} +\institute{\INST} + +\usepackage{amsmath} +\usepackage{multimedia} +\usepackage[percent]{overpic} +\usepackage{url} +\usepackage{pifont} +\usepackage[absolute,overlay]{textpos} +\usepackage{listings} +\lstdefinelanguage{json}{ + basicstyle=\normalfont\ttfamily, + commentstyle=\color{red}, % style of comment + stringstyle=\color{blue}, % style of strings + %numbers=left, + %numberstyle=\scriptsize, + stepnumber=1, + numbersep=8pt, + showstringspaces=false, + breaklines=true, + %frame=lines, + %backgroundcolor=\color{gray}, %only if you like + string=[s]{"}{"}, + comment=[l]{:\ "}, + morecomment=[l]{:"}, + literate= + *{0}{{{\color{blue}0}}}{1} + {1}{{{\color{blue}1}}}{1} + {2}{{{\color{blue}2}}}{1} + {3}{{{\color{blue}3}}}{1} + {4}{{{\color{blue}4}}}{1} + {5}{{{\color{blue}5}}}{1} + {6}{{{\color{blue}6}}}{1} + {7}{{{\color{blue}7}}}{1} + {8}{{{\color{blue}8}}}{1} + {9}{{{\color{blue}9}}}{1} +} + +\lstset{language=PHP} + +\begin{document} + + +\frame{\maketitle +} + + +\begin{frame} +\frametitle{Rest Principles} +\tableofcontents +\end{frame} +\section{Architectural Constraints} + +\begin{frame}{Architectural Constraints (I)} + +Here are the 6 architectural constraints seen in our previous course. + + \begin{block}{Client-server architecture} + \begin{itemize} + \item User interface is separated from back-end. + \end{itemize} + \end{block} + \begin{block}{State-less protocol} + \begin{itemize} + \item The server must not store data corresponding to the session of the client. + \end{itemize} + \end{block} + \begin{block}{Cacheability} + \begin{itemize} + \item Clients can cache response values. + \item Values must be marked as cacheable or non cacheable. + \item Saves a lot of bandwidth and time. + \end{itemize} + \end{block} + +\end{frame} + + +\begin{frame}{Architectural Constraints (II)} + +\begin{block}{Code on demand (optional)} + \begin{block}{Layered system} + \begin{itemize} + \item For scalability reason, one could use proxy or a load + balancer, + \item without changing the code of the client or the server. + \end{itemize} + \end{block} \begin{itemize} + \item Servers can send executable code (scripts for instance) to + the clients. + \end{itemize} + \end{block} + \begin{block}{Uniform interface} + \begin{itemize} + \item Makes the architecture interoperable, + \item Any client can connect any server. + \end{itemize} + \end{block} + +\end{frame} + + +\begin{frame}{Uniform interface (I)} + \begin{block}{Resource identification in requests} + \begin{itemize} + \item Each resource is identified in the requests, + \item for instance using a URI + \end{itemize} + \end{block} + \begin{block}{Resource manipulation through representations} + \begin{itemize} + \item Client has enough information in the representation to + manipulate the resource (CRUD). + \end{itemize} + \end{block} + \begin{block}{Self-descriptive messages} + \begin{itemize} + \item Message contains enough information to be interpreted; + \item for instance MIME-Type for choosing how to display the resource. + \end{itemize} + \end{block} + +\end{frame} + + +\begin{frame}{Uniform interface (II)} + \begin{block}{Hypermedia as the engine of application state (HATEOAS)} + \begin{itemize} + \item Once a resource is downloaded, it contains hyperlinks to + related resources; + \item no need to hard code this in the client code. + \end{itemize} + \end{block} + +\end{frame} + +\section{URIs and Methods} + +\begin{frame}{RESTful Web Services} +A REST API is defined with : + \begin{block}{A Base URI} + \begin{itemize} + \item For instance \url{https://bitcoin.ice.bfh.ch/keys/} + \item called end-point or entry-point. + \end{itemize} + \end{block} + \begin{block}{HTTP methods} + \begin{itemize} + \item GET, POST, PUT, PATCH and DELETE + \end{itemize} + \end{block} + \begin{block}{Encoding of the resource} + \begin{itemize} + \item To know how to change data state. + \item Examples : Atom, microformats, application/vnd.collection+json, etc. + \end{itemize} + + \end{block} + +\end{frame} + + +\begin{frame}{URL for accessing to data} + \begin{block}{Collection corresponds to a URI that are pointing to a + endpoint directly} + \begin{itemize} + \item For instance \url{https://backend.demo.taler.net/private/orders}; + \item refers to a collection of items. + \end{itemize} + \end{block} + + \begin{block}{Access directly to one member} + \begin{itemize} + \item URL contains the address of the Endpoint plus the identifier + of the element. + \item Example : \url{https://backend.demo.taler.net/private/orders/ABB2GG33453} + \end{itemize} + \end{block} + + +\end{frame} +\subsection{GET} +\begin{frame}{Method GET to access information (I)} + + \begin{block}{Method GET for a collection} + \begin{itemize} + \item Gets the URI of the resources in the collection, + \item returns a list of the resources. + \end{itemize} + \end{block} + +\begin{block}{Method GET for a member resource} + \begin{itemize} + \item Contains the identifier of the resource in the URL. + \end{itemize} +\end{block} + +\end{frame} + +\begin{frame}{Method GET to access information (II)} + + + \begin{block}{Access to the representation of the resource} + \begin{itemize} + \item Depending on the \texttt{Accept} header of the request, + \item Can generate different formats for the same resource (JSON / + XML / CSV / HTML / ...). + \end{itemize} + \end{block} + +\begin{block}{GET APIs should be idempotent} + + \begin{itemize} + \item Making multiple identical requests must produce the same + result every time + \item until another API-call (POST, PUT, PATCH) has changed the + state of the resource on the server. + \end{itemize} +\end{block} + +\end{frame} + +\begin{frame}{Method GET to access information(III)} + + +\begin{block}{Returned Resource} + \begin{itemize} + \item If the Request-URI refers to a data-producing process, + \item it is the produced data that shall be returned as the entity + in the response + \item and not the source text of the process, + \item unless that text happens to be the output of the process. + \end{itemize} +\end{block} +\end{frame} + +\begin{frame}[containsverbatim]{GET examples : Collection (I)} +\begin{block}{Read a collection} + \begin{lstlisting} +GET /private/orders HTTP/1.1 +User-Agent: insomnia/8.6.1 +Authorization: Bearer secret-token:sandbox +Host: backend.demo.taler.net + + \end{lstlisting} + +This will download the list of all the elements in the collection. +\end{block} + +\end{frame} + +\begin{frame}[containsverbatim]{GET examples : Collection (II)} + +\begin{block}{JSON returned} +\lstset{language=json} +\lstset{basicstyle=\tiny} + \begin{lstlisting} +{ "orders": [ + { + "order_id": "2024.113-03R7NSPTF0YQ6", + "row_id": 34830, + "timestamp": { + "t_s": 1713799282 + }, + "amount": "KUDOS:3", + "summary": "payment after refund", ... + }, + { + "order_id": "2024.113-02G8P0KQT52R2", + "row_id": 34829, + "timestamp": { + "t_s": 1713799273 + }, + "amount": "KUDOS:7", + "summary": "order that will be refunded", ... + }, + ... + ] + } + \end{lstlisting} +\end{block} +\end{frame} + + +\begin{frame}[containsverbatim]{GET examples : Element (I)} +\begin{block}{Read a collection} + \begin{lstlisting} +GET /private/orders/2024.113-03R7NSPTF0YQ6 HTTP/1.1 +User-Agent: insomnia/8.6.1 +Authorization: Bearer secret-token:sandbox +Host: backend.demo.taler.net + + \end{lstlisting} + +This will download the details concerning the specific instance of the +collection. +\end{block} + +\end{frame} + +\begin{frame}[containsverbatim]{GET examples : Element (II)} + +\begin{block}{JSON returned} +\lstset{language=json} +\lstset{basicstyle=\tiny} + \begin{lstlisting} +{ + "wire_reports": [], + "exchange_code": 0, + "exchange_http_status": 0, + "exchange_ec": 0, + "exchange_hc": 0, + "deposit_total": "KUDOS:0", + "contract_terms": { + "summary": "payment after refund", + "fulfillment_url": "taler://fulfillment-success/thx", + "minimum_age": 0, + "products": [], + "h_wire": "WYEMPXPTA7....BFTJQ660GS1TG", + "wire_method": "iban", + "order_id": "2024.111-03429C3QC89DG", + "timestamp": { + "t_s": 1713576293 + }, + ... + \end{lstlisting} +\end{block} +\end{frame} +\subsection{POST} + +\begin{frame}{POST request (I)} + \begin{block}{Creates a new ressource} + \begin{itemize} + \item Creation uses the instructions in the Body of the Request + \end{itemize} + \end{block} + \begin{block}{URI of resource automatically generated} + \begin{itemize} + \item URI is returned in the \texttt{location} header of response, + \item Can also be part of the Body of the response. + \end{itemize} + \end{block} + + \begin{block}{POST is not idempotent} + \begin{itemize} + \item Running POST a second time with the same arguments, do not + expect the result to be consistent. + \end{itemize} + \end{block} +\end{frame} + + +\begin{frame}{POST request (II)} + \begin{block}{Do not use a POST on a URL of an element} + \begin{itemize} + \item It must creates a new resource, and should not modify an + existing one. + \end{itemize} \end{block} + +\end{frame} + +\begin{frame}[containsverbatim]{POST to add an order (Java)} + \lstset{language=Java,breaklines=true,basicstyle=\footnotesize} + \begin{lstlisting} +HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create("https://backend.demo.taler.net/private/orders")) + .header("Content-Type", "application/json") + .header("User-Agent", "insomnia/8.6.1") + .header("Authorization", "Bearer secret-token:sandbox") + .method("POST", HttpRequest.BodyPublishers.ofString("{\n\t\"order\" :{\n\t\t\"amount\": \"KUDOS:3\",\n\t\t\"summary\": \"purchase for testing\",\n\t\t\"fullfilment_message\": \"Thank you for your order\"\n\t},\n\t\"create_token\": false\n}")) + .build(); +HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString()); +System.out.println(response.body()); + \end{lstlisting} +\end{frame} + + +\begin{frame}[containsverbatim]{POST to add a product (HTTP)} + \lstset{breaklines=true,basicstyle=\footnotesize} + + \begin{lstlisting} +POST /private/products HTTP/1.1 +Content-Type: application/json +User-Agent: insomnia/8.6.1 +Authorization: Bearer secret-token:sandbox +Host: backend.demo.taler.net +Content-Length: 125 + +{ + product_id: "0001-1"; + description: "REST course"; + unit: "File"; + price: "KUDOS:2.0"; + total_stock: -1; +} + \end{lstlisting} +\end{frame} +\subsection{PUT} +\begin{frame}{PUT request on a Collection} + \begin{block}{Replaces ALL the instances of the collection} + \begin{itemize} + \item Takes the data in the Body to replace all the elements. + \end{itemize} + \end{block} + \begin{block}{or create a new collection} + \begin{itemize} + \item If the collection is empty; + \item If it does not exist yet; + \item uses the data in the body to initialize the collection. + \end{itemize} + \end{block} + +\end{frame} + +\begin{frame}{PUT request on an instance} + \begin{block}{Replaces ALL the values of an element} + \begin{itemize} + \item Takes the data in the Body to replace the element. + \end{itemize} + \end{block} + \begin{block}{or create a new element} + \end{block} + \begin{block}{PUT vs POST} + \begin{itemize} + \item POST should be used to CREATE an element, + \item PUT should be used to REPLACE an existing element. + \end{itemize} + \end{block} + +\end{frame} +\subsection{PATCH} +\begin{frame}[containsverbatim]{PATCH request (I)} +\begin{block}{Partial update on a resource} + \begin{itemize} + \item PUT is used to modify all the entity + \item PATCH will just make a delta between the existing resource and + the new value. + \item PATCH will not errase the rest of the element that is not + contained in the body of the request. + \end{itemize} +\end{block} + +\end{frame} + +\begin{frame}[containsverbatim]{PATCH request (II)} + +\begin{block}{Suppose we have the following product at this URL} +\url{https://backend.demo.taler.net/private/products/0001-1} +\end{block} +\begin{block}{Element} +\lstset{basicstyle=\tiny} +\begin{lstlisting} + { + "description": "REST course", + "description_i18n": {}, + "unit": "File", + "price": "KUDOS:2", + "image": "", + "taxes": [], + "total_stock": -1, + "total_sold": 0, + "total_lost": 0, + "address": {}, + "minimum_age": 0 +} +\end{lstlisting} + +\end{block} + +\end{frame} + +\begin{frame}[containsverbatim]{PATCH request (III)} + +\begin{block}{We patch the product} +\lstset{basicstyle=\footnotesize} + \begin{lstlisting} +PATCH /private/products/0001-1 HTTP/1.1 +Content-Type: application/json +User-Agent: insomnia/8.6.1 +Authorization: Bearer secret-token:sandbox +Host: backend.demo.taler.net +Content-Length: 101 + + { + "description": "REST course in PDF", + "unit": "File", + "price": "KUDOS:2.5", + "total_stock": -1 +} + \end{lstlisting} + +\end{block} + +\end{frame} + +\begin{frame}[containsverbatim]{PATCH request (IV)} + +\begin{block}{The patched product is changed} + + \begin{lstlisting} +{ + "description": "REST course in PDF", + "description_i18n": {}, + "unit": "File", + "price": "KUDOS:2.5", + "image": "", + "taxes": [], + "total_stock": -1, + ... +} \end{lstlisting} + +\end{block} + + +\end{frame} + +\begin{frame}[containsverbatim]{PATCH request (V)} + +\begin{block}{Update all the instances of the collection} + \begin{itemize} + \item According to values given in the body of the request; + \item updates the existing instances in the collection. + \end{itemize} + \end{block} + \begin{block}{Create the collection if it does not exist} + \end{block} +\begin{block}{Like \texttt{PUT}, \texttt{PATCH} is not intended + primarily for collections} + \begin{itemize} + \item One should avoid PUT and PATCH on collections. + \end{itemize} +\end{block} +\end{frame} + +\subsection{DELETE} +\begin{frame}{Method DELETE (I)} + +\begin{block}{Deletes the resource (if a resource)} + \begin{itemize} + \item If you DELETE a resource, + \item it’s removed from the collection of resources. + \end{itemize} +\end{block} +\begin{block}{Delete a collection} + \begin{itemize} + \item Erases all the resources contained in the collection. + \end{itemize} + \end{block} +\end{frame} + + +\begin{frame}{Method DELETE (II)} + +\begin{block}{Return codes} + \begin{itemize} + \item Return codes 200 (OK) : resource has been removed and response + contains an entity + \item 202 (Accepted) : deletion has been queued + \item 204 (No Content) : resource removed, response does not contain + any body. + \item 404 (Not found) : resource has already been removed. + \end{itemize} + \end{block} + + +\end{frame} + + + +\section{API authentication methods} + +\begin{frame}{Authorization / Authentication (I)} + + \begin{block}{Authentication vs Authorization} + \begin{itemize} + \item Authentication = who you are ? + \item Authorization = what you can do ? + \end{itemize} + \end{block} +\begin{block}{On Web pages} + \begin{itemize} + \item User authenticate using a username / password; + \item A session is started; + \item A cookie is sent for remembering that session; + \item Authorization is based on the right of the authenticated user. + \item Not possible for REST (since stateless requirement) + \end{itemize} + \end{block} +\end{frame} + + +\begin{frame}{Authorization / Authentication (II)} + +\begin{block}{Stateless authorization / authentication} + \begin{itemize} + \item User gets a token, + \item Token is resent inside each request. + \end{itemize} + \end{block} + + +\end{frame} + + +\begin{frame}[containsverbatim]{HTTP Authentication Schemes (I)} + + \begin{block}{Basic Authentication} + \begin{itemize} + \item the sender places a username:password into the request + header (base64 encoded). + \item is rarely recommended + \item due to its inherent security vulnerabilities. + \end{itemize} + +Here’s an example of a Basic Auth in a request header: +\begin{lstlisting} + Authorization: Basic bG9sOnNlY3VyZQ== +\end{lstlisting} +\end{block} +\end{frame} + + +\begin{frame}[containsverbatim]{HTTP Authentication Schemes (II)} + +\begin{block}{Bearer token} + \begin{itemize} + \item The token is sent in each request, + \item Provided normally by the server as answer to an authentication + (username / password for instance) + \end{itemize} +Here's an example of a Bearer Token in a request header : +\begin{lstlisting} + Authorization: Bearer <token> +\end{lstlisting} +\end{block} +\note[item]{The name “Bearer authentication” can be understood as + “give access to the bearer of this token.” The bearer token allowing + access to a certain resource or URL and most likely is a cryptic + string, usually generated by the server in response to a login + request. } +\end{frame} + +\begin{frame}{HTTP Authentication Schemes (III)} + \begin{block}{Risk with bearer in the source code} + \begin{itemize} + \item Token should not be hard coded in the source code + \item Could be read by anybody accessing the code (\texttt{git clone} for instance) + \end{itemize} + \end{block} +\note[item]{Remarque : The bearer token should never appear in the + source of the program (in Git for instance). In order to be + certain, one should use only tokens starting with ``SECURE'' and + test if this string is in the source code. } +\note[item]{The secret token is compliant with the RFC 8959 document. You can learn more about it here: https://datatracker.ietf.org/doc/html/rfc8959. Keep in mind that this is a Bearer token, and that your authoirization header needs to specify it.} + \begin{block}{Secret Token should be compliant with RFC8959} + \begin{itemize} + \item \url{https://datatracker.ietf.org/doc/html/rfc8959} + \item Idea : every secret token has prefix "secret-token:", + \item Easy to search in code, + \item No hard coded token in the code anymore! + \end{itemize} + \end{block} +\end{frame} + + + + + +\begin{frame}[containsverbatim]{API Key (I)} + \begin{block}{One unique key is given to one user} + \begin{itemize} + \item Key is generated at the first visit of the user + \item Same key will be reused in each request. + \end{itemize} + +Example of a header containing an API key + \end{block} + \begin{lstlisting} +Authorization: Apikey 1234567890abcdef + \end{lstlisting} +\end{frame} + +\begin{frame}[containsverbatim]{API Key (II)} + + \begin{block}{Key can be in various places} + \begin{itemize} + \item Authorization Header (c.f. hereover); + + \item Basic Auth (c.f. previous slides); + + \item Body Data; + +Contains for instance : + +\begin{lstlisting} +{"api-key": "1234-567890-1234''} +\end{lstlisting} + + \item Custom Header; + + \item Query String +(Has a lot of security problems, should be avoided). +\note[item]{The query string is stored for caching purpose and for +logging purpose in various systems (not just the client and the +server) so, the token would be made accessible for many persons.} + \end{itemize} + \end{block} + +\end{frame} + +\begin{frame}{OAuth (2.0)} + \begin{block}{Three tiers architecture} + \begin{itemize} + \item \emph{Resource owner} (that want to consume a resource) + \item \emph{Authorization server} (that makes the authentication and + delivers the tokens) + \item \emph{Resource server} (that delivers the service and consumes the tokens) + \end{itemize} + \end{block} + \begin{block}{Applied to REST APIs} + \begin{itemize} + \item Resource owner is the REST client + \item Authorization server is a third party server responsible for + authenticating the client and giving the tokens. + \item Resource server is the REST server that needs the token. + \end{itemize} + \end{block} + +\end{frame} + +\section{Conclusion} + +\begin{frame}{Conclusion} + \begin{block}{CRUD operations are backed by HTTP Methods} + \begin{itemize} + \item Creation with POST + \item Read with GET and HEAD + \item Update with PUT (full update) and PATCH (partial update) + \item Delete with DELETE + \item return information is contained in the status code and the + body of the response. + \end{itemize} + \end{block} + \begin{block}{Authorizations} + \begin{itemize} + \item Are possible in various means, + \end{itemize} + \end{block} +\end{frame} + +\begin{frame}{References (I)} + \begin{block}{Wikipedia} + \begin{itemize} + \item \url{https://en.wikipedia.org/wiki/REST} + \end{itemize} + \end{block} + \begin{block}{Taler Merchant Backend API description} + \begin{itemize} + \item \url{https://docs.taler.net/core/api-merchant.html} + \end{itemize} + \end{block} + +\begin{block}{Taler Demo Merchant Backend} + + \begin{itemize} + \item \url{https://backend.demo.taler.net/} + \end{itemize} +\end{block} + \begin{block}{REST API Tutorial} + \begin{itemize} + \item \url{https://restfulapi.net/http-methods/} + \end{itemize} + \end{block} +\end{frame} + +\begin{frame}{References (II)} + \begin{block}{The 4 most used REST authentication methods} + \begin{itemize} + \item \url{https://blog.restcase.com/4-most-used-rest-api-authentication-methods/} + \end{itemize} + \end{block} +\begin{block}{The 5 essential HTTP methods in RESTful API development} + \begin{itemize} + \item +\url{https://www.techtarget.com/searchapparchitecture/tip/The-5-essential-HTTP-methods-in-RESTful-API-development} + \end{itemize} +\end{block} + +\begin{block}{RFC8959 : The "secret-token" URI Scheme} + \begin{itemize} + \item \url{https://datatracker.ietf.org/doc/html/rfc8959} + \end{itemize} +\end{block} +\end{frame} + + + +\begin{frame}{Acknowledgements} + + \begin{minipage}{0.45\textwidth} \ \\ + {\tiny Funded by the European Union (Project 101135475).} + + \begin{center} + \includegraphics[width=0.5\textwidth]{../texinputs/images/bandera.jpg} + \end{center} + \end{minipage} + \hfill + \begin{minipage}{0.45\textwidth} + {\tiny Funded by SERI (HEU-Projekt 101135475-TALER).} + + \begin{center} + \includegraphics[width=0.65\textwidth]{../texinputs/images/sbfi.jpg} + \end{center} + \end{minipage} + + \vfill + + {\tiny Views and opinions expressed are however those of the author(s) only + and do not necessarily reflect those of the European Union. Neither the + European Union nor the granting authority can be held responsible for + them.} +\end{frame} + + + +\end{document} + +%%%%%%%%%%%%%%%%%%%%%%%% + +{ + "products": [ + { + "product_serial": 1, + "product_id": "asas" + } + ] +} + +{ + product_id: "0001-1"; + description: "REST course"; + unit: "File"; + price: "KUDOS:2.0"; + total_stock: -1; +} + +% \begin{frame}{} +% \begin{block}{} +% \begin{itemize} +% \item +% \end{itemize} +% \end{block} +% \end{frame} diff --git a/ngi-rest-api/03-security/03-security.pdf b/ngi-rest-api/03-security/03-security.pdf Binary files differnew file mode 100644 index 0000000..462dc79 --- /dev/null +++ b/ngi-rest-api/03-security/03-security.pdf diff --git a/ngi-rest-api/03-security/03-security.tex b/ngi-rest-api/03-security/03-security.tex new file mode 100644 index 0000000..49a9730 --- /dev/null +++ b/ngi-rest-api/03-security/03-security.tex @@ -0,0 +1,505 @@ +\documentclass[aspectratio=169,t]{beamer} +\input ../texinputs/taler-macros + + + +% +% Anonymity lecture. Part of the NGI TALER lecture series. +% Copyright (C) 2024 Emmanuel Benoist +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see <http://www.gnu.org/licenses/>. +% + +% *Especially* edit these... +% \setbeameroption{show notes on second screen=right} % Both + +\newcommand{\SPEAKER}{Emmanuel Benoist} +\newcommand{\DATE}{Spring term 2024} + + +\newcommand{\TITLE}{NEXT \\ GENERATION \\ INTERNET} +\newcommand{\SUB}{REST API - Security} +\newcommand{\AUTHOR}{Emmanuel Benoist} +\newcommand{\INST}{Bern University of Applied Sciences} + +% Do not edit this part +\title{\TITLE} +\subtitle{\SUB} +\date{\DATE} +\author[\SPEAKER]{\AUTHOR} +\institute{\INST} + +\usepackage{amsmath} +\usepackage{multimedia} +\usepackage[percent]{overpic} +\usepackage{url} +\usepackage{pifont} +\usepackage[absolute,overlay]{textpos} +\usepackage{listings} +\lstdefinelanguage{json}{ + basicstyle=\normalfont\ttfamily, + commentstyle=\color{red}, % style of comment + stringstyle=\color{blue}, % style of strings + %numbers=left, + %numberstyle=\scriptsize, + stepnumber=1, + numbersep=8pt, + showstringspaces=false, + breaklines=true, + %frame=lines, + %backgroundcolor=\color{gray}, %only if you like + string=[s]{"}{"}, + comment=[l]{:\ "}, + morecomment=[l]{:"}, + literate= + *{0}{{{\color{blue}0}}}{1} + {1}{{{\color{blue}1}}}{1} + {2}{{{\color{blue}2}}}{1} + {3}{{{\color{blue}3}}}{1} + {4}{{{\color{blue}4}}}{1} + {5}{{{\color{blue}5}}}{1} + {6}{{{\color{blue}6}}}{1} + {7}{{{\color{blue}7}}}{1} + {8}{{{\color{blue}8}}}{1} + {9}{{{\color{blue}9}}}{1} +} + +\lstset{language=PHP} + +\begin{document} +\frame{\maketitle +} +\begin{frame} +\frametitle{REST Security} +\tableofcontents +\end{frame} + +\begin{frame}{REST Security} + \begin{block}{} + \begin{itemize} + \item + \end{itemize} + \end{block} +\end{frame} + +\section{Secure Communication} +\begin{frame}{Use HTTPS only} + \begin{block}{HTTP is not secure} + \begin{itemize} + \item Is sent clear text (including credentials) + \item Everybody can read everything + \item Prone to Man in The Middle attacks + \end{itemize} + \end{block} + \begin{block}{Do not use HTTP inside your local network} + \begin{itemize} + \item LAN can be attacked from within. + \end{itemize} + \end{block} + \begin{block}{HTTPS with client authentication useful but complex} + \begin{itemize} + \item In HTTPS clients can be authenticated using a certificate; + \item Can be expensive (depending on the type of certificate); + \item Cumbersome to configure. + \item Normally, only server authentication is necessary for + security, user authentication will be done using other means. + \end{itemize} + \end{block} +\end{frame} + + +\begin{frame}{Never expose information in URL's} + \begin{block}{URL could contain sensitive information} + \begin{itemize} + \item Secure tokens + \item Sensitive data (username or passwords ) + \end{itemize} + \end{block} + \begin{block}{URL can (and should) be stored in cache} + \begin{itemize} + \item URL will appear in history and data-bases. + \item If contains sensitive information : it makes it accessible + \end{itemize} + \end{block} + + +\end{frame} + + +\section{Validate inputs} +\begin{frame}{Validate Inputs (I)} + \begin{block}{Do not trust input parameters or objects} + \begin{itemize} + \item Validate input : + \item length + \item range + \item format + \item type (string, numbers, positive/negative, + floats, integers, ...); + \end{itemize} + \end{block} + \begin{block}{Achieve an implicit input validation by using strong types} + \begin{itemize} + \item like number, booleans, dates, times + \item or fixed data rangs in API parameters + \end{itemize} + \end{block} +\end{frame} + + +\begin{frame}[containsverbatim]{Validate Inputs (II)} + \begin{block}{Example of type} + \begin{itemize} + \item + \url{https://docs.taler.net/core/api-taldir.html#tsref-type-VersionResponse} +\begin{lstlisting} +interface VersionResponse { + version: string; + name: "taler-directory"; + methods: TaldirMethod[]; + monthly_fee: Amount; + +} +interface TaldirMethod { + name: string; + challenge_fee: Amount; +} +\end{lstlisting} + \end{itemize} + \end{block} + +\end{frame} + + +\begin{frame}{Validate Inputs (II)} + \begin{block}{Inputs : Accept only known good} + \begin{itemize} + \item Do not use black list of inputs + \item Always use white lists + \item Constraint Text inputs with RegExp + \item Make use of validation libraries in your specific language. + \end{itemize} + \end{block} + \begin{block}{Reject unexpected and illegal content} + \begin{itemize} + \item Do not try to sanitize inputs, + \item User friendly feedback is not the job of an API. + \end{itemize} + \end{block} +\end{frame} + + +\begin{frame}{Validate Inputs (III)} + \begin{block}{Define a maximum input size limit} + \begin{itemize} + \item If the request is larger : \texttt{413 Request Entity Too Large} + \end{itemize} + \end{block} + \begin{block}{Use a secure parser} + \begin{itemize} + \item If working in XML, make sure not to be vulnerable to XXE and + similar attacks. + \end{itemize} + \end{block} + +\end{frame} + +\section{Access Validation} +\begin{frame}{Access Validation (I)} + \begin{block}{Each API Endpoint must perform access control (if not public)} + \begin{itemize} + \item Do not expect a Endpoint to be known only by your applications, + \end{itemize} + \end{block} + \begin{block}{Access decision must be taken locally by each endpoint} + \begin{itemize} + \item For the function, + \item for the list integrated in a collection + \item for controlling the access to each of the elements + \item the server must verify that the user has the right to access + to any element they want to access (Create, Read, Update or Delete) + \end{itemize} + \end{block} +\end{frame} + +\begin{frame}{Access Validation (II)} + \begin{block}{No validation of the access rights is expected on the + client side} + \begin{itemize} + \item Client must validate the rights for its own purpose + (usability); + \item Server must validate rights for security; + \item If client is rogue, no problem should occure. + \end{itemize} + \end{block} + \begin{block}{} + \begin{itemize} + \item + \end{itemize} + \end{block} + \begin{block}{} + \begin{itemize} + \item + \end{itemize} + \end{block} + \begin{block}{} + \begin{itemize} + \item + \end{itemize} + \end{block} +\end{frame} + +\section{Authentication} +\begin{frame}{Authentication} + \begin{block}{} + \begin{itemize} + \item + \end{itemize} + \end{block} +\end{frame} + +\begin{frame}{Password authentication (I)} + \begin{block}{Problems with password authentication} + \begin{itemize} + \item \textbf{Brute force} : attacker will try many passwords for + one account; + \item attacker may try many couples (account, password) stollen on + another service; + \item need to limit the number of tests in a given + period; + \item Assume that someone who is performing hundreds of failed input validations per second is up to no good. + \end{itemize} + \end{block} +\end{frame} + +\begin{frame}{Password authentication (II)} + \begin{block}{Store password in a secure way} + \begin{itemize} + \item Storing password clear text is prohibited (in case of a data + leakage); + \item Data can be stolen by extern attackers or by rogue employees + \item Password must be hashed and salted; + \item one should use a specifically designed hash function that + is difficult to brute force : + + argon2id, scrypt, bcrypt, or PBKDF2. + \item In case passwords are stollen : breaking them will cost a + lot (of memory and/or of CPU time). + \end{itemize} + \end{block} +\end{frame} + +\begin{frame}{JWT : JSON Web Tokens (I)} + \begin{block}{Standard for the exchange of secure tokens} + \begin{itemize} + \item Defined in the RFC7519 + \end{itemize} + \end{block} + \begin{block}{Structure} + \begin{itemize} + \item Header : describes the token (a JSON object) + \item Payload : The informations stored inside this object + \item Digital signature (for security purpose) + \end{itemize} + \end{block} +\end{frame} + +\begin{frame}[containsverbatim]{JWT : JSON Web Tokens (II)} + \begin{block}{Example} + +Header +\begin{lstlisting} +{"typ":"jwt", "alg":"HS512"} +\end{lstlisting} + +Payload +\begin{lstlisting} +{"name":"Taler","iat":121345543298} +\end{lstlisting} + +\note{In this example, we have a JWT token named Taler for which the + algorithm is HS512.} + \end{block} +\end{frame} + +\begin{frame}{JWT : JSON Web Tokens (III)} + + \begin{block}{Encoding} + \begin{itemize} + \item We encode header and payload using Base64url + \item Concatenate the two strings (adding a ``.'' between the two + items) + \item hash the concatenation plus your secret key (and encode in + Base64url) + \item concatenate the message and the hash into your token + \end{itemize} + \end{block} + \begin{block}{Verification} + \begin{itemize} + \item Decode the first part of the message, + \item hash it together with your secret key + \item verify the hash! + \end{itemize} + \end{block} +\end{frame} + +\begin{frame}{JWT : JSON Web Tokens (IV)} + + \begin{block}{Security issue : Replay attacks} + \begin{itemize} + \item JWT must contain a validity limit (not mandatory) + \item If a session is terminated (i.e. logout) : Token must be + added to a revocation list. + \end{itemize} + \end{block} +\end{frame} +\section{OAuth 2.0 and OpenIDConnect} +\begin{frame}{OAuth2.0} + \begin{block}{OAuth2.0 is a protocol for delegating the authorization} + \begin{itemize} + \item Your service will require access to another resource + \item The user logs in the resource provider + \item User selects which resources you are given access to + \item You receive a secure token for accessing the resource + \item Token can be used to connect the REST API + \end{itemize} + \end{block} + \begin{block}{User delegates the authorization to the bearer of the token} + \begin{itemize} + \item Token means : \emph{``the holder of the token is authorized to access (or + modify) this set of resources.''} + \end{itemize} + \end{block} +\end{frame} + + + +\begin{frame}{Example OAuth (I)} + \begin{block}{The KYC processus for Exchange} + \begin{itemize} + \item + \end{itemize} + \end{block} +\end{frame} + + +\begin{frame}{Example OAuth (II)} + \begin{block}{} + \begin{itemize} + \item + \end{itemize} + \end{block} +\end{frame} + + +\begin{frame}{OpenIDConnect} + \begin{block}{} + \begin{itemize} + \item + \end{itemize} + \end{block} +\end{frame} + + +\begin{frame}{Example : OpenIDConnect (I)} + \begin{block}{} + \begin{itemize} + \item + \end{itemize} + \end{block} +\end{frame} + + +\begin{frame}{Example : OpenIDConnect (II)} + \begin{block}{} + \begin{itemize} + \item + \end{itemize} + \end{block} +\end{frame} + + + + +\begin{frame}{References (I)} + \begin{block}{OWASP REST Security : REST Security Cheat Sheet} + \begin{itemize} + \item \url{https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html} + \end{itemize} + \end{block} + \begin{block}{Taler Merchant back end tutorial} + \begin{itemize} + \item \url{https://tutorials.taler.net/merchant/introduction} + \end{itemize} + \end{block} + \begin{block}{OWASP Top 10 API Security Risks – 2023} + \begin{itemize} + \item \url{https://owasp.org/API-Security/editions/2023/en/0x11-t10/} + \end{itemize} + \end{block} + \begin{block}{} + \begin{itemize} + \item \url{} + \end{itemize} + \end{block} + \begin{block}{} + \begin{itemize} + \item \url{} + \end{itemize} + \end{block} +\end{frame} + + + + +\begin{frame}{Acknowledgements} + + \begin{minipage}{0.45\textwidth} \ \\ + {\tiny Funded by the European Union (Project 101135475).} + + \begin{center} + \includegraphics[width=0.5\textwidth]{../texinputs/images/bandera.jpg} + \end{center} + \end{minipage} + \hfill + \begin{minipage}{0.45\textwidth} + {\tiny Funded by SERI (HEU-Projekt 101135475-TALER).} + + \begin{center} + \includegraphics[width=0.65\textwidth]{../texinputs/images/sbfi.jpg} + \end{center} + \end{minipage} + + \vfill + + {\tiny Views and opinions expressed are however those of the author(s) only + and do not necessarily reflect those of the European Union. Neither the + European Union nor the granting authority can be held responsible for + them.} +\end{frame} + + + +\end{document} + +%%%%%%%%%%%%%%%%%%%%%%%% + + +\begin{frame}{} + \begin{block}{} + \begin{itemize} + \item + \end{itemize} + \end{block} +\end{frame} diff --git a/ngi-rest-api/ngi-rest-api.html b/ngi-rest-api/ngi-rest-api.html new file mode 100644 index 0000000..14e7317 --- /dev/null +++ b/ngi-rest-api/ngi-rest-api.html @@ -0,0 +1,142 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> + <head> + <title>NGI TALER: REST APIs</title> + <meta name="author" content="Emmanuel Benoist"> + <meta name="robots" content="index,follow"> + <meta name="revisit-after" content="28 days"> + <meta name="publisher" content="Emmanuel Benoist"> + <meta name="date" content="2024"> + <meta name="rights" content="(C) 2024 Emmanuel Benoist"> + <meta http-equiv="expires" content="43200"> + <meta http-equiv="content-type" content="text/html;CHARSET=iso-8859-1"> + </head> + + <body bgcolor="#FFFFFF" text="#000000" link="#000033" vlink="#003300" alink="#330000"> + <h1>NGI TALER: REST API</h1> + <h2>General Information</h2> + <p> + This is a course on introduction to REST API for computer science + students. It is intended for second or third year students. + </p> + <p> + We present the principles of REST APIs and use Taler Merchant + back-end for an example of a working server. The language used for + examples can be chosen by the instructor. + </p> + <p> + The course is divided into four lectures of approximately 90 + minutes each. The lectures are modular, so that it is generally + possible to leave out some or most lectures with at best minimal + changes to the others. + </p> + <p> + The prerequisites are: + <ul> + </ul> + </p> + + <h2>Content</h2> + <p> + <ul> + </ul> + </p> + <p> + The course materials (slides and exercieses) are available in LaTeX source + licensed under the <a href="https://www.gnu.org/licenses/gpl-3.0.en.html">GNU General Public License v3+</a>. + </p> + + <h4>L0: HyperText Transfer Protocol</h4> + <dl> + <dt>Materials</dt> + <dt> + <ul> + <li><a href="00-http/00-http.pdf">Slides</a></li> + </ul> + </dt> + <dh>Exercises</dh> + <dt> + <ul> + <li><a href="00-http/00-http-exercise.pdf">HTTP exercise</a></li> + </ul> + </dt> + <dh>Further reading</dh> + <dt> + <ul> + <li><a href="00-http/example-forms.html">Example page for forms</a></li> + </ul> + </dt> + </dl> + + <h4>L1: Introduction to REST services</h4> + <dl> + <dt>Materials</dt> + <dt> + <ul> + <li><a href="01-introduction/01-introduction.pdf">Slides</a></li> + </ul> + </dt> + <dh>Exercises</dh> + <dt> + <ul> + <li><a href="01-introduction/01-introduction-exercise.pdf">Introduction exercise</a></li> + </ul> + </dt> + <dh>Further reading</dh> + <dt> + <ul> + <li><a href=""></a></li> + </ul> + </dt> + </dl> + + <h4>L2: RESTfull operations</h4> + <dl> + <dt>Materials</dt> + <dt> + <ul> + <li><a href="02-operations/02-operations.pdf">Slides</a></li> + </ul> + </dt> + <dh>Exercises</dh> + <dt> + <ul> + <li><a + href="02-operations/02-operations-exercise.pdf">RESTfull operations exercise</a></li> + </ul> + </dt> + <dh>Further reading</dh> + <dt> + <ul> + <li><a href=""></a></li> + </ul> + </dt> + </dl> + + <h4>L3: Security in REST</h4> + <dl> + <dt>Materials</dt> + <dt> + <ul> + <li><a href="03-security/03-security.pdf">Slides</a></li> + </ul> + </dt> + <dh>Exercises</dh> + <dt> + <ul> + <li><a href="03-security/03-security-exercise.pdf">Blind Signatures exercise</a></li> + </ul> + </dt> + <dh>Further reading</dh> + <dt> + <ul> + <li><a + href="https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html">OWASP + Cheat Sheet Series : <i>REST + Security Cheat Sheet</i></a></li> + </ul> + </dt> + </dl> + + </body> +</html> diff --git a/ngi-rest-api/texinputs/header-drawings.tex b/ngi-rest-api/texinputs/header-drawings.tex new file mode 100644 index 0000000..b13c368 --- /dev/null +++ b/ngi-rest-api/texinputs/header-drawings.tex @@ -0,0 +1,44 @@ +\documentclass[varwidth, border = 5 mm]{standalone} +% \usepackage{tikz-cd} +% \usetikzlibrary{shapes.geometric} +\usepackage{amsmath} + +\usepackage{tikz, xcolor} +\usetikzlibrary{shapes,arrows,positioning} +\tikzset{ + %Define standard arrow tip + >=stealth', + %Define style for boxes + punkt/.style={ + rectangle, + rounded corners, + draw=black, very thick, + minimum width=3.5em, + minimum height=2em, + text centered}, + % Define arrow style + pull/.style={ + <->, + thick,draw=red, + shorten <=2pt, + shorten >=2pt,}, + % Define arrow style + pil/.style={ + ->, + thick, + shorten <=2pt, + shorten >=2pt,} +} +\tikzstyle{decision} = [diamond, draw, text width=4.5em, + text badly centered, node distance=2cm, + inner sep=0pt] +\tikzstyle{block} = [rectangle, draw, text width=5em, + text centered, rounded corners, + minimum height=4em, node distance=3cm] +\tikzstyle{line} = [draw, -latex'] +\tikzstyle{lineeee} = [draw] +\tikzstyle{cloud} = [draw, ellipse, node distance=2.5cm, minimum height=2em] +\tikzstyle{walet} = [draw, rectangle, node distance=0.2cm, minimum height=2em] +\tikzstyle{reseau} = [node distance=0.2cm, minimum height=2em] +\tikzstyle{blank} = [node distance=1cm] + diff --git a/ngi-rest-api/texinputs/header-exercises.tex b/ngi-rest-api/texinputs/header-exercises.tex new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/ngi-rest-api/texinputs/header-exercises.tex diff --git a/ngi-rest-api/texinputs/header-slides.tex b/ngi-rest-api/texinputs/header-slides.tex new file mode 100644 index 0000000..df3a519 --- /dev/null +++ b/ngi-rest-api/texinputs/header-slides.tex @@ -0,0 +1,34 @@ +\documentclass[ + authorontitle=true, + aspectratio=169 + ]{beamer} + + +%\usepackage[main=ngerman]{babel} + +% The following is only necessary for compatibility with versions of pdftex older than April 2018 +\usepackage{iftex} +\ifPDFTeX +\usepackage[utf8]{inputenc} +\fi + + +%Makros für Formatierungen der Doku +%Im Allgemeinen nicht notwendig! +\let\code\texttt + +\usepackage{graphicx} + +\usepackage{listings} + +%\subtitle{Version 0.4} +\author[E. Benoist]{Emmanuel Benoist} +\institute{GNU-Taler} + +%Activate the output of a frame number: +\setbeamertemplate{page number in head/foot}[framenumber] + + +%\AtBeginSection{\sectionpage} +\author{Emmanuel Benoist} +\date{Fall Term 2023/2024} diff --git a/ngi-rest-api/texinputs/images/bandera.jpg b/ngi-rest-api/texinputs/images/bandera.jpg Binary files differnew file mode 100644 index 0000000..0132a1c --- /dev/null +++ b/ngi-rest-api/texinputs/images/bandera.jpg diff --git a/ngi-rest-api/texinputs/images/logo-NGI_TALER.ai b/ngi-rest-api/texinputs/images/logo-NGI_TALER.ai new file mode 100644 index 0000000..af9d842 --- /dev/null +++ b/ngi-rest-api/texinputs/images/logo-NGI_TALER.ai @@ -0,0 +1,168 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + version="1.1" + id="svg2137" + width="553.96533" + height="170.64532" + viewBox="0 0 553.96533 170.64532" + sodipodi:docname="logo_NGI_TALER.ai" + inkscape:version="1.2.2 (b0a8486541, 2022-12-01)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <defs + id="defs2141"> + <linearGradient + inkscape:collect="always" + id="linearGradient4636"> + <stop + style="stop-color:#0042b3;stop-opacity:1;" + offset="0" + id="stop4632" /> + <stop + style="stop-color:#000000;stop-opacity:1;" + offset="1" + id="stop4634" /> + </linearGradient> + <linearGradient + x1="0" + y1="0" + x2="1" + y2="0" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-139.45511,-135.52185,-135.52185,139.45511,177.4727,131.75308)" + spreadMethod="pad" + id="linearGradient2163"> + <stop + style="stop-opacity:1;stop-color:#00afbc" + offset="0" + id="stop2159" /> + <stop + style="stop-opacity:1;stop-color:#205374" + offset="1" + id="stop2161" /> + </linearGradient> + <clipPath + clipPathUnits="userSpaceOnUse" + id="clipPath2173"> + <path + d="M 0,127.984 H 415.474 V 0 H 0 Z" + id="path2171" /> + </clipPath> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4636" + id="linearGradient4654" + x1="14.72319" + y1="14.33813" + x2="213.9493" + y2="113.96497" + gradientUnits="userSpaceOnUse" /> + </defs> + <sodipodi:namedview + id="namedview2139" + pagecolor="#ffffff" + bordercolor="#000000" + borderopacity="0.25" + inkscape:showpageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1" + showgrid="false" + inkscape:zoom="2.6373491" + inkscape:cx="250.63045" + inkscape:cy="85.312938" + inkscape:window-width="1920" + inkscape:window-height="1015" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="g2145"> + <inkscape:page + x="0" + y="0" + id="page2143" + width="553.96533" + height="170.64532" + inkscape:export-filename="logo-NGI_TALER_Bold_.svg" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" /> + </sodipodi:namedview> + <g + id="g2145" + inkscape:groupmode="layer" + inkscape:label="Page 1" + transform="matrix(1.3333333,0,0,-1.3333333,0,170.64533)"> + <g + id="g2147" + style="mix-blend-mode:difference;fill:url(#linearGradient4654);fill-opacity:1;stroke:none;stroke-width:0;stroke-dasharray:none"> + <g + id="g2149" + style="fill:url(#linearGradient4654);fill-opacity:1;stroke:none;stroke-width:0;stroke-dasharray:none"> + <g + id="g2155" + style="fill:url(#linearGradient4654);fill-opacity:1;stroke:none;stroke-width:0;stroke-dasharray:none"> + <g + id="g2157" + style="fill:url(#linearGradient4654);fill-opacity:1;stroke:none;stroke-width:0;stroke-dasharray:none"> + <path + d="m 25.228,113.805 c -6.079,0 -11.051,-4.973 -11.051,-11.051 v 0 -77.523 c 0,-6.079 4.972,-11.051 11.051,-11.051 v 0 h 165.035 c 6.078,0 11.051,4.973 11.051,11.051 v 0 18.26 c 0,2.022 0.803,3.962 2.234,5.393 v 0 l 9.096,9.096 c 2.54,2.539 2.533,6.657 -0.013,9.188 v 0 l -9.067,9.017 c -1.44,1.431 -2.25,3.379 -2.25,5.409 v 0 21.16 c 0,6.078 -4.973,11.051 -11.051,11.051 v 0 z" + style="fill:url(#linearGradient4654);fill-opacity:1;stroke:none;stroke-width:0;stroke-dasharray:none" + id="path2165" /> + </g> + </g> + </g> + </g> + <g + id="g2167"> + <g + id="g2169" + clip-path="url(#clipPath2173)"> + <g + id="g2175" + transform="translate(175.9982,95.8645)"> + <path + d="m 0,0 v 0 c 4.074,0 7.376,-3.302 7.376,-7.376 v -48.993 c 0,-4.074 -3.302,-7.376 -7.376,-7.376 -4.074,0 -7.376,3.302 -7.376,7.376 V -7.376 C -7.376,-3.302 -4.074,0 0,0" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path2177" /> + </g> + <g + id="g2179" + transform="translate(152.1193,64.9934)"> + <path + d="M 0,0 H -0.506 C -0.57,0 -0.633,-0.008 -0.698,-0.01 -0.762,-0.008 -0.825,0 -0.89,0 h -7.283 c -3.929,0 -7.359,-2.965 -7.613,-6.885 -0.278,-4.296 3.124,-7.867 7.361,-7.867 0.776,0 1.343,-0.754 1.111,-1.494 -0.658,-2.088 -2.341,-3.751 -4.547,-4.333 -2.074,-0.547 -4.276,-0.821 -6.605,-0.821 -4.007,0 -7.574,0.865 -10.7,2.595 -3.127,1.73 -5.57,4.144 -7.331,7.24 -1.761,3.096 -2.641,6.617 -2.641,10.564 0,4.006 0.88,7.558 2.641,10.654 1.761,3.097 4.219,5.493 7.377,7.195 3.156,1.698 6.768,2.549 10.836,2.549 4.681,0 8.865,-1.269 12.55,-3.807 2.341,-1.612 5.524,-1.588 7.757,0.171 3.48,2.741 3.289,8.045 -0.315,10.452 -1.7,1.136 -3.538,2.112 -5.512,2.928 -4.553,1.881 -9.623,2.823 -15.208,2.823 -6.679,0 -12.69,-1.412 -18.03,-4.235 -5.344,-2.822 -9.517,-6.738 -12.522,-11.747 -3.005,-5.008 -4.508,-10.67 -4.508,-16.983 0,-6.315 1.503,-11.975 4.508,-16.984 3.005,-5.009 7.148,-8.924 12.43,-11.747 5.282,-2.824 11.231,-4.235 17.849,-4.235 4.613,0 9.197,0.699 13.751,2.095 0.045,0.014 0.091,0.028 0.136,0.042 7.104,2.202 11.884,8.86 11.884,16.297 v 9.047 C 6.486,-2.904 3.583,0 0,0" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path2181" /> + </g> + <g + id="g2183" + transform="translate(90.5807,88.5798)"> + <path + d="m 0,0 v -49.176 c 0,-4.023 -3.262,-7.285 -7.286,-7.285 h -1.381 c -2.181,0 -4.247,0.977 -5.631,2.662 l -24.229,29.505 c -1.804,2.197 -5.368,0.921 -5.368,-1.922 v -22.96 c 0,-4.023 -3.261,-7.285 -7.285,-7.285 -4.023,0 -7.285,3.262 -7.285,7.285 V 0 c 0,4.024 3.262,7.285 7.285,7.285 h 1.468 c 2.184,0 4.253,-0.979 5.636,-2.669 l 24.135,-29.475 c 1.802,-2.202 5.37,-0.927 5.37,1.918 V 0 c 0,4.024 3.261,7.285 7.285,7.285 C -3.262,7.285 0,4.024 0,0" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path2185" /> + </g> + </g> + </g> + <text + xml:space="preserve" + transform="scale(1,-1)" + style="font-variant:normal;font-weight:600;font-stretch:normal;font-size:31.76px;font-family:'Montserrat SemiBold';-inkscape-font-specification:Montserrat-SemiBold;writing-mode:lr-tb;fill:#6f9aa8;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="text2191" + x="237.90379" + y="-51.030296"><tspan + x="237.90379" + sodipodi:role="line" + id="tspan2187" + y="-51.030296" + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:31.76px;font-family:Montserrat;-inkscape-font-specification:'Montserrat, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal">T A L E R</tspan><tspan + x="237.90379" + y="-11.330296" + sodipodi:role="line" + id="tspan2189" /></text> + </g> +</svg> diff --git a/ngi-rest-api/texinputs/images/logo-NGI_TALER_Bold.png b/ngi-rest-api/texinputs/images/logo-NGI_TALER_Bold.png Binary files differnew file mode 100644 index 0000000..a7a10d2 --- /dev/null +++ b/ngi-rest-api/texinputs/images/logo-NGI_TALER_Bold.png diff --git a/ngi-rest-api/texinputs/images/logo-NGI_TALER_Bold.svg b/ngi-rest-api/texinputs/images/logo-NGI_TALER_Bold.svg new file mode 100644 index 0000000..1d7ce39 --- /dev/null +++ b/ngi-rest-api/texinputs/images/logo-NGI_TALER_Bold.svg @@ -0,0 +1,135 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + version="1.1" + id="svg2137" + width="553.96533" + height="170.64532" + viewBox="0 0 553.96533 170.64532" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <defs + id="defs2141"> + <linearGradient + id="linearGradient4636"> + <stop + style="stop-color:#0042b3;stop-opacity:1;" + offset="0" + id="stop4632" /> + <stop + style="stop-color:#000000;stop-opacity:1;" + offset="1" + id="stop4634" /> + </linearGradient> + <clipPath + clipPathUnits="userSpaceOnUse" + id="clipPath2173"> + <path + d="M 0,127.984 H 415.474 V 0 H 0 Z" + id="path2171" /> + </clipPath> + <linearGradient + xlink:href="#linearGradient4636" + id="linearGradient4654" + x1="14.72319" + y1="14.33813" + x2="213.9493" + y2="113.96497" + gradientUnits="userSpaceOnUse" /> + <linearGradient + xlink:href="#linearGradient4636" + id="linearGradient491" + gradientUnits="userSpaceOnUse" + x1="14.72319" + y1="14.33813" + x2="213.9493" + y2="113.96497" /> + <linearGradient + xlink:href="#linearGradient4636" + id="linearGradient493" + gradientUnits="userSpaceOnUse" + x1="14.72319" + y1="14.33813" + x2="213.9493" + y2="113.96497" /> + <linearGradient + xlink:href="#linearGradient4636" + id="linearGradient495" + gradientUnits="userSpaceOnUse" + x1="14.72319" + y1="14.33813" + x2="213.9493" + y2="113.96497" /> + <linearGradient + xlink:href="#linearGradient4636" + id="linearGradient497" + gradientUnits="userSpaceOnUse" + x1="14.72319" + y1="14.33813" + x2="213.9493" + y2="113.96497" /> + </defs> + <g + id="g2145" + transform="matrix(1.3333333,0,0,-1.3333333,0,170.64533)"> + <g + id="g2147" + style="mix-blend-mode:difference;fill:url(#linearGradient4654);fill-opacity:1;stroke:none;stroke-width:0;stroke-dasharray:none"> + <g + id="g2149" + style="fill:url(#linearGradient497);fill-opacity:1;stroke:none;stroke-width:0;stroke-dasharray:none"> + <g + id="g2155" + style="fill:url(#linearGradient495);fill-opacity:1;stroke:none;stroke-width:0;stroke-dasharray:none"> + <g + id="g2157" + style="fill:url(#linearGradient493);fill-opacity:1;stroke:none;stroke-width:0;stroke-dasharray:none"> + <path + d="m 25.228,113.805 c -6.079,0 -11.051,-4.973 -11.051,-11.051 v 0 -77.523 c 0,-6.079 4.972,-11.051 11.051,-11.051 v 0 h 165.035 c 6.078,0 11.051,4.973 11.051,11.051 v 0 18.26 c 0,2.022 0.803,3.962 2.234,5.393 v 0 l 9.096,9.096 c 2.54,2.539 2.533,6.657 -0.013,9.188 v 0 l -9.067,9.017 c -1.44,1.431 -2.25,3.379 -2.25,5.409 v 0 21.16 c 0,6.078 -4.973,11.051 -11.051,11.051 v 0 z" + style="fill:url(#linearGradient491);fill-opacity:1;stroke:none;stroke-width:0;stroke-dasharray:none" + id="path2165" /> + </g> + </g> + </g> + </g> + <g + id="g2167"> + <g + id="g2169" + clip-path="url(#clipPath2173)"> + <g + id="g2175" + transform="translate(175.9982,95.8645)"> + <path + d="m 0,0 v 0 c 4.074,0 7.376,-3.302 7.376,-7.376 v -48.993 c 0,-4.074 -3.302,-7.376 -7.376,-7.376 -4.074,0 -7.376,3.302 -7.376,7.376 V -7.376 C -7.376,-3.302 -4.074,0 0,0" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path2177" /> + </g> + <g + id="g2179" + transform="translate(152.1193,64.9934)"> + <path + d="M 0,0 H -0.506 C -0.57,0 -0.633,-0.008 -0.698,-0.01 -0.762,-0.008 -0.825,0 -0.89,0 h -7.283 c -3.929,0 -7.359,-2.965 -7.613,-6.885 -0.278,-4.296 3.124,-7.867 7.361,-7.867 0.776,0 1.343,-0.754 1.111,-1.494 -0.658,-2.088 -2.341,-3.751 -4.547,-4.333 -2.074,-0.547 -4.276,-0.821 -6.605,-0.821 -4.007,0 -7.574,0.865 -10.7,2.595 -3.127,1.73 -5.57,4.144 -7.331,7.24 -1.761,3.096 -2.641,6.617 -2.641,10.564 0,4.006 0.88,7.558 2.641,10.654 1.761,3.097 4.219,5.493 7.377,7.195 3.156,1.698 6.768,2.549 10.836,2.549 4.681,0 8.865,-1.269 12.55,-3.807 2.341,-1.612 5.524,-1.588 7.757,0.171 3.48,2.741 3.289,8.045 -0.315,10.452 -1.7,1.136 -3.538,2.112 -5.512,2.928 -4.553,1.881 -9.623,2.823 -15.208,2.823 -6.679,0 -12.69,-1.412 -18.03,-4.235 -5.344,-2.822 -9.517,-6.738 -12.522,-11.747 -3.005,-5.008 -4.508,-10.67 -4.508,-16.983 0,-6.315 1.503,-11.975 4.508,-16.984 3.005,-5.009 7.148,-8.924 12.43,-11.747 5.282,-2.824 11.231,-4.235 17.849,-4.235 4.613,0 9.197,0.699 13.751,2.095 0.045,0.014 0.091,0.028 0.136,0.042 7.104,2.202 11.884,8.86 11.884,16.297 v 9.047 C 6.486,-2.904 3.583,0 0,0" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path2181" /> + </g> + <g + id="g2183" + transform="translate(90.5807,88.5798)"> + <path + d="m 0,0 v -49.176 c 0,-4.023 -3.262,-7.285 -7.286,-7.285 h -1.381 c -2.181,0 -4.247,0.977 -5.631,2.662 l -24.229,29.505 c -1.804,2.197 -5.368,0.921 -5.368,-1.922 v -22.96 c 0,-4.023 -3.261,-7.285 -7.285,-7.285 -4.023,0 -7.285,3.262 -7.285,7.285 V 0 c 0,4.024 3.262,7.285 7.285,7.285 h 1.468 c 2.184,0 4.253,-0.979 5.636,-2.669 l 24.135,-29.475 c 1.802,-2.202 5.37,-0.927 5.37,1.918 V 0 c 0,4.024 3.261,7.285 7.285,7.285 C -3.262,7.285 0,4.024 0,0" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path2185" /> + </g> + </g> + </g> + <path + style="font-weight:bold;font-size:31.76px;font-family:Montserrat;-inkscape-font-specification:'Montserrat, Bold';fill:#6f9aa8" + d="m 245.14507,-51.030296 v -18.03968 h -7.11424 v -4.19232 h 19.3736 v 4.19232 h -7.11424 v 18.03968 z m 21.08867,0 9.90912,-22.232 h 5.0816 l 9.94088,22.232 h -5.3992 l -8.13056,-19.62768 h 2.03264 l -8.16232,19.62768 z m 4.95456,-4.764 1.36568,-3.90648 h 11.4336 l 1.39744,3.90648 z m 31.28366,4.764 v -22.232 h 5.14512 v 18.03968 h 11.14776 v 4.19232 z m 32.90339,-13.27568 h 10.70312 v 4.00176 h -10.70312 z m 0.38112,9.14688 h 12.10056 v 4.1288 h -17.21392 v -22.232 h 16.80104 v 4.1288 h -11.68768 z m 25.1857,4.1288 v -22.232 h 9.62328 q 2.98544,0 5.14512,0.98456 2.15968,0.9528 3.3348,2.76312 1.17512,1.81032 1.17512,4.31936 0,2.47728 -1.17512,4.2876 -1.17512,1.77856 -3.3348,2.73136 -2.15968,0.9528 -5.14512,0.9528 h -6.76488 l 2.28672,-2.25496 v 8.44816 z m 14.1332,0 -5.558,-8.06704 h 5.49448 l 5.62152,8.06704 z m -8.98808,-7.87648 -2.28672,-2.41376 h 6.47904 q 2.382,0 3.55712,-1.01632 1.17512,-1.04808 1.17512,-2.8584 0,-1.84208 -1.17512,-2.8584 -1.17512,-1.01632 -3.55712,-1.01632 h -6.47904 l 2.28672,-2.44552 z" + id="text2191" + transform="scale(1,-1)" + aria-label="T A L E R " /> + </g> +</svg> diff --git a/ngi-rest-api/texinputs/images/sbfi.jpg b/ngi-rest-api/texinputs/images/sbfi.jpg Binary files differnew file mode 100644 index 0000000..453ef94 --- /dev/null +++ b/ngi-rest-api/texinputs/images/sbfi.jpg diff --git a/ngi-rest-api/texinputs/myExercise.sty b/ngi-rest-api/texinputs/myExercise.sty new file mode 100644 index 0000000..799093a --- /dev/null +++ b/ngi-rest-api/texinputs/myExercise.sty @@ -0,0 +1,49 @@ +\ProvidesPackage{myExercise}[2003/11/07 ver 0.93] +\NeedsTeXFormat{LaTeX2e}[1995/12/01] +\RequirePackage{fancyhdr,hyperref} +% +\def\@course{} +\def\@nr{} +\def\@semester{} +\def\course#1{\def\@course{#1}} +\def\serie#1{\def\@nr{#1}} +\def\semester#1{\def\@semester{#1}} +% +\makeatletter +\def\maketitle{% +\null +\begin{center}\leavevmode +\normalfont +{\LARGE\textsf{\textbf{\@course}}\par}% +\vskip 1cm +{\large\textsf{\@author}\par}% +\vskip 1cm +{\Large\textsf{\@title~\@nr}\par}% +\vskip 1cm +\end{center}% +\null} +\fancypagestyle{plain}{ +\lhead{\small\textsf{\@title~\@nr}} +\rhead{\small\textsf{Page \thepage}} +\lfoot{\raisebox{2pt}{\small\textsf{\@course}}} +\cfoot{\raisebox{2pt}{\small\textsf{\@semester}}} +\rfoot{\raisebox{2pt}{\small\textsf{\@author}}} +\renewcommand\headrulewidth{0.5pt} +\renewcommand\footrulewidth{0.5pt}} +\makeatother +% +\setlength\textheight{23cm} +\setlength\textwidth{16cm} +\setlength\oddsidemargin{0mm} +\setlength\topmargin{-10mm} +\setlength\headsep{12mm} +\setlength\footskip{18mm} +% +% +\pagestyle{plain} +\hypersetup{colorlinks=true,urlcolor= blue,linkcolor=blue} +% +\newcounter{assign} +\newenvironment{assignment}[1]{\subsubsection*{\textsf{\stepcounter{assign}\theassign.~#1}}}{} +\newenvironment{assignment*}[1]{\subsubsection*{\textsf{#1}}}{} + diff --git a/ngi-rest-api/texinputs/taler-macros.tex b/ngi-rest-api/texinputs/taler-macros.tex new file mode 100644 index 0000000..08b9dbf --- /dev/null +++ b/ngi-rest-api/texinputs/taler-macros.tex @@ -0,0 +1,103 @@ +\usepackage[utf8]{inputenc} + +% fonts and colors +\usepackage[defaultfam,tabular,lining]{montserrat} + +\setbeamercolor{normal text}{fg=black,bg=white} +\setbeamercolor{alerted text}{fg=red!50!black} +\setbeamercolor{example text}{fg=green!50!black} + +\setbeamercolor{title}{fg=white} +\setbeamerfont{title}{size=\Huge} +\setbeamerfont{title}{series=\bfseries} + +\setbeamercolor{subtitle}{fg=white} +\setbeamerfont{subtitle}{size=\Large} + +\setbeamercolor{author}{fg=white} +\setbeamerfont{author}{size=\Large} + +\setbeamercolor{institute}{fg=white} +\setbeamerfont{institute}{size=\large} + +\setbeamercolor{date}{fg=black} +\setbeamerfont{date}{size=\large} + +\setbeamercolor{frametitle}{fg=white} +\setbeamerfont{frametitle}{size=\LARGE} +\setbeamerfont{framesubtitle}{size=\large} + +\makeatletter +\setbeamertemplate{frametitle}{% + \vbox{}\vskip-0.5em% + \begin{beamercolorbox}[wd=.7\paperwidth]{frametitle} + \usebeamerfont{frametitle}% + \strut\insertframetitle\strut\par% + \end{beamercolorbox} + \ifx\insertframesubtitle\@empty% + \vskip.9em + \else% + \vskip-0.3em + \begin{beamercolorbox}[wd=.68\paperwidth]{frametitle} + \usebeamerfont{framesubtitle}% + \strut\insertframesubtitle\strut\par% + \end{beamercolorbox} + \fi +} +\makeatother + +\usepackage{tikz} +\usetikzlibrary{calc,intersections,positioning,fadings,through} + +% footline +\setbeamertemplate{navigation symbols}{} +\setbeamertemplate{footline}{% + \leavevmode% + \includegraphics[height=0.7cm]{../texinputs/images/logo-NGI_TALER_Bold.png} + \hfill + \SPEAKER + \hfill + \TITLE + \hfill + \insertframenumber + \vskip0pt% +} + +% background + +\usepackage{xcolor} +\definecolor{left}{RGB}{0,66,179} + +\setbeamertemplate{title page} +{%\leavemode% + \begin{beamercolorbox}[wd=\the\paperwidth, ht=\the\paperheight,ignorebg,center]{} + \begin{tikzpicture}[overlay, remember picture] + \fill [left color=left, right color=left!50!black] (current page.north west) -- (current page.north east) -- ($(current page.north east)+(0,-6.5)$) -- ($(current page.north west)+(5,-6.5)$) -- ($(current page.north west)+(4.5,-6.8)$) -- ($(current page.north west)+(4,-6.5)$) -- ($(current page.north west)+(0,-6.5)$); + \end{tikzpicture} + \end{beamercolorbox}% + \vspace*{-8cm} + + \begin{beamercolorbox}[sep=8pt,left]{title} + {\usebeamerfont{title}\inserttitle\par}% + {\usebeamerfont{subtitle}\insertsubtitle\par}% + \end{beamercolorbox}% + \vskip1em\par + \begin{beamercolorbox}[sep=8pt,left]{author} + \usebeamerfont{author}\insertauthor + \end{beamercolorbox} + \begin{beamercolorbox}[sep=8pt,left]{institute} + \usebeamerfont{inst}\insertinstitute\\ + \end{beamercolorbox}% + + \begin{beamercolorbox}[sep=5pt,left]{date} + \usebeamerfont{date}\insertdate + \end{beamercolorbox} + \vspace*{2.5cm} +} + +\setbeamertemplate{background canvas} +{%\leavemode% + \begin{tikzpicture}[overlay, remember picture] + \fill [left color=left, right color=left!50!black] (current page.north west) -- (current page.north east) -- ($(current page.north east)+(0,-2)$) -- ($(current page.north west)+(5,-2)$) -- ($(current page.north west)+(4.5,-2.3)$) -- ($(current page.north west)+(4,-2)$) -- ($(current page.north west)+(0,-2)$); + \end{tikzpicture} +} |