xref: /haiku/src/apps/haikudepot/server/UserDetailVerifierProcess.cpp (revision 17889a8c70dbb3d59c1412f6431968753c767bab)
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 }