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 }