1 /* 2 * Copyright 2020, Andrew Lindesay <apl@lindesay.co.nz>. 3 * All rights reserved. Distributed under the terms of the MIT License. 4 */ 5 6 #include "UserDetailVerifierProcess.h" 7 8 #include <AutoLocker.h> 9 #include <Catalog.h> 10 #include <Window.h> 11 12 #include "AppUtils.h" 13 #include "HaikuDepotConstants.h" 14 #include "Logger.h" 15 #include "ServerHelper.h" 16 17 #undef B_TRANSLATION_CONTEXT 18 #define B_TRANSLATION_CONTEXT "UserDetailVerifierProcess" 19 20 21 UserDetailVerifierProcess::UserDetailVerifierProcess(Model* model, 22 UserDetailVerifierListener* listener) 23 : 24 fModel(model), 25 fListener(listener) 26 { 27 } 28 29 30 UserDetailVerifierProcess::~UserDetailVerifierProcess() 31 { 32 } 33 34 35 const char* 36 UserDetailVerifierProcess::Name() const 37 { 38 return "UserDetailVerifierProcess"; 39 } 40 41 42 const char* 43 UserDetailVerifierProcess::Description() const 44 { 45 return B_TRANSLATE("Checking user details"); 46 } 47 48 49 status_t 50 UserDetailVerifierProcess::RunInternal() 51 { 52 status_t result = B_OK; 53 54 if (_ShouldVerify()) { 55 UserDetail userDetail; 56 result = _TryFetchUserDetail(userDetail); 57 58 switch (result) { 59 case B_PERMISSION_DENIED: 60 fListener->UserCredentialsFailed(); 61 result = B_OK; 62 break; 63 case B_OK: 64 if (!userDetail.Agreement().IsLatest()) { 65 HDINFO("the user has not agreed to the latest user usage" 66 " conditions."); 67 fListener->UserUsageConditionsNotLatest(userDetail); 68 } 69 break; 70 default: 71 break; 72 } 73 } 74 75 return result; 76 } 77 78 79 bool 80 UserDetailVerifierProcess::_ShouldVerify() 81 { 82 if (!ServerHelper::IsNetworkAvailable()) { 83 HDINFO("no network --> will not verify user"); 84 return false; 85 } 86 87 { 88 AutoLocker<BLocker> locker(fModel->Lock()); 89 if (fModel->Nickname().IsEmpty()) { 90 HDINFO("no nickname --> will not verify user"); 91 return false; 92 } 93 } 94 95 return true; 96 } 97 98 99 status_t 100 UserDetailVerifierProcess::_TryFetchUserDetail(UserDetail& userDetail) 101 { 102 WebAppInterface interface = fModel->GetWebAppInterface(); 103 BMessage userDetailResponse; 104 status_t result; 105 106 result = interface.RetrieveCurrentUserDetail(userDetailResponse); 107 if (result != B_OK) { 108 HDERROR("a problem has arisen retrieving the current user detail: %s", 109 strerror(result)); 110 } 111 112 if (result == B_OK) { 113 int32 errorCode = interface.ErrorCodeFromResponse(userDetailResponse); 114 switch (errorCode) { 115 case ERROR_CODE_NONE: 116 break; 117 case ERROR_CODE_AUTHORIZATIONFAILURE: 118 result = B_PERMISSION_DENIED; 119 break; 120 default: 121 HDERROR("a problem has arisen retrieving the current user " 122 "detail for user [%s]: jrpc error code %" B_PRId32 "", 123 fModel->Nickname().String(), errorCode); 124 result = B_ERROR; 125 break; 126 } 127 } 128 129 if (result == B_OK) { 130 131 // now we have the user details by showing that an authentication has 132 // worked, it is now necessary to check to see that the user has agreed 133 // to the most recent user-usage conditions. 134 135 result = interface.UnpackUserDetail(userDetailResponse, userDetail); 136 if (result != B_OK) 137 HDERROR("it was not possible to unpack the user details."); 138 } 139 140 return result; 141 }