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 }