$treeview $search $mathjax $extrastylesheet
otsdaq
v2_03_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #include "otsdaq-core/WizardSupervisor/WizardSupervisor.h" 00002 00003 #include "otsdaq-core/GatewaySupervisor/GatewaySupervisor.h" 00004 00005 #include "otsdaq-core/Macros/CoutMacros.h" 00006 #include "otsdaq-core/MessageFacility/MessageFacility.h" 00007 00008 #include <xdaq/NamespaceURI.h> 00009 #include "otsdaq-core/CgiDataUtilities/CgiDataUtilities.h" 00010 #include "otsdaq-core/SOAPUtilities/SOAPCommand.h" 00011 #include "otsdaq-core/SOAPUtilities/SOAPUtilities.h" 00012 #include "otsdaq-core/WebUsersUtilities/WebUsers.h" 00013 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h" 00014 00015 #include <dirent.h> //for DIR 00016 #include <sys/stat.h> // mkdir 00017 #include <chrono> // std::chrono::seconds 00018 #include <fstream> 00019 #include <iostream> 00020 #include <string> 00021 #include <thread> // std::this_thread::sleep_for 00022 00023 using namespace ots; 00024 00025 #define SECURITY_FILE_NAME \ 00026 std::string(getenv("SERVICE_DATA_PATH")) + "/OtsWizardData/security.dat" 00027 #define SEQUENCE_FILE_NAME \ 00028 std::string(getenv("SERVICE_DATA_PATH")) + "/OtsWizardData/sequence.dat" 00029 #define SEQUENCE_OUT_FILE_NAME \ 00030 std::string(getenv("SERVICE_DATA_PATH")) + "/OtsWizardData/sequence.out" 00031 #define USER_DATA_PATH std::string(getenv("SERVICE_DATA_PATH")) + std::string("/") 00032 //#define LOGBOOK_PREVIEWS_PATH "uploads/" 00033 00034 #define XML_STATUS "editUserData_status" 00035 00036 #define XML_ADMIN_STATUS "logbook_admin_status" 00037 #define XML_MOST_RECENT_DAY "most_recent_day" 00038 #define XML_EXPERIMENTS_ROOT "experiments" 00039 #define XML_EXPERIMENT "experiment" 00040 #define XML_ACTIVE_EXPERIMENT "active_experiment" 00041 #define XML_EXPERIMENT_CREATE "create_time" 00042 #define XML_EXPERIMENT_CREATOR "creator" 00043 00044 #define XML_LOGBOOK_ENTRY "logbook_entry" 00045 #define XML_LOGBOOK_ENTRY_SUBJECT "logbook_entry_subject" 00046 #define XML_LOGBOOK_ENTRY_TEXT "logbook_entry_text" 00047 #define XML_LOGBOOK_ENTRY_FILE "logbook_entry_file" 00048 #define XML_LOGBOOK_ENTRY_TIME "logbook_entry_time" 00049 #define XML_LOGBOOK_ENTRY_CREATOR "logbook_entry_creator" 00050 #define XML_LOGBOOK_ENTRY_HIDDEN "logbook_entry_hidden" 00051 #define XML_LOGBOOK_ENTRY_HIDER "logbook_entry_hider" 00052 #define XML_LOGBOOK_ENTRY_HIDDEN_TIME "logbook_entry_hidden_time" 00053 00054 #define XML_PREVIEW_INDEX "preview_index" 00055 #define LOGBOOK_PREVIEW_FILE "preview.xml" 00056 00057 XDAQ_INSTANTIATOR_IMPL(WizardSupervisor) 00058 00059 #undef __MF_SUBJECT__ 00060 #define __MF_SUBJECT__ "Wizard" 00061 00062 //======================================================================================================================== 00063 WizardSupervisor::WizardSupervisor(xdaq::ApplicationStub* s) throw( 00064 xdaq::exception::Exception) 00065 : xdaq::Application(s) 00066 , SOAPMessenger(this) 00067 , supervisorClass_(getApplicationDescriptor()->getClassName()) 00068 , supervisorClassNoNamespace_(supervisorClass_.substr( 00069 supervisorClass_.find_last_of(":") + 1, 00070 supervisorClass_.length() - supervisorClass_.find_last_of(":"))) 00071 { 00072 __COUT__ << "Constructor started." << __E__; 00073 00074 INIT_MF("OtsConfigurationWizard"); 00075 00076 // attempt to make directory structure (just in case) 00077 mkdir((std::string(getenv("SERVICE_DATA_PATH"))).c_str(), 0755); 00078 mkdir((std::string(getenv("SERVICE_DATA_PATH")) + "/OtsWizardData").c_str(), 0755); 00079 00080 GatewaySupervisor::indicateOtsAlive(); 00081 00082 generateURL(); 00083 xgi::bind(this, &WizardSupervisor::Default, "Default"); 00084 xgi::bind(this, &WizardSupervisor::verification, "Verify"); 00085 xgi::bind(this, &WizardSupervisor::request, "Request"); 00086 xgi::bind(this, &WizardSupervisor::requestIcons, "requestIcons"); 00087 xgi::bind(this, &WizardSupervisor::editSecurity, "editSecurity"); 00088 xgi::bind(this, &WizardSupervisor::UserSettings, "UserSettings"); 00089 xgi::bind(this, &WizardSupervisor::tooltipRequest, "TooltipRequest"); 00090 xgi::bind(this, 00091 &WizardSupervisor::toggleSecurityCodeGeneration, 00092 "ToggleSecurityCodeGeneration"); 00093 xoap::bind(this, 00094 &WizardSupervisor::supervisorSequenceCheck, 00095 "SupervisorSequenceCheck", 00096 XDAQ_NS_URI); 00097 xoap::bind(this, 00098 &WizardSupervisor::supervisorLastConfigGroupRequest, 00099 "SupervisorLastConfigGroupRequest", 00100 XDAQ_NS_URI); 00101 init(); 00102 00103 __COUT__ << "Constructor complete." << __E__; 00104 } 00105 00106 //======================================================================================================================== 00107 WizardSupervisor::~WizardSupervisor(void) { destroy(); } 00108 00109 //======================================================================================================================== 00110 void WizardSupervisor::init(void) 00111 { 00112 // getApplicationContext(); 00113 00114 // init allowed file upload types 00115 allowedFileUploadTypes_.push_back("image/png"); 00116 matchingFileUploadTypes_.push_back("png"); 00117 allowedFileUploadTypes_.push_back("image/jpeg"); 00118 matchingFileUploadTypes_.push_back("jpeg"); 00119 allowedFileUploadTypes_.push_back("image/gif"); 00120 matchingFileUploadTypes_.push_back("gif"); 00121 allowedFileUploadTypes_.push_back("image/bmp"); 00122 matchingFileUploadTypes_.push_back("bmp"); 00123 allowedFileUploadTypes_.push_back("application/pdf"); 00124 matchingFileUploadTypes_.push_back("pdf"); 00125 allowedFileUploadTypes_.push_back("application/zip"); 00126 matchingFileUploadTypes_.push_back("zip"); 00127 allowedFileUploadTypes_.push_back("text/plain"); 00128 matchingFileUploadTypes_.push_back("txt"); 00129 } 00130 00131 //======================================================================================================================== 00132 void WizardSupervisor::requestIcons(xgi::Input* in, 00133 xgi::Output* out) throw(xgi::exception::Exception) 00134 { 00135 cgicc::Cgicc cgi(in); 00136 00137 std::string submittedSequence = CgiDataUtilities::postData(cgi, "sequence"); 00138 00139 // SECURITY CHECK START **** 00140 if(securityCode_.compare(submittedSequence) != 0) 00141 { 00142 __COUT__ << "Unauthorized Request made, security sequence doesn't match! " 00143 << time(0) << std::endl; 00144 return; 00145 } 00146 else 00147 { 00148 __COUT__ << "***Successfully authenticated security sequence. " << time(0) 00149 << std::endl; 00150 } 00151 // SECURITY CHECK END **** 00152 00153 // an icon is 7 fields.. give comma-separated 00154 // 0 - subtext = text below icon 00155 // 1 - altText = text for icon if image set to 0 00156 // 2 - uniqueWin = if true, only one window is allowed, else multiple instances of 00157 // window 3 - permissions = security level needed to see icon 4 - picfn = icon image 00158 // filename, 0 for no image 5 - linkurl = url of the window to open 6 - folderPath = 00159 // folder and subfolder location 00160 00161 *out << "Configure,CFG,0,1,icon-Configure.png,/urn:xdaq-application:lid=280/,/" 00162 << ",Table " 00163 "Editor,TBL,0,1,icon-IconEditor.png,/urn:xdaq-application:lid=280/" 00164 "?configWindowName=tableEditor,/" 00165 << ",Security " 00166 "Settings,SEC,1,1,icon-SecuritySettings.png,/WebPath/html/" 00167 "SecuritySettings.html,/User Settings" 00168 << ",Edit User " 00169 "Data,USER,1,1,icon-EditUserData.png,/WebPath/html/EditUserData.html,/User " 00170 "Settings" 00171 << 00172 00173 ",Console,C,1,1,icon-Console.png,/urn:xdaq-application:lid=260/,/" << 00174 00175 //",Iterate,IT,0,1,icon-Iterate.png,/urn:xdaq-application:lid=280/?configWindowName=iterate,/" 00176 //<< 00177 //",Configure,CFG,0,1,icon-Configure.png,/urn:xdaq-application:lid=280/,myFolder" 00178 //<< 00179 //",Configure,CFG,0,1,icon-Configure.png,/urn:xdaq-application:lid=280/,/myFolder/mySub.folder" 00180 //<< 00181 //",Configure,CFG,0,1,icon-Configure.png,/urn:xdaq-application:lid=280/,myFolder/" 00182 //<< 00183 ",Front-end " 00184 "Wizard,CFG,0,1,icon-Configure.png,/WebPath/html/" 00185 "RecordWiz_ConfigurationGUI.html?urn=280&recordAlias=Front%2Dend,Config Wizards" 00186 << ",Processor " 00187 "Wizard,CFG,0,1,icon-Configure.png,/WebPath/html/" 00188 "RecordWiz_ConfigurationGUI.html?urn=280&recordAlias=Processor,Config Wizards" 00189 << ",Block " 00190 "Diagram,CFG,0,1,icon-Configure.png,/WebPath/html/" 00191 "ConfigurationSubsetBlockDiagram.html?urn=280,Config Wizards" 00192 << 00193 //",Consumer 00194 // Wizard,CFG,0,1,icon-Configure.png,/WebPath/html/RecordWiz_ConfigurationGUI.html?urn=280&subsetBasePath=FEInterfaceConfiguration&recordAlias=Consumer,Config 00195 // Wizards" << 00196 00197 //",DB Utilities,DB,1,1,0,http://127.0.0.1:8080/db/client.html" << 00198 00199 ",Code Editor,CODE,0,1,icon-CodeEditor.png,/urn:xdaq-application:lid=240/,/" 00200 //",Code Editor,CODE,0,1,icon-CodeEditor.png,/WebPath/html/CodeEditor.html,/" 00201 << ""; 00202 return; 00203 } // end requestIcons() 00204 00205 //======================================================================================================================== 00206 void WizardSupervisor::verification(xgi::Input* in, 00207 xgi::Output* out) throw(xgi::exception::Exception) 00208 { 00209 cgicc::Cgicc cgi(in); 00210 std::string submittedSequence = CgiDataUtilities::getData(cgi, "code"); 00211 __COUT__ << "submittedSequence=" << submittedSequence << " " << time(0) << std::endl; 00212 00213 std::string securityWarning = ""; 00214 00215 if(securityCode_.compare(submittedSequence) != 0) 00216 { 00217 __COUT__ << "Unauthorized Request made, security sequence doesn't match!" 00218 << std::endl; 00219 *out << "Invalid code."; 00220 return; 00221 } 00222 else 00223 { 00224 // defaultSequence_ = false; 00225 __COUT__ << "*** Successfully authenticated security sequence " 00226 << "@ " << time(0) << std::endl; 00227 00228 if(defaultSequence_) 00229 { 00230 //__COUT__ << " UNSECURE!!!" << std::endl; 00231 securityWarning = "&secure=False"; 00232 } 00233 } 00234 00235 *out << "<!DOCTYPE HTML><html lang='en'><head><title>ots wiz</title>" << 00236 // show ots icon 00237 // from http://www.favicon-generator.org/ 00238 "<link rel='apple-touch-icon' sizes='57x57' href='/WebPath/images/otsdaqIcons/apple-icon-57x57.png'>\ 00239 <link rel='apple-touch-icon' sizes='60x60' href='/WebPath/images/otsdaqIcons/apple-icon-60x60.png'>\ 00240 <link rel='apple-touch-icon' sizes='72x72' href='/WebPath/images/otsdaqIcons/apple-icon-72x72.png'>\ 00241 <link rel='apple-touch-icon' sizes='76x76' href='/WebPath/images/otsdaqIcons/apple-icon-76x76.png'>\ 00242 <link rel='apple-touch-icon' sizes='114x114' href='/WebPath/images/otsdaqIcons/apple-icon-114x114.png'>\ 00243 <link rel='apple-touch-icon' sizes='120x120' href='/WebPath/images/otsdaqIcons/apple-icon-120x120.png'>\ 00244 <link rel='apple-touch-icon' sizes='144x144' href='/WebPath/images/otsdaqIcons/apple-icon-144x144.png'>\ 00245 <link rel='apple-touch-icon' sizes='152x152' href='/WebPath/images/otsdaqIcons/apple-icon-152x152.png'>\ 00246 <link rel='apple-touch-icon' sizes='180x180' href='/WebPath/images/otsdaqIcons/apple-icon-180x180.png'>\ 00247 <link rel='icon' type='image/png' sizes='192x192' href='/WebPath/images/otsdaqIcons/android-icon-192x192.png'>\ 00248 <link rel='icon' type='image/png' sizes='32x32' href='/WebPath/images/otsdaqIcons/favicon-32x32.png'>\ 00249 <link rel='icon' type='image/png' sizes='96x96' href='/WebPath/images/otsdaqIcons/favicon-96x96.png'>\ 00250 <link rel='icon' type='image/png' sizes='16x16' href='/WebPath/images/otsdaqIcons/favicon-16x16.png'>\ 00251 <link rel='manifest' href='/WebPath/images/otsdaqIcons/manifest.json'>\ 00252 <meta name='msapplication-TileColor' content='#ffffff'>\ 00253 <meta name='msapplication-TileImage' content='/ms-icon-144x144.png'>\ 00254 <meta name='theme-color' content='#ffffff'>" 00255 << 00256 // end show ots icon 00257 "</head>" 00258 << "<frameset col='100%' row='100%'><frame src='/WebPath/html/Wizard.html?urn=" 00259 << this->getApplicationDescriptor()->getLocalId() << securityWarning 00260 << "'></frameset></html>"; 00261 } // end verification() 00262 00263 //======================================================================================================================== 00264 void WizardSupervisor::generateURL() 00265 { 00266 defaultSequence_ = true; 00267 00268 int length = 4; 00269 FILE* fp = fopen((SEQUENCE_FILE_NAME).c_str(), "r"); 00270 if(fp) 00271 { 00272 __COUT_INFO__ << "Sequence length file found: " << SEQUENCE_FILE_NAME 00273 << std::endl; 00274 char line[100]; 00275 fgets(line, 100, fp); 00276 sscanf(line, "%d", &length); 00277 fclose(fp); 00278 if(length < 4) 00279 length = 4; // don't allow shorter than 4 00280 else 00281 defaultSequence_ = false; 00282 srand(time(0)); // randomize differently each "time" 00283 } 00284 else 00285 { 00286 __COUT_INFO__ 00287 << "(Reverting to default wiz security) Sequence length file NOT found: " 00288 << SEQUENCE_FILE_NAME << std::endl; 00289 srand(0); // use same seed for convenience if file not found 00290 } 00291 00292 __COUT__ << "Sequence length = " << length << std::endl; 00293 00294 securityCode_ = ""; 00295 00296 static const char alphanum[] = 00297 "0123456789" 00298 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 00299 "abcdefghijklmnopqrstuvwxyz"; 00300 00301 for(int i = 0; i < length; ++i) 00302 { 00303 securityCode_ += alphanum[rand() % (sizeof(alphanum) - 1)]; 00304 } 00305 00306 __COUT__ << getenv("OTS_CONFIGURATION_WIZARD_SUPERVISOR_SERVER") << ":" 00307 << getenv("PORT") << "/urn:xdaq-application:lid=" 00308 << this->getApplicationDescriptor()->getLocalId() 00309 << "/Verify?code=" << securityCode_ << std::endl; 00310 00311 // Note: print out handled by StartOTS.sh now 00312 // std::thread([&](WizardSupervisor *ptr, std::string securityCode) 00313 // {printURL(ptr,securityCode);},this,securityCode_).detach(); 00314 00315 fp = fopen((SEQUENCE_OUT_FILE_NAME).c_str(), "w"); 00316 if(fp) 00317 { 00318 fprintf(fp, "%s", securityCode_.c_str()); 00319 fclose(fp); 00320 } 00321 else 00322 __COUT_ERR__ << "Sequence output file NOT found: " << SEQUENCE_OUT_FILE_NAME 00323 << std::endl; 00324 00325 return; 00326 } 00327 00328 void WizardSupervisor::printURL(WizardSupervisor* ptr, std::string securityCode) 00329 { 00330 INIT_MF("ConfigurationWizard"); 00331 // child process 00332 int i = 0; 00333 for(; i < 5; ++i) 00334 { 00335 std::this_thread::sleep_for(std::chrono::seconds(2)); 00336 __COUT__ << getenv("OTS_CONFIGURATION_WIZARD_SUPERVISOR_SERVER") << ":" 00337 << getenv("PORT") << "/urn:xdaq-application:lid=" 00338 << ptr->getApplicationDescriptor()->getLocalId() 00339 << "/Verify?code=" << securityCode << std::endl; 00340 } 00341 } 00342 00343 //======================================================================================================================== 00344 void WizardSupervisor::destroy(void) 00345 { 00346 // called by destructor 00347 } 00348 00349 //======================================================================================================================== 00350 void WizardSupervisor::tooltipRequest(xgi::Input* in, 00351 xgi::Output* out) throw(xgi::exception::Exception) 00352 { 00353 cgicc::Cgicc cgi(in); 00354 00355 std::string Command = CgiDataUtilities::getData(cgi, "RequestType"); 00356 __COUT__ << "Command = " << Command << std::endl; 00357 00358 std::string submittedSequence = CgiDataUtilities::postData(cgi, "sequence"); 00359 00360 // SECURITY CHECK START **** 00361 if(securityCode_.compare(submittedSequence) != 0) 00362 { 00363 __COUT__ << "Unauthorized Request made, security sequence doesn't match!" 00364 << std::endl; 00365 return; 00366 } 00367 else 00368 { 00369 __COUT__ << "***Successfully authenticated security sequence." << std::endl; 00370 } 00371 // SECURITY CHECK END **** 00372 00373 HttpXmlDocument xmldoc; 00374 00375 if(Command == "check") 00376 { 00377 WebUsers::tooltipCheckForUsername(WebUsers::DEFAULT_ADMIN_USERNAME, 00378 &xmldoc, 00379 CgiDataUtilities::getData(cgi, "srcFile"), 00380 CgiDataUtilities::getData(cgi, "srcFunc"), 00381 CgiDataUtilities::getData(cgi, "srcId")); 00382 } 00383 else if(Command == "setNeverShow") 00384 { 00385 WebUsers::tooltipSetNeverShowForUsername( 00386 WebUsers::DEFAULT_ADMIN_USERNAME, 00387 &xmldoc, 00388 CgiDataUtilities::getData(cgi, "srcFile"), 00389 CgiDataUtilities::getData(cgi, "srcFunc"), 00390 CgiDataUtilities::getData(cgi, "srcId"), 00391 CgiDataUtilities::getData(cgi, "doNeverShow") == "1" ? true : false, 00392 CgiDataUtilities::getData(cgi, "temporarySilence") == "1" ? true : false); 00393 } 00394 else 00395 __COUT__ << "Command Request, " << Command << ", not recognized." << std::endl; 00396 00397 xmldoc.outputXmlDocument((std::ostringstream*)out, false, true); 00398 } 00399 00400 //======================================================================================================================== 00401 void WizardSupervisor::toggleSecurityCodeGeneration( 00402 xgi::Input* in, xgi::Output* out) throw(xgi::exception::Exception) 00403 { 00404 cgicc::Cgicc cgi(in); 00405 00406 std::string Command = CgiDataUtilities::getData(cgi, "RequestType"); 00407 __COUT__ << "Got to Command = " << Command << std::endl; 00408 00409 std::string submittedSequence = CgiDataUtilities::postData(cgi, "sequence"); 00410 00411 // SECURITY CHECK START **** 00412 if(securityCode_.compare(submittedSequence) != 0) 00413 { 00414 __COUT__ << "Unauthorized Request made, security sequence doesn't match!" 00415 << std::endl; 00416 return; 00417 } 00418 else 00419 { 00420 __COUT__ << "***Successfully authenticated security sequence." << std::endl; 00421 } 00422 // SECURITY CHECK END **** 00423 00424 HttpXmlDocument xmldoc; 00425 00426 if(Command == "TurnGenerationOn") 00427 { 00428 __COUT__ << "Turning automatic URL Generation on with a sequence depth of 16!" 00429 << std::endl; 00430 std::ofstream outfile((SEQUENCE_FILE_NAME).c_str()); 00431 outfile << "16" << std::endl; 00432 outfile.close(); 00433 generateURL(); 00434 00435 // std::stringstream url; 00436 // url << getenv("OTS_CONFIGURATION_WIZARD_SUPERVISOR_SERVER") << ":" << 00437 // getenv("PORT") 00438 // << "/urn:xdaq-application:lid=" << 00439 // this->getApplicationDescriptor()->getLocalId() 00440 // << "/Verify?code=" << securityCode_; 00441 // printURL(this, securityCode_); 00442 std::thread([&](WizardSupervisor* ptr, 00443 std::string securityCode) { printURL(ptr, securityCode); }, 00444 this, 00445 securityCode_) 00446 .detach(); 00447 00448 xmldoc.addTextElementToData("Status", "Generation_Success"); 00449 } 00450 else 00451 __COUT__ << "Command Request, " << Command << ", not recognized." << std::endl; 00452 00453 xmldoc.outputXmlDocument((std::ostringstream*)out, false, true); 00454 } 00455 00456 //======================================================================================================================== 00457 // xoap::supervisorSequenceCheck 00458 // verify cookie 00459 xoap::MessageReference WizardSupervisor::supervisorSequenceCheck( 00460 xoap::MessageReference message) throw(xoap::exception::Exception) 00461 { 00462 // SOAPUtilities::receive request parameters 00463 SOAPParameters parameters; 00464 parameters.addParameter("sequence"); 00465 SOAPUtilities::receive(message, parameters); 00466 00467 std::string submittedSequence = parameters.getValue("sequence"); 00468 00469 // If submittedSequence matches securityCode_ then return full permissions (255) 00470 // else, return permissions 0 00471 std::map<std::string /*groupName*/, WebUsers::permissionLevel_t> permissionMap; 00472 00473 if(securityCode_ == submittedSequence) 00474 permissionMap.emplace( 00475 std::pair<std::string /*groupName*/, WebUsers::permissionLevel_t>( 00476 WebUsers::DEFAULT_USER_GROUP, WebUsers::PERMISSION_LEVEL_ADMIN)); 00477 else 00478 { 00479 __COUT__ << "Unauthorized Request made, security sequence doesn't match!" 00480 << std::endl; 00481 00482 permissionMap.emplace( 00483 std::pair<std::string /*groupName*/, WebUsers::permissionLevel_t>( 00484 WebUsers::DEFAULT_USER_GROUP, WebUsers::PERMISSION_LEVEL_INACTIVE)); 00485 } 00486 00487 // fill return parameters 00488 SOAPParameters retParameters; 00489 retParameters.addParameter("Permissions", StringMacros::mapToString(permissionMap)); 00490 00491 return SOAPUtilities::makeSOAPMessageReference("SequenceResponse", retParameters); 00492 } 00493 00494 //=================================================================================================================== 00495 // xoap::supervisorLastConfigGroupRequest 00496 // return the group name and key for the last state machine activity 00497 // 00498 // Note: same as Supervisor::supervisorLastConfigGroupRequest 00499 xoap::MessageReference WizardSupervisor::supervisorLastConfigGroupRequest( 00500 xoap::MessageReference message) throw(xoap::exception::Exception) 00501 { 00502 SOAPParameters parameters; 00503 parameters.addParameter("ActionOfLastGroup"); 00504 SOAPUtilities::receive(message, parameters); 00505 00506 return GatewaySupervisor::lastConfigGroupRequestHandler(parameters); 00507 } 00508 00509 //======================================================================================================================== 00510 void WizardSupervisor::Default(xgi::Input* in, 00511 xgi::Output* out) throw(xgi::exception::Exception) 00512 { 00513 __COUT__ << "Unauthorized Request made, security sequence doesn't match!" 00514 << std::endl; 00515 *out << "Unauthorized Request."; 00516 } 00517 00518 //======================================================================================================================== 00519 void WizardSupervisor::request(xgi::Input* in, 00520 xgi::Output* out) throw(xgi::exception::Exception) 00521 { 00522 cgicc::Cgicc cgiIn(in); 00523 00524 std::string submittedSequence = CgiDataUtilities::postData(cgiIn, "sequence"); 00525 00526 // SECURITY CHECK START **** 00527 if(securityCode_.compare(submittedSequence) != 0) 00528 { 00529 __COUT__ << "Unauthorized Request made, security sequence doesn't match! " 00530 << time(0) << std::endl; 00531 return; 00532 } 00533 else 00534 { 00535 __COUT__ << "***Successfully authenticated security sequence. " << time(0) 00536 << std::endl; 00537 } 00538 // SECURITY CHECK END **** 00539 00540 std::string requestType = CgiDataUtilities::getData(cgiIn, "RequestType"); 00541 __COUTV__(requestType); 00542 00543 HttpXmlDocument xmlOut; 00544 00545 try 00546 { 00547 if(requestType == "gatewayLaunchOTS" || requestType == "gatewayLaunchWiz") 00548 { 00549 // NOTE: similar to ConfigurationGUI version but DOES keep active sessions 00550 00551 __COUT_WARN__ << requestType << " requestType received! " << __E__; 00552 __MOUT_WARN__ << requestType << " requestType received! " << __E__; 00553 00554 // now launch 00555 ConfigurationManager cfgMgr; 00556 if(requestType == "gatewayLaunchOTS") 00557 GatewaySupervisor::launchStartOTSCommand("LAUNCH_OTS", &cfgMgr); 00558 else if(requestType == "gatewayLaunchWiz") 00559 GatewaySupervisor::launchStartOTSCommand("LAUNCH_WIZ", &cfgMgr); 00560 } 00561 else 00562 { 00563 __SS__ << "requestType Request, " << requestType << ", not recognized." 00564 << __E__; 00565 __SS_THROW__; 00566 } 00567 } 00568 catch(const std::runtime_error& e) 00569 { 00570 __SS__ << "An error was encountered handling requestType '" << requestType 00571 << "':" << e.what() << __E__; 00572 __COUT__ << "\n" << ss.str(); 00573 xmlOut.addTextElementToData("Error", ss.str()); 00574 } 00575 catch(...) 00576 { 00577 __SS__ << "An unknown error was encountered handling requestType '" << requestType 00578 << ".' " 00579 << "Please check the printouts to debug." << __E__; 00580 __COUT__ << "\n" << ss.str(); 00581 xmlOut.addTextElementToData("Error", ss.str()); 00582 } 00583 00584 // return xml doc holding server response 00585 xmlOut.outputXmlDocument( 00586 (std::ostringstream*)out, 00587 false /*dispStdOut*/, 00588 true /*allowWhiteSpace*/); // Note: allow white space need for error response 00589 00590 } // end request() 00591 00592 //======================================================================================================================== 00593 void WizardSupervisor::editSecurity(xgi::Input* in, 00594 xgi::Output* out) throw(xgi::exception::Exception) 00595 { 00596 // if sequence doesn't match up -> return 00597 cgicc::Cgicc cgi(in); 00598 std::string submittedSequence = CgiDataUtilities::postData(cgi, "sequence"); 00599 std::string submittedSecurity = CgiDataUtilities::postData(cgi, "selection"); 00600 std::string securityFileName = SECURITY_FILE_NAME; 00601 00602 // SECURITY CHECK START **** 00603 if(securityCode_.compare(submittedSequence) != 0) 00604 { 00605 __COUT__ << "Unauthorized Request made, security sequence doesn't match!" 00606 << std::endl; 00607 return; 00608 } 00609 else 00610 { 00611 __COUT__ << "***Successfully authenticated security sequence." << std::endl; 00612 } 00613 // SECURITY CHECK END **** 00614 00615 if(submittedSecurity != "") 00616 { 00617 __COUT__ << "Selection exists!" << std::endl; 00618 __COUT__ << submittedSecurity << std::endl; 00619 00620 if(submittedSecurity == "ResetAllUserData") 00621 { 00622 WebUsers::deleteUserData(); 00623 __COUT__ << "Turning URL Generation back to default!" << std::endl; 00624 // std::remove((SEQUENCE_FILE_NAME).c_str()); 00625 // std::remove((SEQUENCE_OUT_FILE_NAME).c_str()); 00626 std::ofstream newFile((SEQUENCE_FILE_NAME).c_str()); 00627 newFile << "4" << std::endl; 00628 newFile.close(); 00629 00630 generateURL(); 00631 std::thread([&](WizardSupervisor* ptr, 00632 std::string securityCode) { printURL(ptr, securityCode); }, 00633 this, 00634 securityCode_) 00635 .detach(); 00636 *out << "Default_URL_Generation"; 00637 } 00638 else if(submittedSecurity == "ResetAllUserTooltips") 00639 { 00640 WebUsers::resetAllUserTooltips(); 00641 *out << submittedSecurity; 00642 return; 00643 } 00644 else if(submittedSecurity == "DigestAccessAuthentication" || 00645 submittedSecurity == "NoSecurity") 00646 { 00647 std::ofstream writeSecurityFile; 00648 00649 writeSecurityFile.open(securityFileName.c_str()); 00650 if(writeSecurityFile.is_open()) 00651 writeSecurityFile << submittedSecurity; 00652 else 00653 __COUT__ << "Error writing file!" << std::endl; 00654 00655 writeSecurityFile.close(); 00656 } 00657 else 00658 { 00659 __COUT_ERR__ << "Invalid submittedSecurity string: " << submittedSecurity 00660 << std::endl; 00661 *out << "Error"; 00662 return; 00663 } 00664 } 00665 00666 // Always return the file 00667 std::ifstream securityFile; 00668 std::string line; 00669 std::string security = ""; 00670 int lineNumber = 0; 00671 00672 securityFile.open(securityFileName.c_str()); 00673 00674 if(!securityFile) 00675 { 00676 //__SS__ << "Error opening file: "<< securityFileName << std::endl; 00677 //__COUT_ERR__ << "\n" << ss.str(); 00678 00679 //__SS_THROW__; 00680 // return; 00681 security = "DigestAccessAuthentication"; // default security when no file exists 00682 } 00683 if(securityFile.is_open()) 00684 { 00685 //__COUT__ << "Opened File: " << securityFileName << std::endl; 00686 while(std::getline(securityFile, line)) 00687 { 00688 security += line; 00689 lineNumber++; 00690 } 00691 //__COUT__ << std::to_string(lineNumber) << ":" << iconList << std::endl; 00692 00693 // Close file 00694 securityFile.close(); 00695 } 00696 00697 *out << security; 00698 } 00699 //======================================================================================================================== 00700 void WizardSupervisor::UserSettings(xgi::Input* in, 00701 xgi::Output* out) throw(xgi::exception::Exception) 00702 { 00703 // if sequence doesn't match up -> return 00704 cgicc::Cgicc cgi(in); 00705 std::string submittedSequence = CgiDataUtilities::postData(cgi, "sequence"); 00706 std::string securityFileName = SECURITY_FILE_NAME; 00707 std::string Command; 00708 if((Command = CgiDataUtilities::postData(cgi, "RequestType")) == "") 00709 Command = cgi("RequestType"); // get command from form, if PreviewEntry 00710 00711 __COUT__ << Command << std::endl; 00712 __COUT__ << "We are vewing Users' Settings!" << std::endl; 00713 00714 // SECURITY CHECK START **** 00715 if(securityCode_.compare(submittedSequence) != 0) 00716 { 00717 __COUT__ << "Unauthorized Request made, security sequence doesn't match!" 00718 << std::endl; 00719 __COUT__ << submittedSequence << std::endl; 00720 // return; 00721 } 00722 else 00723 { 00724 __COUT__ << "***Successfully authenticated security sequence." << std::endl; 00725 } 00726 // SECURITY CHECK END **** 00727 00728 HttpXmlDocument xmldoc; 00729 uint64_t activeSessionIndex; 00730 std::string user; 00731 uint8_t userPermissions; 00732 00733 if(Command != "") 00734 { 00735 __COUT__ << "Action exists!" << std::endl; 00736 __COUT__ << Command << std::endl; 00737 00738 if(Command == "Import") 00739 { 00740 // cleanup temporary folder 00741 // NOTE: all input parameters for User Data will be attached to form 00742 // so use cgi(xxx) to get values. 00743 // increment number for each temporary preview, previewPostTempIndex_ 00744 // save entry and uploads to previewPath / previewPostTempIndex_ /. 00745 00746 // cleanUpPreviews(); 00747 // std::string EntryText = cgi("EntryText"); 00748 // __COUT__ << "EntryText " << EntryText << std::endl << std::endl; 00749 // std::string EntrySubject = cgi("EntrySubject"); 00750 // __COUT__ << "EntrySubject " << EntrySubject << std::endl << 00751 // std::endl; 00752 00753 // get creator name 00754 // std::string creator = user; 00755 // CgiDataUtilities::postData(cgi, "file"); CgiDataUtilities::postData(cgi, 00756 // "file");// 00757 __COUT__ << cgi("Entry") << std::endl; 00758 __COUT__ << cgi("Filename") << std::endl; 00759 __COUT__ << cgi("Imported_File") << std::endl; 00760 00761 const std::vector<cgicc::FormFile> files = cgi.getFiles(); 00762 __COUT__ << "FormFiles: " << sizeof(files) << std::endl; 00763 __COUT__ << "Number of files: " << files.size() << std::endl; 00764 00765 for(unsigned int i = 0; i < files.size(); ++i) 00766 { 00767 std::string filename = USER_DATA_PATH + files[i].getFilename(); 00768 __COUT__ << filename << std::endl; 00769 std::ofstream myFile; 00770 myFile.open(filename.c_str()); 00771 files[0].writeToStream(myFile); 00772 } 00773 00774 __COUT__ << files[0].getFilename() << std::endl; 00775 __COUT__ << "********************Files Begin********************" 00776 << std::endl; 00777 for(unsigned int i = 0; i < files.size(); ++i) 00778 { 00779 __COUT__ << files[i].getDataType() << std::endl; 00780 } 00781 __COUT__ << "*********************Files End*********************" 00782 << std::endl; 00783 00784 // savePostPreview(EntrySubject, EntryText, cgi.getFiles(), creator, 00785 //&xmldoc); else xmldoc.addTextElementToData(XML_STATUS,"Failed - could not 00786 // get username info."); 00787 } 00788 else if(Command == "Export") 00789 { 00790 __SS__ << "This has been commented out due to problems compiling. Contact " 00791 "system admins." 00792 << __E__; 00793 __SS_THROW__; 00794 // 00795 // __COUT__ << "We are exporting Users' Settings!!!" << std::endl; 00796 // //system('pwd'); 00797 // 00798 // //Check for a TMP directory; if it doesn't exist, make it 00799 // std::string command = "cd " + USER_DATA_PATH; 00800 // std::string pathToTmp = USER_DATA_PATH + "/tmp/"; 00801 // std::filesystem::path tmp = pathToTmp; 00802 // 00803 // exec(command.c_str()); 00804 // __COUT__ << exec("pwd") << std::endl; 00805 // 00806 // 00807 // if(std::filesystem::status_known(tmpDir) ? 00808 // std::filesystem::exists(tmpDir) : std::filesystem::exists(tmpDir)) 00809 // __COUT__ << pathToTmp << " exists!" << std::endl; 00810 // else 00811 // __COUT__ << pathToTmp << "does not exist! Creating it now. " 00812 //<< std::endl; 00813 // 00814 // //Zip current files into TMP directory 00815 // command = std::string("tar -cvf user_settings.tar") + 00816 // std::string("ActiveTableGroups.cfg ") + 00817 // std::string("ConsolePreferences ") + 00818 // std::string("CoreTableInfoNames.dat ") + 00819 // std::string("LoginData ") + 00820 // std::string("OtsWizardData ") + 00821 // std::string("ProgressBarData "); 00822 // 00823 // 00824 // //return zip 00825 // if(exec("pwd").find(USER_DATA_PATH) != std::string::npos) 00826 // { 00827 // __COUT__ << "Found USER_DATA directory " << std::endl; 00828 // system(command.c_str()); 00829 // __COUT__ << system("ls") << std::endl; 00830 // } 00831 } 00832 else 00833 { 00834 __COUT__ << "Command request not recognized: " << Command << std::endl; 00835 *out << "Error"; 00836 return; 00837 } 00838 } 00839 00840 *out << "test"; 00841 return; 00842 } 00843 //======================================================================================================================== 00844 // validateUploadFileType 00845 // returns "" if file type is invalid, else returns file extension to use 00846 std::string WizardSupervisor::validateUploadFileType(const std::string fileType) 00847 { 00848 for(unsigned int i = 0; i < allowedFileUploadTypes_.size(); ++i) 00849 if(allowedFileUploadTypes_[i] == fileType) 00850 return matchingFileUploadTypes_[i]; // found and done 00851 00852 return ""; // not valid, return "" 00853 } 00854 //======================================================================================================================== 00855 // cleanUpPreviews 00856 // cleanup logbook preview directory 00857 // all names have time_t creation time + "_" + incremented index 00858 void WizardSupervisor::cleanUpPreviews() 00859 { 00860 std::string userData = (std::string)USER_DATA_PATH; 00861 00862 DIR* dir = opendir(userData.c_str()); 00863 if(!dir) 00864 { 00865 __COUT__ << "Error - User Data directory missing: " << userData << std::endl; 00866 return; 00867 } 00868 00869 struct dirent* entry; 00870 time_t dirCreateTime; 00871 unsigned int i; 00872 00873 while( 00874 (entry = readdir( 00875 dir))) // loop through all entries in directory and remove anything expired 00876 { 00877 if(strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0 && 00878 strcmp(entry->d_name, ".svn") != 0) 00879 { 00880 // replace _ with space so sscanf works 00881 for(i = 0; i < strlen(entry->d_name); ++i) 00882 if(entry->d_name[i] == '_') 00883 { 00884 entry->d_name[i] = ' '; 00885 break; 00886 } 00887 sscanf(entry->d_name, "%li", &dirCreateTime); 00888 00889 if((time(0) - dirCreateTime) > USER_DATA_EXPIRATION_TIME) 00890 { 00891 __COUT__ << "Expired" << std::endl; 00892 00893 entry->d_name[i] = '_'; // put _ back 00894 00895 __COUT__ << "rm -rf " << USER_DATA_PATH + (std::string)entry->d_name 00896 << std::endl 00897 << std::endl; 00898 system(((std::string)("rm -rf " + userData + (std::string)entry->d_name)) 00899 .c_str()); 00900 } 00901 } 00902 } 00903 00904 closedir(dir); 00905 } 00906 00907 //======================================================================================================================== 00908 // savePostPreview 00909 // save post to preview directory named with time and incremented index 00910 void WizardSupervisor::savePostPreview(std::string& subject, 00911 std::string& text, 00912 const std::vector<cgicc::FormFile>& files, 00913 std::string creator, 00914 HttpXmlDocument* xmldoc) 00915 { 00916 /*if(activeExperiment_ == "") //no active experiment! 00917 { 00918 if(xmldoc) xmldoc->addTextElementToData(XML_STATUS,"Failed - no active experiment 00919 currently!"); return; 00920 } 00921 */ 00922 char fileIndex[40]; 00923 sprintf(fileIndex, 00924 "%lu_%lu", 00925 time(0), 00926 clock()); // create unique time label for entry time(0)_clock() 00927 std::string userDataPath = (std::string)USER_DATA_PATH + (std::string)fileIndex; 00928 00929 __COUT__ << "userDataPath " << userDataPath << std::endl; 00930 if(-1 == mkdir(userDataPath.c_str(), 0755)) 00931 { 00932 if(xmldoc) 00933 xmldoc->addTextElementToData(XML_STATUS, 00934 "Failed - directory could not be generated."); 00935 return; 00936 } 00937 /* 00938 //new directory created successfully, save text and files 00939 //entry structure: 00940 // <XML_LOGBOOK_ENTRY> 00941 // <XML_LOGBOOK_ENTRY_TIME> 00942 // <XML_LOGBOOK_ENTRY_CREATOR> 00943 // <XML_LOGBOOK_ENTRY_SUBJECT> 00944 // <XML_LOGBOOK_ENTRY_TEXT> 00945 // <XML_LOGBOOK_ENTRY_FILE value=fileType0> 00946 // <XML_LOGBOOK_ENTRY_FILE value=fileType1> ... 00947 // </XML_LOGBOOK_ENTRY> 00948 00949 escapeLogbookEntry(text); 00950 escapeLogbookEntry(subject); 00951 __COUT__ << "~~subject " << subject << std::endl << "~~text " << text << std::endl << 00952 std::endl; 00953 00954 HttpXmlDocument previewXml; 00955 00956 previewXml.addTextElementToData(XML_LOGBOOK_ENTRY); 00957 previewXml.addTextElementToParent(XML_LOGBOOK_ENTRY_TIME, fileIndex, 00958 XML_LOGBOOK_ENTRY); if(xmldoc) 00959 xmldoc->addTextElementToData(XML_LOGBOOK_ENTRY_TIME,fileIndex); //return time 00960 previewXml.addTextElementToParent(XML_LOGBOOK_ENTRY_CREATOR, creator, 00961 XML_LOGBOOK_ENTRY); if(xmldoc) 00962 xmldoc->addTextElementToData(XML_LOGBOOK_ENTRY_CREATOR,creator); //return creator 00963 previewXml.addTextElementToParent(XML_LOGBOOK_ENTRY_TEXT, text, XML_LOGBOOK_ENTRY); 00964 if(xmldoc) xmldoc->addTextElementToData(XML_LOGBOOK_ENTRY_TEXT,text); //return text 00965 previewXml.addTextElementToParent(XML_LOGBOOK_ENTRY_SUBJECT, subject, 00966 XML_LOGBOOK_ENTRY); if(xmldoc) 00967 xmldoc->addTextElementToData(XML_LOGBOOK_ENTRY_SUBJECT,subject); //return subject 00968 00969 __COUT__ << "file size " << files.size() << std::endl; 00970 00971 std::string filename; 00972 std::ofstream myfile; 00973 for (unsigned int i=0; i<files.size(); ++i) 00974 { 00975 00976 previewXml.addTextElementToParent(XML_LOGBOOK_ENTRY_FILE, files[i].getDataType(), 00977 XML_LOGBOOK_ENTRY); if(xmldoc) 00978 xmldoc->addTextElementToData(XML_LOGBOOK_ENTRY_FILE,files[i].getDataType()); //return 00979 file type 00980 00981 if((filename = validateUploadFileType(files[i].getDataType())) == "") //invalid 00982 file type 00983 { 00984 if(xmldoc) xmldoc->addTextElementToData(XML_STATUS,"Failed - invalid file 00985 type, " + files[i].getDataType() + "."); return; 00986 }*/ 00987 00988 /*//file validated, so save upload to temp directory 00989 sprintf(fileIndex,"%d",i); 00990 filename = previewPath + "/" + (std::string)LOGBOOK_PREVIEW_UPLOAD_PREFACE + 00991 (std::string)fileIndex + "." + filename; 00992 00993 __COUT__ << "file " << i << " - " << filename << std::endl; 00994 myfile.open(filename.c_str()); 00995 if (myfile.is_open()) 00996 { 00997 files[i].writeToStream(myfile); 00998 myfile.close(); 00999 } 01000 }*/ 01001 /* 01002 //save xml doc for preview entry 01003 previewXml.saveXmlDocument(USER_DATA_PATH + "/" + (std::string)LOGBOOK_PREVIEW_FILE); 01004 01005 if(xmldoc) xmldoc->addTextElementToData(XML_STATUS,"1"); //1 indicates success! 01006 if(xmldoc) xmldoc->addTextElementToData(XML_PREVIEW_INDEX,"1"); //1 indicates is a 01007 preview post*/ 01008 }