00001 #include "otsdaq-core/WizardSupervisor/WizardSupervisor.h"
00002
00003 #include "otsdaq-core/GatewaySupervisor/GatewaySupervisor.h"
00004
00005 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00006 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
00007
00008 #include <xdaq/NamespaceURI.h>
00009 #include "otsdaq-core/CgiDataUtilities/CgiDataUtilities.h"
00010 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
00011 #include "otsdaq-core/WebUsersUtilities/WebUsers.h"
00012 #include "otsdaq-core/SOAPUtilities/SOAPUtilities.h"
00013 #include "otsdaq-core/SOAPUtilities/SOAPCommand.h"
00014
00015 #include <iostream>
00016 #include <fstream>
00017 #include <string>
00018 #include <thread>
00019 #include <chrono>
00020 #include <sys/stat.h>
00021
00022
00023 using namespace ots;
00024
00025
00026 #define SECURITY_FILE_NAME std::string(getenv("SERVICE_DATA_PATH")) + "/OtsWizardData/security.dat"
00027 #define SEQUENCE_FILE_NAME std::string(getenv("SERVICE_DATA_PATH")) + "/OtsWizardData/sequence.dat"
00028 #define SEQUENCE_OUT_FILE_NAME std::string(getenv("SERVICE_DATA_PATH")) + "/OtsWizardData/sequence.out"
00029
00030 XDAQ_INSTANTIATOR_IMPL(WizardSupervisor)
00031
00032
00033
00034 #undef __MF_SUBJECT__
00035 #define __MF_SUBJECT__ "Wizard"
00036
00037
00038
00039 WizardSupervisor::WizardSupervisor(xdaq::ApplicationStub * s) throw (xdaq::exception::Exception):
00040 xdaq::Application(s ),
00041 SOAPMessenger (this)
00042 {
00043 INIT_MF("OtsConfigurationWizard");
00044
00045
00046
00047 mkdir((std::string(getenv("SERVICE_DATA_PATH"))).c_str(), 0755);
00048 mkdir((std::string(getenv("SERVICE_DATA_PATH")) + "/OtsWizardData").c_str(), 0755);
00049
00050 generateURL();
00051 xgi::bind (this, &WizardSupervisor::Default, "Default" );
00052 xgi::bind (this, &WizardSupervisor::verification, "Verify" );
00053 xgi::bind (this, &WizardSupervisor::requestIcons, "requestIcons" );
00054 xgi::bind (this, &WizardSupervisor::editSecurity, "editSecurity" );
00055 xgi::bind (this, &WizardSupervisor::tooltipRequest, "TooltipRequest" );
00056 xgi::bind (this, &WizardSupervisor::toggleSecurityCodeGeneration, "ToggleSecurityCodeGeneration" );
00057 xoap::bind(this, &WizardSupervisor::supervisorSequenceCheck, "SupervisorSequenceCheck", XDAQ_NS_URI);
00058 xoap::bind(this, &WizardSupervisor::supervisorLastConfigGroupRequest, "SupervisorLastConfigGroupRequest", XDAQ_NS_URI);
00059 init();
00060
00061 }
00062
00063
00064 WizardSupervisor::~WizardSupervisor(void)
00065 {
00066 destroy();
00067 }
00068
00069
00070 void WizardSupervisor::init(void)
00071 {
00072 getApplicationContext();
00073 }
00074
00075
00076 void WizardSupervisor::generateURL()
00077 {
00078 defaultSequence_ = true;
00079 int length = 4;
00080 FILE *fp = fopen((SEQUENCE_FILE_NAME).c_str(),"r");
00081 if(fp)
00082 {
00083 __COUT_INFO__ << "Sequence length file found: " << SEQUENCE_FILE_NAME << std::endl;
00084 char line[100];
00085 fgets(line,100,fp);
00086 sscanf(line,"%d",&length);
00087 fclose(fp);
00088 if(length < 4)
00089 length = 4;
00090 else
00091 defaultSequence_ = false;
00092 srand(time(0));
00093 }
00094 else
00095 {
00096 __COUT_INFO__ << "(Reverting to default wiz security) Sequence length file NOT found: " << SEQUENCE_FILE_NAME << std::endl;
00097 srand(0);
00098 }
00099
00100 __COUT__ << "Sequence length = " << length << std::endl;
00101
00102 securityCode_ = "";
00103
00104 static const char alphanum[] =
00105 "0123456789"
00106 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
00107 "abcdefghijklmnopqrstuvwxyz";
00108
00109
00110 for (int i = 0; i < length; ++i) {
00111 securityCode_ += alphanum[rand() % (sizeof(alphanum) - 1)];
00112 }
00113
00114 std::cout << __COUT_HDR_FL__ <<
00115 getenv("OTS_CONFIGURATION_WIZARD_SUPERVISOR_SERVER") << ":" << getenv("PORT") <<
00116 "/urn:xdaq-application:lid="
00117 << this->getApplicationDescriptor()->getLocalId() << "/Verify?code=" << securityCode_ << std::endl;
00118
00119
00120
00121
00122
00123 fp = fopen((SEQUENCE_OUT_FILE_NAME).c_str(),"w");
00124 if(fp)
00125 {
00126 fprintf(fp,"%s",securityCode_.c_str());
00127 fclose(fp);
00128 }
00129 else
00130 __COUT_ERR__ << "Sequence output file NOT found: " << SEQUENCE_OUT_FILE_NAME << std::endl;
00131
00132
00133 return;
00134 }
00135
00136 void WizardSupervisor::printURL(WizardSupervisor *ptr,
00137 std::string securityCode)
00138 {
00139 INIT_MF("ConfigurationWizard");
00140
00141 int i = 0;
00142 for (; i < 5; ++i)
00143 {
00144 std::this_thread::sleep_for (std::chrono::seconds(2));
00145 std::cout << __COUT_HDR_FL__ <<
00146 getenv("OTS_CONFIGURATION_WIZARD_SUPERVISOR_SERVER") << ":" << getenv("PORT") <<
00147 "/urn:xdaq-application:lid="
00148 << ptr->getApplicationDescriptor()->getLocalId() << "/Verify?code=" << securityCode << std::endl;
00149 }
00150 }
00151
00152
00153 void WizardSupervisor::destroy(void)
00154 {
00155
00156
00157 }
00158
00159
00160
00161 void WizardSupervisor::tooltipRequest(xgi::Input * in, xgi::Output * out)
00162 throw (xgi::exception::Exception)
00163 {
00164 cgicc::Cgicc cgi(in);
00165
00166 std::string Command = CgiDataUtilities::getData(cgi, "RequestType");
00167 __COUT__ << "Command = " << Command << std::endl;
00168
00169 std::string submittedSequence = CgiDataUtilities::postData(cgi, "sequence");
00170
00171
00172 if(securityCode_.compare(submittedSequence) != 0)
00173 {
00174 __COUT__ << "Unauthorized Request made, security sequence doesn't match!" << std::endl;
00175 return;
00176 }
00177 else
00178 {
00179 __COUT__ << "***Successfully authenticated security sequence." << std::endl;
00180 }
00181
00182
00183 HttpXmlDocument xmldoc;
00184
00185 if(Command == "check")
00186 {
00187 WebUsers::tooltipCheckForUsername(
00188 WebUsers::DEFAULT_ADMIN_USERNAME,
00189 &xmldoc,
00190 CgiDataUtilities::getData(cgi, "srcFile"),
00191 CgiDataUtilities::getData(cgi, "srcFunc"),
00192 CgiDataUtilities::getData(cgi, "srcId"));
00193 }
00194 else if(Command == "setNeverShow")
00195 {
00196 WebUsers::tooltipSetNeverShowForUsername(
00197 WebUsers::DEFAULT_ADMIN_USERNAME,
00198 &xmldoc,
00199 CgiDataUtilities::getData(cgi, "srcFile"),
00200 CgiDataUtilities::getData(cgi, "srcFunc"),
00201 CgiDataUtilities::getData(cgi, "srcId"),
00202 CgiDataUtilities::getData(cgi, "doNeverShow") == "1"?true:false,
00203 CgiDataUtilities::getData(cgi, "temporarySilence") == "1"?true:false);
00204
00205 }
00206 else
00207 __COUT__ << "Command Request, " << Command << ", not recognized." << std::endl;
00208
00209 xmldoc.outputXmlDocument((std::ostringstream*) out, false, true);
00210 }
00211
00212
00213 void WizardSupervisor::toggleSecurityCodeGeneration(xgi::Input * in, xgi::Output * out)
00214 throw (xgi::exception::Exception)
00215 {
00216 cgicc::Cgicc cgi(in);
00217
00218 std::string Command = CgiDataUtilities::getData(cgi, "RequestType");
00219 __COUT__ << "Got to Command = " << Command << std::endl;
00220
00221 std::string submittedSequence = CgiDataUtilities::postData(cgi, "sequence");
00222
00223
00224 if(securityCode_.compare(submittedSequence) != 0)
00225 {
00226 __COUT__ << "Unauthorized Request made, security sequence doesn't match!" << std::endl;
00227 return;
00228 }
00229 else
00230 {
00231 __COUT__ << "***Successfully authenticated security sequence." << std::endl;
00232 }
00233
00234
00235 HttpXmlDocument xmldoc;
00236
00237 if(Command == "TurnGenerationOn")
00238 {
00239 __COUT__ << "Turning automatic URL Generation on with a sequence depth of 16!" << std::endl;
00240 std::ofstream outfile ((SEQUENCE_FILE_NAME).c_str());
00241 outfile << "16" << std::endl;
00242 outfile.close();
00243 generateURL();
00244
00245
00246
00247
00248
00249
00250 std::thread([&](WizardSupervisor *ptr, std::string securityCode)
00251 {printURL(ptr,securityCode);},this,securityCode_).detach();
00252
00253 xmldoc.addTextElementToData("Status", "Generation_Success");
00254 }
00255 else
00256 __COUT__ << "Command Request, " << Command << ", not recognized." << std::endl;
00257
00258 xmldoc.outputXmlDocument((std::ostringstream*) out, false, true);
00259 }
00260
00261
00262
00263
00264 xoap::MessageReference WizardSupervisor::supervisorSequenceCheck(xoap::MessageReference message)
00265 throw (xoap::exception::Exception)
00266 {
00267
00268 SOAPParameters parameters;
00269 parameters.addParameter("sequence");
00270 receive(message, parameters);
00271
00272 std::string submittedSequence = parameters.getValue("sequence");
00273
00274
00275
00276 uint8_t userPermissions = 0;
00277 std::string userWithLock = "";
00278
00279 if(securityCode_ == submittedSequence)
00280 userPermissions = 255;
00281 else
00282 __COUT__ << "Unauthorized Request made, security sequence doesn't match!" << std::endl;
00283
00284
00285 SOAPParameters retParameters;
00286 char tmp[5];
00287 sprintf(tmp, "%d", userPermissions);
00288 retParameters.addParameter("Permissions", tmp);
00289
00290
00291 return SOAPUtilities::makeSOAPMessageReference("SequenceResponse",
00292 retParameters);
00293 }
00294
00295
00296
00297
00298
00299
00300 xoap::MessageReference WizardSupervisor::supervisorLastConfigGroupRequest(
00301 xoap::MessageReference message)
00302 throw (xoap::exception::Exception)
00303 {
00304 SOAPParameters parameters;
00305 parameters.addParameter("ActionOfLastGroup");
00306 receive(message, parameters);
00307
00308 return GatewaySupervisor::lastConfigGroupRequestHandler(parameters);
00309 }
00310
00311
00312 void WizardSupervisor::Default(xgi::Input * in, xgi::Output * out )
00313 throw (xgi::exception::Exception)
00314 {
00315 __COUT__ << "Unauthorized Request made, security sequence doesn't match!" << std::endl;
00316 *out << "Unauthorized Request.";
00317 }
00318
00319
00320 void WizardSupervisor::verification(xgi::Input * in, xgi::Output * out )
00321 throw (xgi::exception::Exception)
00322 {
00323 cgicc::Cgicc cgi(in);
00324 std::string submittedSequence = CgiDataUtilities::getData(cgi, "code");
00325 __COUT__ << "submittedSequence=" << submittedSequence <<
00326 " " << time(0) << std::endl;
00327
00328 std::string securityWarning = "";
00329
00330 if(securityCode_.compare(submittedSequence) != 0)
00331 {
00332 __COUT__ << "Unauthorized Request made, security sequence doesn't match!" << std::endl;
00333 *out << "Invalid code.";
00334 return;
00335 }
00336 else
00337 {
00338
00339 __COUT__ << "***Successfully authenticated security sequence. Default Sequence: "<< defaultSequence_ <<
00340 time(0) << std::endl;
00341
00342 if (defaultSequence_)
00343 {
00344 __COUT__ << " UNSECURE!!!" << std::endl;
00345 securityWarning = "&secure=False";
00346 }
00347 }
00348
00349 *out << "<!DOCTYPE HTML><html lang='en'><head><title>ots wiz</title>" <<
00350
00351
00352 "<link rel='apple-touch-icon' sizes='57x57' href='/WebPath/images/otsdaqIcons/apple-icon-57x57.png'>\
00353 <link rel='apple-touch-icon' sizes='60x60' href='/WebPath/images/otsdaqIcons/apple-icon-60x60.png'>\
00354 <link rel='apple-touch-icon' sizes='72x72' href='/WebPath/images/otsdaqIcons/apple-icon-72x72.png'>\
00355 <link rel='apple-touch-icon' sizes='76x76' href='/WebPath/images/otsdaqIcons/apple-icon-76x76.png'>\
00356 <link rel='apple-touch-icon' sizes='114x114' href='/WebPath/images/otsdaqIcons/apple-icon-114x114.png'>\
00357 <link rel='apple-touch-icon' sizes='120x120' href='/WebPath/images/otsdaqIcons/apple-icon-120x120.png'>\
00358 <link rel='apple-touch-icon' sizes='144x144' href='/WebPath/images/otsdaqIcons/apple-icon-144x144.png'>\
00359 <link rel='apple-touch-icon' sizes='152x152' href='/WebPath/images/otsdaqIcons/apple-icon-152x152.png'>\
00360 <link rel='apple-touch-icon' sizes='180x180' href='/WebPath/images/otsdaqIcons/apple-icon-180x180.png'>\
00361 <link rel='icon' type='image/png' sizes='192x192' href='/WebPath/images/otsdaqIcons/android-icon-192x192.png'>\
00362 <link rel='icon' type='image/png' sizes='32x32' href='/WebPath/images/otsdaqIcons/favicon-32x32.png'>\
00363 <link rel='icon' type='image/png' sizes='96x96' href='/WebPath/images/otsdaqIcons/favicon-96x96.png'>\
00364 <link rel='icon' type='image/png' sizes='16x16' href='/WebPath/images/otsdaqIcons/favicon-16x16.png'>\
00365 <link rel='manifest' href='/WebPath/images/otsdaqIcons/manifest.json'>\
00366 <meta name='msapplication-TileColor' content='#ffffff'>\
00367 <meta name='msapplication-TileImage' content='/ms-icon-144x144.png'>\
00368 <meta name='theme-color' content='#ffffff'>" <<
00369
00370 "</head>" <<
00371 "<frameset col='100%' row='100%'><frame src='/WebPath/html/Wizard.html?urn=" <<
00372 this->getApplicationDescriptor()->getLocalId() << securityWarning <<"'></frameset></html>";
00373
00374 }
00375
00376
00377 void WizardSupervisor::requestIcons(xgi::Input * in, xgi::Output * out )
00378 throw (xgi::exception::Exception)
00379 {
00380 cgicc::Cgicc cgi(in);
00381
00382 std::string submittedSequence = CgiDataUtilities::postData(cgi, "sequence");
00383
00384
00385 if(securityCode_.compare(submittedSequence) != 0)
00386 {
00387 __COUT__ << "Unauthorized Request made, security sequence doesn't match! " <<
00388 time(0) << std::endl;
00389 return;
00390 }
00391 else
00392 {
00393 __COUT__ << "***Successfully authenticated security sequence. " <<
00394 time(0) << std::endl;
00395 }
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 *out << "Security Settings,SEC,1,1,icon-SecuritySettings.png,/WebPath/html/SecuritySettings.html,/" <<
00409 ",Edit User Data,USER,1,1,icon-EditUserData.png,/WebPath/html/EditUserData.html,/" <<
00410 ",Configure,CFG,0,1,icon-Configure.png,/urn:xdaq-application:lid=280/,/" <<
00411 ",Table Editor,TBL,0,1,icon-IconEditor.png,/urn:xdaq-application:lid=280/?configWindowName=tableEditor,/" <<
00412
00413
00414
00415
00416 ",Front-end Wizard,CFG,0,1,icon-Configure.png,/WebPath/html/RecordWiz_ConfigurationGUI.html?urn=280&subsetBasePath=FEInterfaceConfiguration&recordAlias=Front%2Dend,Config Wizards" <<
00417 ",Producer Wizard,CFG,0,1,icon-Configure.png,/WebPath/html/RecordWiz_ConfigurationGUI.html?urn=280&subsetBasePath=FEInterfaceConfiguration&recordAlias=Producer,Config Wizards" <<
00418 ",Consumer Wizard,CFG,0,1,icon-Configure.png,/WebPath/html/RecordWiz_ConfigurationGUI.html?urn=280&subsetBasePath=FEInterfaceConfiguration&recordAlias=Consumer,Config Wizards" <<
00419 ",Console,C,1,1,icon-Console.png,/urn:xdaq-application:lid=260/,/" <<
00420
00421 "";
00422 return;
00423 }
00424
00425
00426 void WizardSupervisor::editSecurity(xgi::Input * in, xgi::Output * out )
00427 throw (xgi::exception::Exception)
00428 {
00429
00430
00431 cgicc::Cgicc cgi(in);
00432 std::string submittedSequence = CgiDataUtilities::postData(cgi, "sequence");
00433 std::string submittedSecurity = CgiDataUtilities::postData(cgi, "selection");
00434 std::string securityFileName = SECURITY_FILE_NAME;
00435
00436
00437
00438 if(securityCode_.compare(submittedSequence) != 0)
00439 {
00440 __COUT__ << "Unauthorized Request made, security sequence doesn't match!" << std::endl;
00441 return;
00442 }
00443 else
00444 {
00445 __COUT__ << "***Successfully authenticated security sequence." << std::endl;
00446 }
00447
00448
00449
00450
00451 if(submittedSecurity != "")
00452 {
00453 __COUT__ << "Selection exists!" << std::endl;
00454 __COUT__ << submittedSecurity << std::endl;
00455
00456 if(submittedSecurity == "ResetAllUserData")
00457 {
00458 WebUsers::deleteUserData();
00459 __COUT__ << "Turning URL Generation back to default!" << std::endl;
00460
00461
00462 std::ofstream newFile ((SEQUENCE_FILE_NAME).c_str());
00463 newFile << "4" << std::endl;
00464 newFile.close();
00465
00466 generateURL();
00467 std::thread([&](WizardSupervisor *ptr, std::string securityCode)
00468 {printURL(ptr,securityCode);},this,securityCode_).detach();
00469 *out << "Default_URL_Generation";
00470 }
00471 else if(submittedSecurity == "ResetAllUserTooltips")
00472 {
00473 WebUsers::resetAllUserTooltips();
00474 *out << submittedSecurity;
00475 return;
00476 }
00477 else if(submittedSecurity == "DigestAccessAuthentication" ||
00478 submittedSecurity == "NoSecurity")
00479 {
00480 std::ofstream writeSecurityFile;
00481
00482 writeSecurityFile.open(securityFileName.c_str());
00483 if(writeSecurityFile.is_open())
00484 writeSecurityFile << submittedSecurity;
00485 else
00486 __COUT__ << "Error writing file!" << std::endl;
00487
00488 writeSecurityFile.close();
00489 }
00490 else
00491 {
00492 __COUT_ERR__ << "Invalid submittedSecurity string: " <<
00493 submittedSecurity << std::endl;
00494 *out << "Error";
00495 return;
00496 }
00497 }
00498
00499
00500
00501 std::ifstream securityFile;
00502 std::string line;
00503 std::string security = "";
00504 int lineNumber = 0;
00505
00506 securityFile.open(securityFileName.c_str());
00507
00508 if(!securityFile)
00509 {
00510 __SS__ << "Error opening file: "<< securityFileName << std::endl;
00511 __COUT_ERR__ << "\n" << ss.str();
00512
00513
00514 security = "DigestAccessAuthentication";
00515 }
00516 if(securityFile.is_open())
00517 {
00518
00519 while(std::getline(securityFile, line))
00520 {
00521 security += line;
00522 lineNumber++;
00523 }
00524
00525
00526
00527 securityFile.close();
00528 }
00529
00530 *out << security;
00531 }