commit d556d2d26c59ae9a8af7da2ec993bbf3d1b32b03 parent 552d2fde8cf2f2c1db7f2cf84e78f7ef90202a35 Author: Joel-Haeberli <haebu@rubigen.ch> Date: Tue, 19 Mar 2024 22:36:20 +0100 docs: fix toc, fix explanations Diffstat:
28 files changed, 219 insertions(+), 139 deletions(-)
diff --git a/.gitignore b/.gitignore @@ -31,6 +31,7 @@ _* *.cb *.cb2 .*.lb +*.out.ps ## Intermediate documents: *.dvi diff --git a/docs/content/architecture/nonce2ecash.tex b/docs/content/architecture/nonce2ecash.tex @@ -1,14 +1,16 @@ -\section*{The nonce2ecash RESTful API} +\section{nonce2ecash} The API of the nonce2ecash component mirrors the flow from the creation of a nonce2ecash mapping to the creation of the reserve. Therefore three endpoints are implemented. A specification of the API in yaml format can be found in \autoref*{appendix-api-spec}. -\subsection{Authentication} +\subsection{The nonce2ecash RESTful API} -Terminals which authenticate against the nonce2ecash API must provide their respective access token. Therefore, they provide a \texttt{Authorization: Bearer \$ACCESS\_TOKEN} header, where \$ACCESS\_TOKEN is a secret authentication token configured by the exchange and must begin with the RFC 8959 prefix \textit{secret-token}. +\subsubsection{Authentication} -\subsection{Configuration of nonce2ecash} +Terminals which authenticate against the nonce2ecash API must provide their respective access token. Therefore, they provide a \texttt{Authorization: Bearer \$ACCESS\_TOKEN} header, where \texttt{\$ACCESS\_TOKEN} is a secret authentication token configured by the exchange and must begin with the RFC 8959 \cite{rfc8959} prefix \textit{secret-token}. + +\subsubsection{Configuration of nonce2ecash} \begin{itemize} \item \textbf{Method:} GET @@ -17,10 +19,11 @@ Terminals which authenticate against the nonce2ecash API must provide their resp \item \textbf{Response:} HTTP status code 200 OK. The exchange responds with a \texttt{Nonce2ecashConfig} object. \end{itemize} -\subsection{Withdrawing using nonce2ecash} +\subsubsection{Withdrawing using nonce2ecash} Withdrawals with a nonce2ecash are based on withdrawal operations which register a withdrawal identifier (nonce) at the nonce2ecash component. The provider must first create a unique identifier for the withdrawal operation (the \texttt{WITHDRAWAL\_ID}) to interact with the withdrawal operation and eventually withdraw using the wallet. +\textbf{POST - withdrawal-operation} \begin{itemize} \item \textbf{Method:} POST \item \textbf{Endpoint:} /withdrawal-operation @@ -29,6 +32,7 @@ Withdrawals with a nonce2ecash are based on withdrawal operations which register \item \textbf{Response:} HTTP status code 204 No content, 400 Bad request, or 500 Internal Server error. \end{itemize} +\textbf{GET - withdrawal-operation by withdrawal-id} \begin{itemize} \item \textbf{Method:} GET \item \textbf{Endpoint:} /withdrawal-operation/\$WITHDRAWAL\_ID @@ -36,6 +40,7 @@ Withdrawals with a nonce2ecash are based on withdrawal operations which register \item \textbf{Response:} HTTP status code 200 OK or 404 Not found. \end{itemize} +\textbf{POST - withdrawal-operation by withdrawal-id} \begin{itemize} \item \textbf{Method:} POST \item \textbf{Endpoint:} /withdrawal-operation/\$WITHDRAWAL\_ID @@ -44,7 +49,7 @@ Withdrawals with a nonce2ecash are based on withdrawal operations which register \item \textbf{Response:} HTTP status code 204 No content, 400 Bad request, 404 Not found, or 500 Internal Server error. \end{itemize} -\section*{The nonce2ecash database} +\subsection{The nonce2ecash database} The database of the nonce2ecash component must track two different aspects. The first is the mapping of a nonce to a reserve public key to enable withdrawals and the second aspect is the authentication of terminals allowing withdrawals owned by terminal providers like \textit{Wallee}. diff --git a/docs/content/architecture/overview.tex b/docs/content/architecture/overview.tex @@ -1,14 +1,6 @@ -\section*{GNU Taler} -% TODO -General introduction to GNU Taler +\section{Overview} -\section*{Wallee} -% TODO -General introduction to Wallee - -\section*{Overview} - -\subsection*{Components} +\subsection{Components} \begin{figure}[h] \centering @@ -26,13 +18,13 @@ The component diagram shows the components involved by the withdrawal using the \label{fig-diagram-all-sequence} \end{figure} -The diagram in \autoref*{fig-diagram-all-sequence} shows the high level flow to withdraw Taler using the credit card terminal. It shows when the components of \autoref*{fig-diagram-all-components} interact with each other. It shows the implementation of the \textbf{nonce2ecash} flow. Terminal, Wallet and Exchange are linked leveraging a nonce initially generated by the terminal and presented to the Exchange by the withdrawing Wallet accompanied by a public key. +The diagram in \autoref{fig-diagram-all-sequence} shows the high level flow to withdraw Taler using the credit card terminal. It shows when the components of \autoref{fig-diagram-all-components} interact with each other. It shows the implementation of the \textbf{nonce2ecash} flow. Terminal, Wallet and Exchange are linked leveraging a nonce initially generated by the terminal and presented to the Exchange by the withdrawing Wallet accompanied by a public key. -\subsection*{The three parts} +\subsection{Process} -The process requires three parties. The Terminal, the Wallet and the Exchange must therefore interact with each other. +The process requires three parties interacting with each other. The Terminal, the Wallet and the Exchange must therefore interact with each other. In this section the highlevel process as showed in \autoref{fig-diagram-all-sequence} is explained. -\subsubsection*{The Terminal} +\subsubsection{The Terminal} The Terminal initiates the withdrawal leveraging an application which works as follows: @@ -41,20 +33,24 @@ The Terminal initiates the withdrawal leveraging an application which works as f \item When a user wishes to do a withdrawal, the owner of the terminal opens the application and initiates a new withdrawal. \begin{enumerate} \item Application creates a nonce - \item The application starts long polling at the Exchange and awaits the establishment of the nonce (by the Exchange). + \item The application starts long polling at the Exchange and awaits the selection of the reserve parameters mapped to the nonce. The parameters are sent by the Wallet to the Exchange. \item Nonce is packed into a QR code (with Exchange and amount entered by the terminal owner) + \item Terminal calculates fees and shows summary and the Terms of Service (ToS) of Taler. + \item The user accepts the offer, agrees with the ToS \item QR code is displayed \end{enumerate} \item The user now scans the QR Code using his wallet. - \item The application receives the establishment notification of the Exchange. - \item Terminal calculates fees and shows summary and the Terms of Service (ToS) of Taler. - \item The user accepts the offer, agrees with the ToS and pays using his Credit Card. - \item The Terminal executes the payment and presents the result to the user. + \item The application receives the notification of the Exchange, inlcuding the reserve public key. + \item The Terminal executes the payment (using the Terminal Backend, the reserve public key is sent as payment purpose). + \begin{enumerate} + \item It presents the result to the user. + \item It tells the Exchange, that the payment was successful. + \end{enumerate} \end{enumerate} -\subsubsection*{The Exchange} +\subsubsection{The Exchange} -The Exchange manages the withdrawal using a third party and seeks guarantees of the third party in order to provide a reserve containing Taler which can be withdrawn by the wallet. +The Exchange manages the withdrawal using a third party provider (e.g. Wallee) and seeks guarantees in order to provide a reserve containing Taler which can be withdrawn by the wallet. \begin{enumerate} \item The Exchange retrieves a long polling request for a nonce (from the Terminal). @@ -64,12 +60,12 @@ The Exchange manages the withdrawal using a third party and seeks guarantees of \item The Exchange ends the long polling from the terminal (by sending back the reserve public key). \item The Exchange receives payment notification of the terminal. \item The Exchange verifies the notification by asking the terminal backend for confirmation. - \item The Exchange, upon successfully checking the notification, creates the reserve with the verified amount + \item The Exchange, upon successfully checking the notification, checks that the transaction went through and therefore a reserve is created by the wirewatch gateway (using the public key in the payment purpose field). \end{enumerate} -\subsubsection*{The Wallet} +\subsubsection{The Wallet} -The Wallet must attest its presence to the terminal by registering a nonce and belonging reserve public key which will hold the Taler that can eventually be withdrawn by the wallet. +The Wallet must attest its presence to the terminal by registering a nonce and belonging reserve public key which will holds the digital currency that can eventually be withdrawn by the wallet. \begin{enumerate} \item The Wallet scans the QR Code (nonce, Exchange information and amount) on the Terminal @@ -77,12 +73,3 @@ The Wallet must attest its presence to the terminal by registering a nonce and b \item The Wallet sends the reserve public key and the scanned nonce to the Exchange \item The Wallet can withdraw money from the created reserve. \end{enumerate} - -\subsection*{Taler system} -\subsubsection*{Taler Wallet} -\subsubsection*{Taler Exchange} - -\subsection*{Terminal system} -\subsubsection*{Terminal} -\subsubsection*{Terminal Manufacturer Backend} -\subsubsection*{Terminal Fulfillment } -\ No newline at end of file diff --git a/docs/content/architecture/terminal.tex b/docs/content/architecture/terminal.tex @@ -1,6 +1,6 @@ -\section*{Wallee Terminal Application} +\section{Wallee Terminal Application} -\subsection*{Wallee Transaction Process} +\subsection{Wallee Transaction Process} describe: https://app-wallee.com/de-de/doc/payment/transaction-process document implications for cashless2ecash component (which states are reliable to cashout coins). diff --git a/docs/content/architecture/testing.tex b/docs/content/architecture/testing.tex @@ -1,13 +1,13 @@ -\section*{Testing} +\section{Testing} Testing is a crucial part and makes sure, every component behaves as intended. To make sure implementations are tested, this section describes the testing concept taken in place in order to do so. Two scopes will be leveraged in testing. One is the unit testing scope which tests single functions for their well behaving. The integration testing scope will then test the integration of the distributed parts with one another. While the unit tests will be automated tests, integrationtests are thought to be manual tests which are described in the respective section further down. -\subsection*{Testing in general} +\subsection{Testing in general} -\subsection*{Unit Testing} +\subsection{Unit Testing} -\subsection*{Component Testing} +\subsection{Component Testing} -\subsection*{Integration Testing} +\subsection{Integration Testing} -\subsubsection*{Test cases} +\subsubsection{Test cases} diff --git a/docs/content/architecture/usecase.tex b/docs/content/architecture/usecase.tex @@ -1 +1 @@ -\section*{Use Case} -\ No newline at end of file +\section{Use Case} +\ No newline at end of file diff --git a/docs/content/architecture/wallet.tex b/docs/content/architecture/wallet.tex @@ -1 +1 @@ -\section*{Wallet} -\ No newline at end of file +\section{Wallet} +\ No newline at end of file diff --git a/docs/content/context/context.tex b/docs/content/context/context.tex @@ -1,4 +0,0 @@ -To better understand the architecture, specification and the implementation of the new components, this chapter contains the description of the necessary components of the Taler system and the Wallee system. This is however not a complete documentation or explanation but rather a compilation of the features needed to implement the respective components. - -\include{content/context/taler} -\include{content/context/wallee} -\ No newline at end of file diff --git a/docs/content/context/taler.tex b/docs/content/context/taler.tex @@ -1,11 +0,0 @@ -\section*{GNU Taler} - -GNU Taler is a payment system which allows paying for goods in an anonymous way while maintaining a trustworthy relationship between exchanges, merchants and customers. This goal is reached by implementing strong cryptographic primitives. Taler is wether a blockchain nor a currency. It is a payment system. It allows transferring money from A to B anonymously but still letting regulators control that no bad activities are going on. - -\subsection*{Wirewatch Gateway RESTful API} - -The wirewatch gateway helps communicating with the Exchanges core using convenient API. This includes retrieving information about transactions which were sent through the EBICS system. EBICS stands for \textit{Electronic Banking Internet Communication Standard} and represents an interface for interbank communication based on TCP/IP. Taler can retrieve incoming transaction through the EBICS interface. This will help nonce2ecash to capture the transaction of the Terminal Backend to the Exchange's account and therefore allow the withdrawal by the customer. Therefore the wirewatch gateway API is used in nonce2ecash. - -\subsection*{Bank Integration RESTful API} - -The Bank Integration API is used to withdraw digital currency. It supplies API to initiate a withdrawal and fetching status information about a withdrawal. When initiating a withdrawal a reserve is created at the exchange which contains digital currency signed by the exchange. Since these assets are linked to a reserve public key supplied by the Taler Wallet, they can be retrieved by the Wallet. The reserve will only be collectable, if the transaction was approved by the Exchange as valid and the money reached the Exchange's bank account. diff --git a/docs/content/context/wallee.tex b/docs/content/context/wallee.tex @@ -1,5 +0,0 @@ -\section*{Wallee} - -\subsection*{Wallee Terminal} - -\subsection*{Wallee Backend and API} -\ No newline at end of file diff --git a/docs/content/implementation/exchange.tex b/docs/content/implementation/exchange.tex @@ -1 +1 @@ -\section*{implementing nonce2ecash docs} -\ No newline at end of file +\section{implementing nonce2ecash docs} +\ No newline at end of file diff --git a/docs/content/implementation/terminal.tex b/docs/content/implementation/terminal.tex @@ -1 +1 @@ -\section*{implementing terminal docs} -\ No newline at end of file +\section{implementing terminal docs} +\ No newline at end of file diff --git a/docs/content/implementation/wallee.tex b/docs/content/implementation/wallee.tex @@ -1 +1 @@ -\section*{implementing wallee docs} -\ No newline at end of file +\section{implementing wallee docs} +\ No newline at end of file diff --git a/docs/content/introduction/goal.tex b/docs/content/introduction/goal.tex @@ -1,10 +1,10 @@ -\section*{Goal} +\section{Goal} The goal of this thesis is to implement a process which allows withdrawing Taler using a credit card at a terminal of the terminal provider \textit{Wallee}. -\subsection*{nonce2ecash} +\subsection{nonce2ecash} Therefore a new component, named \textbf{nonce2ecash}, will be implemented as part of the Taler Exchange. Nonce2ecash will mediate between the Taler Exchange and the terminal provider. This includes checking that the transaction of the debitor reaches the account of the Exchange and therefore the digital currency can be withdrawn by the user, using its Wallet. -\subsection*{Wallee} +\subsection{Wallee} A new app for the payment terminal provider \textbf{Wallee} must be implemented which allows to start the withdrawal using providers facilities. The provider will guarantee through its backend, that the payment was successful. This puts the liability of the payment on the provider of the terminal. diff --git a/docs/content/introduction/introduction.tex b/docs/content/introduction/introduction.tex @@ -1,28 +1,28 @@ -\section*{Motivation} +\section{Motivation} -Ever tried withdrawing Taler? It is quite hard if a bank you have access to, does not implement and run the facilities supplied by Taler or you are not able to find people controlling the respective Exchange. The second approach is somewhat strange and prone to human errors anyway, but it works. +Ever used Taler to pay for your goods? Probably not. This is because there exist only very specific ways to withdraw money with Taler. -So the problem currently is that it is not possible for users to get Taler if the above options are not feasible for them. This thesis proposes a way allowing users who own a credit card and a Taler Wallet, to buy Taler at a terminal supporting the withdrawal of Taler. +So the problem currently is that it is not possible for a larger group of users to get money using Taler. This thesis proposes a way allowing users who own a credit card and a Taler Wallet, to withdraw money using Taler at a terminal supporting the withdrawal. -To make the withdrawal possible, various loose ends must be put together within the Taler ecosystem and the terminal provider. Also a new component called \textit{cashless2ecash} is implemented. The thesis focuses on the terminal provider called \textit{Wallee}. Therefore an application for the Wallee Terminal (PAX A50) for withdrawing Taler is implemented. +To make the withdrawal possible, various loose ends must be put together within the Taler ecosystem and the terminal provider. Also a new component called \textit{nonce2ecash} is implemented. The thesis focuses on the terminal provider called \textit{Wallee}. Therefore an application for the Wallee Terminal (PAX A50) for withdrawing money with Taler is implemented. -With these components, a trustworthy relationship can be created, which makes it possible for the Exchange to issue digital currency to a user. Therefore the Exchange is not putting his trust on the money received but rather on the promise of a trusted third party (the terminal provider) to put the received money in a location, controlled by the Exchange eventually (e.g. a bank account owned by the Exchange). +With these components, a trustworthy relationship can be created, which makes it possible for the Exchange to issue digital money to a user. Therefore the Exchange is not putting his trust on the money received but rather on the promise of a trusted third party (the terminal provider) to put the received money in a location, controlled by the Exchange eventually (e.g. a bank account owned by the Exchange). This enables a broader group of people to leverage Taler for their payments. Which eventually leads to wider adoption of the payment system Taler. -\section*{Perspectives} +\section{Perspectives} During the initial analysis of the task, two main areas of work were discovered. One is the Taler Exchange and the other is the Application for the terminal. This led to different views on the system by two different players within it. To allow a more concise view on the system and to support the readers and implementer, two perspectives shall be kept in mind. They have different views on the process but need to interact with each other seamlessly. -\subsection*{Terminal Application} -The perspective of the terminal application includes all processes within the application which interacts with the user, his Taler Wallet and its credit card allowing the withdrawal of digital currency. The terminal application wants to conviently allow the withdrawal of digital currency and charge fees to cover its costs and risks. +\subsection{Terminal Application} +The perspective of the terminal application includes all processes within the application which interacts with the user, his Taler Wallet and its credit card allowing the withdrawal of digital money. The terminal application wants to conviently allow the withdrawal of digital money and charge fees to cover its costs and risks. -\subsection*{Taler Exchange (nonce2ecash)} -The perspective of the Taler Exchange includes all processes within nonce2ecash component and the interaction with the terminal application, terminal backend and the wallet of the user. The Taler Exchange wants to allow withdrawal of digital currency only to users who pay the equivalent value to the Exchange. The Exchange wants to stay out of any legal implications at all costs. +\subsection{Taler Exchange (nonce2ecash)} +The perspective of the Taler Exchange includes all processes within nonce2ecash component and the interaction with the terminal application, terminal backend and the wallet of the user. The Taler Exchange wants to allow withdrawal of digital money only to users who pay the equivalent value to the Exchange. The Exchange wants to stay out of any legal implications at all costs. -\section*{Fees} -Since buying Taler using a credit card leverages a third party payment system, new \textbf{fees} are introduced and must be taken care of. The fees to buy Taler are defined by the third party payment system and therefore do not lie in the control of the Taler system. The fees are retrieved by the terminal and added to the amount of money which is to be withdrawn by the user. Only after giving the confirmation to buy the specified amount of Taler with the specified amount of fees, the payment shall be processed. +\section{Fees} +Since buying Taler using a credit card leverages a third party payment system, new \textbf{fees} are introduced and must be taken care of. The fees to withdraw money using Taler are defined by the third party payment system and therefore do not lie in the control of the Taler system. The fees are retrieved by the terminal and added to the amount of money which is to be withdrawn by the user. Only after giving the confirmation to buy the specified amount of Taler with the specified amount of fees, the payment shall be processed. -\section*{nonce2ecash} +\section{nonce2ecash} Very simplified, the process of a withdrawal currently looks as follows: \begin{enumerate} diff --git a/docs/content/sysview/sysview.tex b/docs/content/sysview/sysview.tex @@ -0,0 +1,4 @@ +To better understand the architecture, specification and the implementation of the new components, this chapter contains the description of the necessary components of the Taler system and the Wallee system. This is however not a complete documentation or explanation but rather a compilation of the features needed to implement the respective components. + +\include{content/sysview/taler} +\include{content/sysview/wallee} +\ No newline at end of file diff --git a/docs/content/sysview/taler.tex b/docs/content/sysview/taler.tex @@ -0,0 +1,7 @@ +\section{GNU Taler} + +GNU Taler is a payment system which allows paying for goods in an anonymous way while maintaining a trustworthy relationship between exchanges, merchants and customers. This goal is reached by implementing strong cryptographic primitives. Taler is wether a blockchain nor a currency. It is a payment system. It allows transferring money from A to B anonymously but still letting regulators control that no regulations are bypassed or ignored. + +\subsection{Wirewatch Gateway RESTful API} + +The wirewatch gateway helps communicating with the Exchange core using a convenient API. This includes retrieving information about transactions which were sent through the EBICS system. EBICS stands for \textit{Electronic Banking Internet Communication Standard} and represents an interface for interbank communication based on TCP/IP. Taler can retrieve incoming transaction through the EBICS interface using the Taler Nexus component, which acts as subscriber to an EBICS instance. This will help nonce2ecash to capture the transaction of the Terminal Backend to the Exchange's account and therefore allow the withdrawal by the customer. Therefore the wirewatch gateway API is used in nonce2ecash. When the wirewatch gateway captures a transaction pointed to the Exchanges account, it will automatically create a reserve if the payment purpose contains a valid reserve public key. diff --git a/docs/content/sysview/wallee.tex b/docs/content/sysview/wallee.tex @@ -0,0 +1,19 @@ +\section{Wallee} +Wallee offers level 1 PCI-DSS \cite{pci-dss} compliant payment processes to its customers \cite{wallee-pcidss-compliance} and allows an easy integration of its process into various kinds of merchant systems (e.g. websites, terminals, etc). + +\subsection{Wallee Terminal} +Wallee Terminals are based on android and run a modified, certified android version as operating system. Thus they can be used for payments and establish strong authentication in a trusted way. + +\subsection{Wallee Backend and API} +Terminals of Wallee are used to communicate with the customer at the shop of the merchant. The payment and processing of the transaction is run on the wallee backend. This means that + +\subsubsection{Wallee Transaction State} +In order to decide if a transaction was successful, the states of a transaction within Wallee must be mapped to the world of Taler. This means that a reserve shall only be created, if the transaction is in a state which allows Taler not having any liabilities regarding the transaction and that Wallee could process the payment successfully. The documentation states that \textit{only} in the transaction state (see \autoref*{fig-wallee-transasction-states}) \textit{fulfill}, the delivery of the goods (in case of withdrawal this means, that the reserve can be created) shall be started \cite*{wallee-transaction-process}. For the withdrawal this means, that the only interesting state for fulfillment is the \textit{fulfill} state. Every other state means, that the transaction was not successful and the reserve shall not be created. + +\begin{figure}[h] + \centering + \includegraphics[width=0.7\textwidth]{pictures/wallee/wallee_transaction_states.png} + \caption{Wallee Transaction States} + \label{fig-wallee-transasction-states} +\end{figure} + diff --git a/docs/pictures/wallee/wallee_transaction_states.png b/docs/pictures/wallee/wallee_transaction_states.png Binary files differ. diff --git a/docs/project.bib b/docs/project.bib @@ -20,4 +20,40 @@ url = {https://www.card-security.ch/betrugsarten/}, howpublished = {\url{https://www.card-security.ch/betrugsarten/}} -} -\ No newline at end of file +} + +@misc{pci-dss, + author = {PCI Security Standards Council}, + title = {PCI Data Security Standard}, + url = {https://docs-prv.pcisecuritystandards.org/PCI%20DSS/Standard/PCI-DSS-v4_0.pdf}, + howpublished = {\url{https://docs-prv.pcisecuritystandards.org/PCI%20DSS/Standard/PCI-DSS-v4_0.pdf}} +} + +@misc{wallee-transaction-process, + author = {Wallee}, + title = {Transaction States}, + url = {https://app-wallee.com/de-de/doc/payment/transaction-process}, + howpublished = {\url{https://app-wallee.com/de-de/doc/payment/transaction-process}} +} + +@misc{wallee-pcidss-compliance, + author = {Wallee}, + title = {Transaction States}, + url = {https://app-wallee.com/de-de/doc/payment}, + howpublished = {\url{https://app-wallee.com/de-de/doc/payment}} +} + +@misc{rfc8959, + series = {Request for Comments}, + number = 8959, + howpublished = {RFC 8959}, + publisher = {RFC Editor}, + doi = {10.17487/RFC8959}, + url = {https://www.rfc-editor.org/info/rfc8959}, + author = {Mark Nottingham}, + title = {{The "secret-token" URI Scheme}}, + pagetotal = 5, + year = 2021, + month = jan, + abstract = {This document registers the "secret-token" URI scheme to aid in the identification of authentication tokens.}, +} diff --git a/docs/thesis.pdf b/docs/thesis.pdf Binary files differ. diff --git a/docs/thesis.tex b/docs/thesis.tex @@ -177,8 +177,8 @@ \input{content/introduction/introduction} \input{content/introduction/goal} -\chapter{Context} -\input{content/context/context} +\chapter{System Overview} +\input{content/sysview/sysview} \chapter{Architecture} \input{content/architecture/overview} @@ -219,7 +219,7 @@ %------------ Appendix ---------------- \appendix \chapter{Appendix A} -\section*{API} +\section{API} \label{appendix-api-spec} \lstinputlisting[style=yaml,caption={nonce2ecash API specification}]{listings/specs/nonce2ecash_api_spec.yml} diff --git a/nonce2ecash/pkg/common/codec.go b/nonce2ecash/pkg/common/codec.go @@ -9,6 +9,7 @@ import ( type Codec[T any] interface { HttpApplicationContentHeader() string Encode(*T) (io.Reader, error) + EncodeToBytes(body *T) ([]byte, error) Decode(io.Reader) (*T, error) } @@ -35,6 +36,19 @@ func (*JsonCodec[T]) Encode(body *T) (io.Reader, error) { return bytes.NewReader(encodedBytes), err } +func (c *JsonCodec[T]) EncodeToBytes(body *T) ([]byte, error) { + + reader, err := c.Encode(body) + if err != nil { + return make([]byte, 0), err + } + buf, err := io.ReadAll(reader) + if err != nil { + return make([]byte, 0), err + } + return buf, nil +} + func (*JsonCodec[T]) Decode(reader io.Reader) (*T, error) { body := new(T) diff --git a/nonce2ecash/pkg/common/http-util.go b/nonce2ecash/pkg/common/http-util.go @@ -12,6 +12,7 @@ const HTTP_NO_CONTENT = 204 const HTTP_BAD_REQUEST = 400 const HTTP_UNAUTHORIZED = 401 const HTTP_NOT_FOUND = 404 +const HTTP_METHOD_NOT_ALLOWED = 405 const HTTP_CONFLICT = 409 const HTTP_INTERNAL_SERVER_ERROR = 500 diff --git a/nonce2ecash/pkg/handler.go b/nonce2ecash/pkg/handler.go @@ -1,62 +1,70 @@ package main import ( - "fmt" + "bytes" + "log" http "net/http" - "strings" + "nonce2ecash/pkg/common" ) -const HTTP_OK = 200 -const HTTP_NO_CONTENT = 204 -const HTTP_METHOD_NOT_ALLOWED = 405 +const CONFIG_ENDPOINT = "/config" +const WITHDRAWAL_OPERATION = "/withdrawal-operation" -func config(writer http.ResponseWriter, req *http.Request) { +const WOPID_PARAMETER = "wopid" +const GET_CONFIG_PATTERN = GET + CONFIG_ENDPOINT +const POST_WITHDRAWAL_OPERATION_PATTERN = POST + WITHDRAWAL_OPERATION +const GET_WITHDRAWAL_OPERATION_BY_WOPID_PATTERN = GET + WITHDRAWAL_OPERATION + "/{" + WOPID_PARAMETER + "}" +const POST_WITHDRAWAL_OPERATION_BY_WOPID_PATTERN = POST + WITHDRAWAL_OPERATION + "/{" + WOPID_PARAMETER + "}" - if isGet(req) { - writer.Write([]byte("{\n\"\":\"\",\n\"\":\"\"\n}")) - writer.WriteHeader(HTTP_OK) - } - - methodNotAllowed(writer) -} - -func withdrawalOperationDispatcher(writer http.ResponseWriter, req *http.Request) { +func config(res http.ResponseWriter, req *http.Request) { - fmt.Printf("req.URL.Fragment: %v\n", req.URL.Fragment) - fmt.Printf("req.URL.RawPath: %v\n", req.URL.RawPath) - fmt.Printf("req.URL.Path: %v\n", req.URL.Path) - - if strings.Compare("POST", strings.ToUpper(req.Method)) != 0 { + cfg := Nonce2ecashConfig{ + Name: "taler-nonce2ecash", + Version: "0:0:1", + } - writer.WriteHeader(405) + serializedCfg, err := common.NewJsonCodec[Nonce2ecashConfig]().EncodeToBytes(&cfg) + if err != nil { + log.Default().Printf("failed serializing config: %s", err.Error()) + res.WriteHeader(common.HTTP_INTERNAL_SERVER_ERROR) return } + res.WriteHeader(common.HTTP_OK) + res.Write(serializedCfg) } -func handleWithdrawalRegistration(writer http.ResponseWriter, req *http.Request) { +func handleWithdrawalRegistration(res http.ResponseWriter, req *http.Request) { + res.WriteHeader(common.HTTP_OK) + res.Write(bytes.NewBufferString("retrieved withdrawal request").Bytes()) } -func handleWithdrawalStatus(writer http.ResponseWriter, req *http.Request) { - -} +func handleWithdrawalStatus(res http.ResponseWriter, req *http.Request) { -func handlePaymentNotification(writer http.ResponseWriter, req *http.Request) { + wopid := parseWopId(req) + if wopid == "" { + res.WriteHeader(common.HTTP_BAD_REQUEST) + return + } + res.WriteHeader(common.HTTP_OK) + res.Write(bytes.NewBufferString("retrieved withdrawal status request for wopid=" + wopid).Bytes()) } -func isGet(req *http.Request) bool { +func handlePaymentNotification(res http.ResponseWriter, req *http.Request) { - return strings.EqualFold("GET", strings.ToUpper(req.Method)) -} - -func isPost(req *http.Request) bool { + wopid := parseWopId(req) + if wopid == "" { + res.WriteHeader(common.HTTP_BAD_REQUEST) + return + } - return strings.EqualFold("POST", strings.ToUpper(req.Method)) + res.WriteHeader(common.HTTP_OK) + res.Write(bytes.NewBufferString("retrieved payment notification for wopid=" + wopid).Bytes()) } -func methodNotAllowed(writer http.ResponseWriter) { +func parseWopId(req *http.Request) string { - writer.WriteHeader(HTTP_METHOD_NOT_ALLOWED) + return req.PathValue(WOPID_PARAMETER) } diff --git a/nonce2ecash/pkg/main.go b/nonce2ecash/pkg/main.go @@ -4,13 +4,30 @@ import ( http "net/http" ) -const CONFIG_ENDPOINT = "/config" -const WITHDRAWAL_OPERATION = "/withdrawal-operation" +const GET = "GET " +const POST = "POST " func main() { - http.HandleFunc(CONFIG_ENDPOINT, config) - http.HandleFunc(WITHDRAWAL_OPERATION, withdrawalOperationDispatcher) + http.HandleFunc( + GET_CONFIG_PATTERN, + config, + ) + + http.HandleFunc( + POST_WITHDRAWAL_OPERATION_PATTERN, + handleWithdrawalRegistration, + ) + + http.HandleFunc( + GET_WITHDRAWAL_OPERATION_BY_WOPID_PATTERN, + handleWithdrawalStatus, + ) + + http.HandleFunc( + POST_WITHDRAWAL_OPERATION_BY_WOPID_PATTERN, + handlePaymentNotification, + ) http.ListenAndServe(":8080", nil) } diff --git a/nonce2ecash/pkg/model.go b/nonce2ecash/pkg/model.go @@ -14,6 +14,10 @@ type WithdrawRegistration struct { ProviderId uint64 `json:"provider_id"` } +type Withdrawal struct { + ReservePubKey common.EddsaPublicKey `json:"reserve_pub_key"` +} + type PaymentNotification struct { ProviderTransactionId string `json:"provider_transaction_id"` Amount common.Amount `json:"amount"` diff --git a/nonce2ecash/pkg/pkg b/nonce2ecash/pkg/pkg Binary files differ.