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