xref: /haiku/src/apps/haikudepot/server/UserDetailVerifierProcess.cpp (revision 3634f142352af2428aed187781fc9d75075e9140)
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 
108 	if (result != B_OK) {
109 		HDERROR("a problem has arisen retrieving the current user detail: %s",
110 			strerror(result));
111 	}
112 
113 	if (result == B_OK) {
114 		int32 errorCode = WebAppInterface::ErrorCodeFromResponse(userDetailResponse);
115 		switch (errorCode) {
116 			case ERROR_CODE_NONE:
117 				break;
118 			case ERROR_CODE_AUTHORIZATIONFAILURE:
119 				result = B_PERMISSION_DENIED;
120 				break;
121 			default:
122 				HDERROR("a problem has arisen retrieving the current user "
123 					"detail for user [%s]: jrpc error code %" B_PRId32 "",
124 					fModel->Nickname().String(), errorCode);
125 				result = B_ERROR;
126 				break;
127 		}
128 	}
129 
130 	if (result == B_OK) {
131 
132 		// now we have the user details by showing that an authentication has
133 		// worked, it is now necessary to check to see that the user has agreed
134 		// to the most recent user-usage conditions.
135 
136 		result = interface->UnpackUserDetail(userDetailResponse, userDetail);
137 		if (result != B_OK)
138 			HDERROR("it was not possible to unpack the user details.");
139 	}
140 
141 	return result;
142 }