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