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