Line data Source code
1 : #include "otsdaq/WebUsersUtilities/RemoteWebUsers.h"
2 :
3 : #include "otsdaq/CgiDataUtilities/CgiDataUtilities.h"
4 : #include "otsdaq/SOAPUtilities/SOAPCommand.h"
5 : #include "otsdaq/SOAPUtilities/SOAPParameters.h" //must include in .h for static function
6 : #include "otsdaq/SOAPUtilities/SOAPUtilities.h"
7 : #include "otsdaq/XmlUtilities/HttpXmlDocument.h"
8 :
9 : #include <cstdio>
10 : #include <cstdlib>
11 : #include <tuple>
12 : #include <vector>
13 :
14 : #include "otsdaq/SupervisorInfo/AllSupervisorInfo.h"
15 :
16 : using namespace ots;
17 :
18 : #undef __MF_SUBJECT__
19 : #define __MF_SUBJECT__ "RemoteWebUsers"
20 :
21 : //==============================================================================
22 : /// User Notes:
23 : /// - use xmlRequestGateway to check security from outside the Supervisor and Wizard
24 : ///
25 : /// Example usage: at void CoreSupervisorBase::requestWrapper(xgi::Input* in, xgi::Output* out)
26 : ///
27 : ///
28 : ///
29 : //==============================================================================
30 0 : RemoteWebUsers::RemoteWebUsers(
31 : xdaq::Application* application,
32 0 : XDAQ_CONST_CALL xdaq::ApplicationDescriptor* gatewaySupervisorDescriptor)
33 : : SOAPMessenger(application)
34 0 : , gatewaySupervisorDescriptor_(gatewaySupervisorDescriptor)
35 : {
36 0 : ActiveUserLastUpdateTime_ = 0; // init to never
37 0 : ActiveUserList_ = ""; // init to empty
38 0 : } // end constructor()
39 :
40 : //==============================================================================
41 : /// xmlRequestGateway
42 : /// if false, user code should just return.. out is handled on false; on true, out is
43 : /// untouched
44 0 : bool RemoteWebUsers::xmlRequestToGateway(cgicc::Cgicc& cgi,
45 : std::ostringstream* out,
46 : HttpXmlDocument* xmldoc,
47 : const AllSupervisorInfo& allSupervisorInfo,
48 : WebUsers::RequestUserInfo& userInfo)
49 : {
50 : //__COUT__ << std::endl;
51 : // initialize user info parameters to failed results
52 0 : WebUsers::initializeRequestUserInfo(cgi, userInfo);
53 :
54 : XDAQ_CONST_CALL xdaq::ApplicationDescriptor* gatewaySupervisor;
55 :
56 0 : SOAPParameters parameters;
57 0 : xoap::MessageReference retMsg;
58 :
59 : //**** start LOGIN GATEWAY CODE ***//
60 : // If TRUE, cookie code is good, and refreshed code is in cookieCode
61 : // Else, error message is returned in cookieCode
62 :
63 : /////////////////////////////////////////////////////
64 : // if Wiz or Macormaker mode, use sequence instead of cookieCode
65 0 : if(allSupervisorInfo.isWizardMode() || allSupervisorInfo.isMacroMakerMode())
66 : {
67 : // if missing CookieCode... check if in Wizard mode and using sequence
68 : std::string sequence =
69 0 : CgiDataUtilities::getOrPostData(cgi, "sequence"); // from GET or POST
70 : //__COUT__ << "sequence=" << sequence << std::endl;
71 0 : if(!sequence.length())
72 : {
73 0 : __COUT_ERR__ << "Invalid access attempt (@" << userInfo.ip_ << ")."
74 0 : << std::endl;
75 0 : *out << WebUsers::REQ_NO_LOGIN_RESPONSE;
76 : // invalid cookie and also invalid sequence
77 0 : goto HANDLE_ACCESS_FAILURE; // return false, access failed
78 : }
79 :
80 : // have sequence, try it out
81 :
82 0 : if(allSupervisorInfo.isWizardMode())
83 0 : gatewaySupervisor = allSupervisorInfo.getWizardInfo().getDescriptor();
84 : else //is MacroMaker mode
85 0 : gatewaySupervisor = allSupervisorInfo.getAllMacroMakerTypeSupervisorInfo()
86 0 : .begin()
87 0 : ->second.getDescriptor();
88 :
89 0 : if(!gatewaySupervisor)
90 : {
91 0 : __COUT_ERR__ << "Missing gateway supervisor." << std::endl;
92 0 : *out << WebUsers::REQ_NO_LOGIN_RESPONSE;
93 : // sequence code present, but no wizard supervisor
94 0 : goto HANDLE_ACCESS_FAILURE; // return false, access failed
95 : }
96 :
97 0 : parameters.addParameter("sequence", sequence);
98 0 : parameters.addParameter("IPAddress", userInfo.ip_);
99 0 : retMsg = SOAPMessenger::sendWithSOAPReply(
100 0 : gatewaySupervisor, "SupervisorSequenceCheck", parameters);
101 0 : parameters.clear();
102 0 : parameters.addParameter("Permissions");
103 0 : SOAPUtilities::receive(retMsg, parameters);
104 :
105 0 : userInfo.setGroupPermissionLevels(parameters.getValue("Permissions"));
106 :
107 0 : if(WebUsers::checkRequestAccess(
108 : cgi, out, xmldoc, userInfo, true /*isWizardMode*/, sequence))
109 0 : return true; //successful sequence login!
110 : else
111 0 : goto HANDLE_ACCESS_FAILURE; // return false, access failed
112 0 : } //end Wiz or Macormaker mode
113 :
114 : // else proceed with inquiry to Gateway Supervisor
115 :
116 0 : gatewaySupervisor = allSupervisorInfo.getGatewayInfo().getDescriptor();
117 :
118 0 : if(!gatewaySupervisor)
119 : {
120 0 : __COUT_ERR__ << "Missing gateway supervisor." << std::endl;
121 0 : *out << WebUsers::REQ_NO_LOGIN_RESPONSE;
122 0 : goto HANDLE_ACCESS_FAILURE; // return false, access failed
123 : }
124 :
125 0 : parameters.clear();
126 0 : parameters.addParameter("CookieCode", userInfo.cookieCode_);
127 0 : parameters.addParameter("RefreshOption", userInfo.automatedCommand_ ? "0" : "1");
128 0 : parameters.addParameter("IPAddress", userInfo.ip_);
129 0 : parameters.addParameter("RequireLock", userInfo.requireLock_ ? "1" : "0");
130 :
131 0 : retMsg = SOAPMessenger::sendWithSOAPReply(
132 0 : gatewaySupervisor, "SupervisorCookieCheck", parameters);
133 :
134 0 : parameters.clear();
135 0 : parameters.addParameter("CookieCode");
136 0 : parameters.addParameter("Permissions");
137 0 : parameters.addParameter("UserGroups");
138 0 : parameters.addParameter("UserWithLock");
139 0 : parameters.addParameter("Username");
140 0 : parameters.addParameter("DisplayName");
141 : // parameters.addParameter("ActiveSessionIndex");
142 0 : SOAPUtilities::receive(retMsg, parameters);
143 :
144 : // first extract a few things always from parameters
145 : // like permissionLevel for this request... must consider allowed groups!!
146 0 : userInfo.setGroupPermissionLevels(parameters.getValue("Permissions"));
147 0 : userInfo.cookieCode_ = parameters.getValue("CookieCode");
148 0 : userInfo.username_ = parameters.getValue("Username");
149 0 : userInfo.displayName_ = parameters.getValue("DisplayName");
150 0 : userInfo.usernameWithLock_ = parameters.getValue("UserWithLock");
151 : // userInfo.activeUserSessionIndex_ = strtoul(parameters.getValue("ActiveSessionIndex").c_str(), 0, 0);
152 :
153 0 : if(!WebUsers::checkRequestAccess(cgi, out, xmldoc, userInfo))
154 0 : goto HANDLE_ACCESS_FAILURE; // return false, access failed
155 : // else successful access request!
156 :
157 0 : return true; // request granted
158 :
159 : /////////////////////////////////////////////////////
160 :
161 0 : HANDLE_ACCESS_FAILURE:
162 :
163 : // print out return string on failure
164 0 : if(!userInfo.automatedCommand_)
165 0 : __COUT_ERR__ << "Failed request (requestType = " << userInfo.requestType_
166 0 : << "): " << out->str() << __E__;
167 0 : return false; // access failed
168 0 : } // end xmlRequestToGateway()
169 :
170 : //==============================================================================
171 : /// getActiveUserList
172 : /// if lastUpdateTime is not too recent as spec'd by ACTIVE_USERS_UPDATE_THRESHOLD
173 : /// if server responds with
174 0 : std::string RemoteWebUsers::getActiveUserList()
175 : {
176 0 : if(time(0) - ActiveUserLastUpdateTime_ >
177 : ACTIVE_USERS_UPDATE_THRESHOLD) // need to update
178 : {
179 0 : __COUTS__(2) << "Need to update active user list" << std::endl;
180 :
181 : xoap::MessageReference retMsg = ots::SOAPMessenger::sendWithSOAPReply(
182 0 : gatewaySupervisorDescriptor_, "SupervisorGetActiveUsers");
183 :
184 0 : SOAPParameters retParameters("UserList");
185 0 : SOAPUtilities::receive(retMsg, retParameters);
186 :
187 0 : ActiveUserLastUpdateTime_ = time(0);
188 0 : return (ActiveUserList_ = retParameters.getValue("UserList"));
189 0 : }
190 : else
191 0 : return ActiveUserList_;
192 : } // end getActiveUserList()
193 :
194 : //==============================================================================
195 : /// getLastTableGroups
196 : /// request last "Configured" or "Started" group, for example
197 : /// returns empty "" for actionTimeString on failure
198 : /// returns "Wed Dec 31 18:00:01 1969 CST" for actionTimeString (in CST) if action never
199 : /// has occurred
200 0 : void RemoteWebUsers::getLastTableGroups(
201 : std::map<std::string /* group type */,
202 : std::tuple<std::string /*group name*/,
203 : TableGroupKey,
204 : std::string /* time string*/>>& theGroups)
205 : {
206 : xoap::MessageReference retMsg =
207 : ots::SOAPMessenger::sendWithSOAPReply(gatewaySupervisorDescriptor_,
208 : "SupervisorLastTableGroupRequest",
209 0 : SOAPParameters("ActionOfLastGroup", "ALL"));
210 :
211 0 : SOAPParameters retParameters;
212 0 : retParameters.addParameter("GroupName");
213 0 : retParameters.addParameter("GroupKey");
214 0 : retParameters.addParameter("GroupAction");
215 0 : retParameters.addParameter("GroupActionTime");
216 0 : SOAPUtilities::receive(retMsg, retParameters);
217 :
218 : //parse as CSV
219 : std::vector<std::string> groupNames =
220 0 : StringMacros::getVectorFromString(retParameters.getValue("GroupName"), {','});
221 : std::vector<std::string> groupKeys =
222 0 : StringMacros::getVectorFromString(retParameters.getValue("GroupKey"), {','});
223 : std::vector<std::string> groupActions =
224 0 : StringMacros::getVectorFromString(retParameters.getValue("GroupAction"), {','});
225 : std::vector<std::string> groupTimes = StringMacros::getVectorFromString(
226 0 : retParameters.getValue("GroupActionTime"), {','});
227 :
228 0 : if(groupNames.size() < 2)
229 : {
230 : //expecting something like 7?
231 0 : __SS__ << "Failure in handling request for recent config group activity. "
232 0 : "Response received was this: \n"
233 0 : << SOAPUtilities::translate(retMsg) << __E__;
234 0 : __SS_THROW__;
235 0 : }
236 :
237 0 : if(groupNames.size() != groupKeys.size() ||
238 0 : groupNames.size() != groupActions.size() || groupNames.size() != groupTimes.size())
239 : {
240 0 : __SS__ << "Illegal list size mismatch while retrieving recent config group info. "
241 0 : "Should not be possible! Notify admins."
242 0 : << __E__;
243 0 : __SS_THROW__;
244 0 : }
245 :
246 0 : for(size_t i = 0; i < groupNames.size(); ++i)
247 : {
248 0 : theGroups[groupActions[i]] = std::make_tuple(
249 0 : groupNames[i], strtol(groupKeys[i].c_str(), 0, 0), groupTimes[i]);
250 : }
251 :
252 0 : __COUTT__ << "Done with getLastTableGroups()" << __E__;
253 0 : } // end getLastTableGroup()
254 :
255 : //==============================================================================
256 : /// getLastTableGroup
257 : /// request last "Configured" or "Started" group, for example
258 : /// returns empty "" for actionTimeString on failure
259 : /// returns "Wed Dec 31 18:00:01 1969 CST" for actionTimeString (in CST) if action never
260 : /// has occurred
261 0 : std::pair<std::string /*group name*/, TableGroupKey> RemoteWebUsers::getLastTableGroup(
262 : const std::string& actionOfLastGroup, std::string& actionTimeString)
263 : {
264 0 : actionTimeString = "";
265 : xoap::MessageReference retMsg = ots::SOAPMessenger::sendWithSOAPReply(
266 : gatewaySupervisorDescriptor_,
267 : "SupervisorLastTableGroupRequest",
268 0 : SOAPParameters("ActionOfLastGroup", actionOfLastGroup));
269 :
270 0 : SOAPParameters retParameters;
271 0 : retParameters.addParameter("GroupName");
272 0 : retParameters.addParameter("GroupKey");
273 0 : retParameters.addParameter("GroupAction");
274 0 : retParameters.addParameter("GroupActionTime");
275 0 : SOAPUtilities::receive(retMsg, retParameters);
276 :
277 0 : std::pair<std::string /*group name*/, TableGroupKey> theGroup;
278 0 : if(retParameters.getValue("GroupAction") !=
279 0 : actionOfLastGroup) // if action doesn't match.. weird
280 : {
281 0 : __SS__ << "Returned group action '" << retParameters.getValue("GroupAction")
282 0 : << "' does not match requested group action '" << actionOfLastGroup << ".'"
283 0 : << std::endl;
284 0 : __SS_THROW__;
285 0 : }
286 : // else we have an action match
287 :
288 0 : theGroup.first = retParameters.getValue("GroupName");
289 0 : theGroup.second = strtol(retParameters.getValue("GroupKey").c_str(), 0, 0);
290 0 : actionTimeString = retParameters.getValue("GroupActionTime");
291 0 : return theGroup;
292 0 : } // end getLastTableGroup()
293 :
294 : //==============================================================================
295 : /// sendSystemMessage
296 : /// send system message to toUser through Supervisor
297 : /// toUser wild card * is to all users
298 0 : void RemoteWebUsers::sendSystemMessage(const std::string& toUser,
299 : const std::string& message,
300 : bool doEmail /*=false*/)
301 : {
302 0 : sendSystemMessage(toUser, "" /*subject*/, message, doEmail);
303 0 : } // end sendSystemMessage)
304 :
305 : //==============================================================================
306 : /// sendSystemMessage
307 : /// send system message to toUser comma separate variable (CSV) list through Supervisor
308 : /// toUser wild card * is to all users
309 0 : void RemoteWebUsers::sendSystemMessage(const std::string& toUser,
310 : const std::string& subject,
311 : const std::string& message,
312 : bool doEmail /*=false*/)
313 : {
314 0 : SOAPParameters parameters;
315 0 : parameters.addParameter("ToUser", toUser); // CSV list or *
316 0 : parameters.addParameter("Subject", subject);
317 0 : parameters.addParameter("Message", message);
318 0 : parameters.addParameter("DoEmail", doEmail ? "1" : "0");
319 :
320 : xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
321 0 : gatewaySupervisorDescriptor_, "SupervisorSystemMessage", parameters);
322 :
323 : //__COUT__ << SOAPUtilities::translate(retMsg) << __E__;
324 0 : } // end sendSystemMessage)
325 :
326 : //==============================================================================
327 : /// makeSystemLogEntry
328 : /// make system logbook through Supervisor
329 0 : void RemoteWebUsers::makeSystemLogEntry(const std::string& entryText)
330 : {
331 0 : SOAPParameters parameters;
332 0 : parameters.addParameter("EntryText", entryText);
333 :
334 : xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
335 0 : gatewaySupervisorDescriptor_, "SupervisorSystemLogbookEntry", parameters);
336 :
337 : //__COUT__ << SOAPUtilities::translate(retMsg) << __E__;
338 0 : } // end makeSystemLogEntry()
|