1 /*!
2 * \copyright Copyright (c) 2014-2021 Governikus GmbH & Co. KG, Germany
3 */
4
5 #include "WebserviceActivationContext.h"
6
7 #include "LanguageLoader.h"
8 #include "Template.h"
9 #include "UrlUtil.h"
10
11 #include <QFile>
12 #include <QLoggingCategory>
13 #include <QUrlQuery>
14
15
16 using namespace governikus;
17
Q_DECLARE_LOGGING_CATEGORY(activation)18 Q_DECLARE_LOGGING_CATEGORY(activation)
19
20 void WebserviceActivationContext::setCommonHeaders(HttpResponse& pResponse) const
21 {
22 pResponse.setHeader(QByteArrayLiteral("Connection"), QByteArrayLiteral("close"));
23 pResponse.setHeader(QByteArrayLiteral("Cache-Control"), QByteArrayLiteral("no-cache, no-store"));
24 pResponse.setHeader(QByteArrayLiteral("Pragma"), QByteArrayLiteral("no-cache"));
25 }
26
27
WebserviceActivationContext(const QSharedPointer<HttpRequest> & pRequest)28 WebserviceActivationContext::WebserviceActivationContext(const QSharedPointer<HttpRequest>& pRequest)
29 : ActivationContext()
30 , mRequest(pRequest)
31 {
32 }
33
34
getActivationURL() const35 QUrl WebserviceActivationContext::getActivationURL() const
36 {
37 return mRequest->getUrl();
38 }
39
40
sendProcessing()41 bool WebserviceActivationContext::sendProcessing()
42 {
43 if (!mRequest->isConnected())
44 {
45 //: ERROR ALL_PLATFORMS No HTTP connection present.
46 mSendError = tr("The browser connection was lost.");
47 return false;
48 }
49
50 mRequest->send(HTTP_STATUS_PROCESSING);
51 return true;
52 }
53
54
sendOperationAlreadyActive()55 bool WebserviceActivationContext::sendOperationAlreadyActive()
56 {
57 if (!mRequest->isConnected())
58 {
59 //: ERROR ALL_PLATFORMS No HTTP connection present.
60 mSendError = tr("The browser connection was lost.");
61 return false;
62 }
63
64 Template htmlTemplate = Template::fromFile(QStringLiteral(":/html_templates/alreadyactive.html"));
65 //: ERROR ALL_PLATFORMS A new authentication request was received while the previous one was still running. Part of an HTML error page.
66 htmlTemplate.setContextParameter(QStringLiteral("TITLE"), tr("Cannot start authentication"));
67 //: ERROR ALL_PLATFORMS A new authentication request was received while the previous one was still running. Part of an HTML error page.
68 htmlTemplate.setContextParameter(QStringLiteral("MESSAGE_HEADER"), tr("Cannot start authentication"));
69 //: ERROR ALL_PLATFORMS A new authentication request was received while the previous one was still running. Part of an HTML error page.
70 htmlTemplate.setContextParameter(QStringLiteral("MESSAGE_HEADER_EXPLANATION"), tr("An operation is already in progress."));
71 //: ERROR ALL_PLATFORMS A new authentication request was received while the previous one was still running. Part of an HTML error page.
72 htmlTemplate.setContextParameter(QStringLiteral("CONTENT_HEADER"), tr("Would you like to try again?"));
73 htmlTemplate.setContextParameter(QStringLiteral("CONTENT_LINK"), mRequest->getUrl().toString());
74 //: ERROR ALL_PLATFORMS A new authentication request was received while the previous one was still running. Part of an HTML error page.
75 htmlTemplate.setContextParameter(QStringLiteral("CONTENT_BUTTON"), tr("Try again"));
76 QByteArray htmlPage = htmlTemplate.render().toUtf8();
77
78 HttpResponse response;
79 response.setStatus(HTTP_STATUS_CONFLICT);
80 response.setBody(htmlPage, QByteArrayLiteral("text/html; charset=utf-8"));
81 mRequest->send(response);
82 return true;
83 }
84
85
sendErrorPage(http_status pStatusCode,const GlobalStatus & pStatus)86 bool WebserviceActivationContext::sendErrorPage(http_status pStatusCode, const GlobalStatus& pStatus)
87 {
88 if (!mRequest->isConnected())
89 {
90 //: ERROR ALL_PLATFORMS No HTTP connection present.
91 mSendError = tr("The browser connection was lost.");
92 return false;
93 }
94
95 qCDebug(activation) << "Send error page to browser, error code" << pStatusCode;
96 Q_ASSERT(pStatusCode == HTTP_STATUS_BAD_REQUEST || pStatusCode == HTTP_STATUS_NOT_FOUND);
97 QString statusCodeString;
98 if (pStatusCode == HTTP_STATUS_BAD_REQUEST)
99 {
100 //: ERROR ALL_PLATFORMS HTTP error code 400, invalid request, part of an HTML error page.
101 statusCodeString = tr("400 Bad Request");
102 }
103 else if (pStatusCode == HTTP_STATUS_NOT_FOUND)
104 {
105 //: ERROR ALL_PLATFORMS HTTP error code 404, invalid request, part of an HTML error page.
106 statusCodeString = tr("404 Not found");
107 }
108
109 Template htmlTemplate = Template::fromFile(QStringLiteral(":/html_templates/error.html"));
110 htmlTemplate.setContextParameter(QStringLiteral("TITLE"), statusCodeString);
111 //: ERROR ALL_PLATFORMS Invalid request by the browser, part of an HTML error page
112 htmlTemplate.setContextParameter(QStringLiteral("MESSAGE_HEADER"), tr("Invalid request"));
113 //: ERROR ALL_PLATFORMS Invalid request by the browser, part of an HTML error page
114 htmlTemplate.setContextParameter(QStringLiteral("MESSAGE_HEADER_EXPLANATION"), tr("Your browser sent a request that couldn't be interpreted."));
115 //: ERROR ALL_PLATFORMS Invalid request by the browser, part of an HTML error page
116 htmlTemplate.setContextParameter(QStringLiteral("ERROR_MESSAGE_LABEL"), tr("Error message"));
117 htmlTemplate.setContextParameter(QStringLiteral("ERROR_MESSAGE"), pStatus.toErrorDescription(true));
118 //: ERROR ALL_PLATFORMS Invalid request by the browser, part of an HTML error page
119 htmlTemplate.setContextParameter(QStringLiteral("REPORT_HEADER"), tr("Would you like to report this error?"));
120 htmlTemplate.setContextParameter(QStringLiteral("REPORT_LINK"), QStringLiteral("https://www.ausweisapp.bund.de/%1/aa2/report").arg(LanguageLoader::getLocalCode()));
121 //: ERROR ALL_PLATFORMS Invalid request by the browser, part of an HTML error page
122 htmlTemplate.setContextParameter(QStringLiteral("REPORT_BUTTON"), tr("Report now"));
123 QByteArray htmlPage = htmlTemplate.render().toUtf8();
124
125 HttpResponse response;
126 setCommonHeaders(response);
127 response.setStatus(pStatusCode);
128 response.setBody(htmlPage, QByteArrayLiteral("text/html; charset=utf-8"));
129 mRequest->send(response);
130 return true;
131 }
132
133
sendRedirect(const QUrl & pRedirectAddress,const GlobalStatus & pStatus)134 bool WebserviceActivationContext::sendRedirect(const QUrl& pRedirectAddress, const GlobalStatus& pStatus)
135 {
136 QUrl redirectAddressWithResult = UrlUtil::addMajorMinor(pRedirectAddress, pStatus);
137 qCDebug(activation) << "Redirect URL:" << redirectAddressWithResult;
138
139 if (!mRequest->isConnected())
140 {
141 const auto& url = QStringLiteral("<a href='%1'>%2</a>").arg(redirectAddressWithResult.toString(), redirectAddressWithResult.host());
142 //: ERROR ALL_PLATFORMS The connection to the browser was lost/timed out..
143 mSendError = tr("The connection to the browser was lost. No forwarding was executed. Please try to call the URL again manually: %1").arg(url);
144 return false;
145 }
146
147 qCDebug(activation) << "Redirecting now to URL:" << redirectAddressWithResult;
148 HttpResponse response;
149 setCommonHeaders(response);
150 response.setHeader(QByteArrayLiteral("Location"), redirectAddressWithResult.toEncoded());
151 response.setStatus(HTTP_STATUS_SEE_OTHER);
152 mRequest->send(response);
153 return true;
154 }
155