xref: /haiku/src/apps/haikudepot/server/ServerHelper.cpp (revision 5d0fd0e4220b461e2021d5768ebaa936c13417f8)
1 /*
2  * Copyright 2017-2018, Andrew Lindesay <apl@lindesay.co.nz>.
3  * All rights reserved. Distributed under the terms of the MIT License.
4  */
5 
6 #include "ServerHelper.h"
7 
8 #include <stdio.h>
9 #include <stdlib.h>
10 
11 #include <Alert.h>
12 #include <Application.h>
13 #include <Catalog.h>
14 #include <NetworkInterface.h>
15 #include <NetworkRoster.h>
16 
17 #include "HaikuDepotConstants.h"
18 #include "ServerSettings.h"
19 #include "WebAppInterface.h"
20 
21 
22 #undef B_TRANSLATION_CONTEXT
23 #define B_TRANSLATION_CONTEXT "ServerHelper"
24 #define KEY_MSG_MINIMUM_VERSION "minimumVersion"
25 #define KEY_HEADER_MINIMUM_VERSION "X-Desktop-Application-Minimum-Version"
26 
27 
28 /*! This method will cause an alert to be shown to the user regarding a
29     JSON-RPC error that has been sent from the application server.  It will
30     send a message to the application looper which will then relay the message
31     to the looper and then onto the user to see.
32 */
33 
34 void
35 ServerHelper::NotifyServerJsonRpcError(BMessage& error)
36 {
37 	BMessage message(MSG_SERVER_ERROR);
38 	message.AddMessage("error", &error);
39 	be_app->PostMessage(&message);
40 }
41 
42 
43 void
44 ServerHelper::AlertServerJsonRpcError(BMessage* message)
45 {
46 	BMessage error;
47 	int32 errorCode = 0;
48 
49 	if (message->FindMessage("error", &error) == B_OK)
50 		errorCode = WebAppInterface::ErrorCodeFromResponse(error);
51 
52 	BString alertText;
53 
54 	switch (errorCode) {
55 		case ERROR_CODE_VALIDATION:
56 				// TODO; expand on that message.
57 			alertText = B_TRANSLATE("A validation error has occurred");
58 			break;
59 		case ERROR_CODE_OBJECTNOTFOUND:
60 			alertText = B_TRANSLATE("A requested object or an object involved"
61 				" in the request was not found on the server.");
62 			break;
63 		case ERROR_CODE_CAPTCHABADRESPONSE:
64 			alertText = B_TRANSLATE("The response to the captcha was incorrect.");
65 			break;
66 		case ERROR_CODE_AUTHORIZATIONFAILURE:
67 		case ERROR_CODE_AUTHORIZATIONRULECONFLICT:
68 			alertText = B_TRANSLATE("Authorization or security issue");
69 			break;
70 		default:
71 			alertText.SetToFormat(
72 				B_TRANSLATE("An unexpected error has been sent from the"
73 					" HaikuDepot server [%" B_PRIi32 "]"), errorCode);
74 			break;
75 	}
76 
77 	BAlert* alert = new BAlert(
78 		B_TRANSLATE("Server Error"),
79 		alertText,
80 		B_TRANSLATE("OK"));
81 
82 	alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
83 	alert->Go();
84 }
85 
86 
87 void
88 ServerHelper::NotifyTransportError(status_t error)
89 {
90 	switch (error) {
91 		case HD_CLIENT_TOO_OLD:
92 				// this is handled earlier on because it requires some
93 				// information from the HTTP request to create a sensible
94 				// error message.
95 			break;
96 
97 		default:
98 		{
99 			BMessage message(MSG_NETWORK_TRANSPORT_ERROR);
100 			message.AddInt64("errno", (int64) error);
101 			be_app->PostMessage(&message);
102 			break;
103 		}
104 	}
105 }
106 
107 
108 void
109 ServerHelper::AlertTransportError(BMessage* message)
110 {
111 	status_t errno = B_OK;
112 	int64 errnoInt64;
113 	message->FindInt64("errno", &errnoInt64);
114 	errno = (status_t) errnoInt64;
115 
116 	BString errorDescription("?");
117 	BString alertText;
118 
119 	switch (errno) {
120 		case HD_NETWORK_INACCESSIBLE:
121 			errorDescription = B_TRANSLATE("Network Error");
122 			break;
123 		default:
124 			errorDescription.SetTo(strerror(errno));
125 			break;
126 	}
127 
128 	alertText.SetToFormat(B_TRANSLATE("A network transport error has arisen"
129 		" communicating with the HaikuDepot server system: %s"),
130 		errorDescription.String());
131 
132 	BAlert* alert = new BAlert(
133 		B_TRANSLATE("Network Transport Error"),
134 		alertText,
135 		B_TRANSLATE("OK"));
136 
137 	alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
138 	alert->Go();
139 }
140 
141 
142 void
143 ServerHelper::NotifyClientTooOld(const BHttpHeaders& responseHeaders)
144 {
145 	if (!ServerSettings::IsClientTooOld()) {
146 		ServerSettings::SetClientTooOld();
147 
148 		const char* minimumVersionC = responseHeaders[KEY_HEADER_MINIMUM_VERSION];
149 		BMessage message(MSG_CLIENT_TOO_OLD);
150 
151 		if (minimumVersionC != NULL && strlen(minimumVersionC) != 0) {
152 			message.AddString(KEY_MSG_MINIMUM_VERSION, minimumVersionC);
153 		}
154 
155 		be_app->PostMessage(&message);
156 	}
157 }
158 
159 
160 void
161 ServerHelper::AlertClientTooOld(BMessage* message)
162 {
163 	BString minimumVersion;
164 	BString alertText;
165 
166 	if (message->FindString(KEY_MSG_MINIMUM_VERSION, &minimumVersion) != B_OK)
167 		minimumVersion = "???";
168 
169 	alertText.SetToFormat(
170 		B_TRANSLATE("This application is too old to communicate with the "
171 			" HaikuDepot server system.  Obtain a newer version of HaikuDepot "
172 			" by updating your Haiku system.  The minimum version of "
173 			" HaikuDepot required is \"%s\"."), minimumVersion.String());
174 
175 	BAlert* alert = new BAlert(
176 		B_TRANSLATE("client_version_too_old"),
177 		alertText,
178 		B_TRANSLATE("OK"));
179 
180 	alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
181 	alert->Go();
182 }
183 
184 
185 bool
186 ServerHelper::IsNetworkAvailable()
187 {
188 	return !ServerSettings::ForceNoNetwork() && IsPlatformNetworkAvailable();
189 }
190 
191 
192 bool
193 ServerHelper::IsPlatformNetworkAvailable()
194 {
195 	BNetworkRoster& roster = BNetworkRoster::Default();
196 	BNetworkInterface interface;
197 	uint32 cookie = 0;
198 	while (roster.GetNextInterface(&cookie, interface) == B_OK) {
199 		uint32 flags = interface.Flags();
200 		if ((flags & IFF_LOOPBACK) == 0
201 			&& (flags & (IFF_UP | IFF_LINK)) == (IFF_UP | IFF_LINK)) {
202 			return true;
203 		}
204 	}
205 
206 	return false;
207 }
208