xref: /haiku/src/apps/haikudepot/server/ServerHelper.cpp (revision 77fb9ca3e653f72d1d15c9f1a50c3d4287f680e0)
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 
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 incorrect.");
67 			break;
68 		case ERROR_CODE_AUTHORIZATIONFAILURE:
69 		case ERROR_CODE_AUTHORIZATIONRULECONFLICT:
70 			alertText = B_TRANSLATE("Authorization or security issue");
71 			break;
72 		default:
73 			alertText.SetToFormat(
74 				B_TRANSLATE("An unexpected error has been sent from the"
75 					" HaikuDepot server [%" B_PRIi32 "]"), errorCode);
76 			break;
77 	}
78 
79 	BAlert* alert = new BAlert(
80 		B_TRANSLATE("Server Error"),
81 		alertText,
82 		B_TRANSLATE("OK"));
83 
84 	alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
85 	alert->Go();
86 }
87 
88 
89 /*static*/ void
90 ServerHelper::NotifyTransportError(status_t error)
91 {
92 	switch (error) {
93 		case HD_CLIENT_TOO_OLD:
94 				// this is handled earlier on because it requires some
95 				// information from the HTTP request to create a sensible
96 				// error message.
97 			break;
98 
99 		default:
100 		{
101 			BMessage message(MSG_NETWORK_TRANSPORT_ERROR);
102 			message.AddInt64("errno", (int64) error);
103 			be_app->PostMessage(&message);
104 			break;
105 		}
106 	}
107 }
108 
109 
110 /*static*/ void
111 ServerHelper::AlertTransportError(BMessage* message)
112 {
113 	status_t errno = B_OK;
114 	int64 errnoInt64;
115 	message->FindInt64("errno", &errnoInt64);
116 	errno = (status_t) errnoInt64;
117 
118 	BString errorDescription("?");
119 	BString alertText;
120 
121 	switch (errno) {
122 		case HD_NETWORK_INACCESSIBLE:
123 			errorDescription = B_TRANSLATE("Network Error");
124 			break;
125 		default:
126 			errorDescription.SetTo(strerror(errno));
127 			break;
128 	}
129 
130 	alertText.SetToFormat(B_TRANSLATE("A network transport error has arisen"
131 		" communicating with the HaikuDepot server system: %s"),
132 		errorDescription.String());
133 
134 	BAlert* alert = new BAlert(
135 		B_TRANSLATE("Network Transport Error"),
136 		alertText,
137 		B_TRANSLATE("OK"));
138 
139 	alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
140 	alert->Go();
141 }
142 
143 
144 /*static*/ void
145 ServerHelper::NotifyClientTooOld(const BHttpHeaders& responseHeaders)
146 {
147 	if (!ServerSettings::IsClientTooOld()) {
148 		ServerSettings::SetClientTooOld();
149 
150 		const char* minimumVersionC = responseHeaders[KEY_HEADER_MINIMUM_VERSION];
151 		BMessage message(MSG_CLIENT_TOO_OLD);
152 
153 		if (minimumVersionC != NULL && strlen(minimumVersionC) != 0) {
154 			message.AddString(KEY_MSG_MINIMUM_VERSION, minimumVersionC);
155 		}
156 
157 		be_app->PostMessage(&message);
158 	}
159 }
160 
161 
162 /*static*/ void
163 ServerHelper::AlertClientTooOld(BMessage* message)
164 {
165 	BString minimumVersion;
166 	BString alertText;
167 
168 	if (message->FindString(KEY_MSG_MINIMUM_VERSION, &minimumVersion) != B_OK)
169 		minimumVersion = "???";
170 
171 	alertText.SetToFormat(
172 		B_TRANSLATE("This application is too old to communicate with the "
173 			" HaikuDepot server system.  Obtain a newer version of HaikuDepot "
174 			" by updating your Haiku system.  The minimum version of "
175 			" HaikuDepot required is \"%s\"."), minimumVersion.String());
176 
177 	BAlert* alert = new BAlert(
178 		B_TRANSLATE("Client version too old"),
179 		alertText,
180 		B_TRANSLATE("OK"));
181 
182 	alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
183 	alert->Go();
184 }
185 
186 
187 /*static*/ bool
188 ServerHelper::IsNetworkAvailable()
189 {
190 	return !ServerSettings::ForceNoNetwork() && IsPlatformNetworkAvailable();
191 }
192 
193 
194 /*static*/ bool
195 ServerHelper::IsPlatformNetworkAvailable()
196 {
197 	BNetworkRoster& roster = BNetworkRoster::Default();
198 	BNetworkInterface interface;
199 	uint32 cookie = 0;
200 	while (roster.GetNextInterface(&cookie, interface) == B_OK) {
201 		uint32 flags = interface.Flags();
202 		if ((flags & IFF_LOOPBACK) == 0
203 			&& (flags & (IFF_UP | IFF_LINK)) == (IFF_UP | IFF_LINK)) {
204 			return true;
205 		}
206 	}
207 
208 	return false;
209 }