espprotocol.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #pragma warning (disable : 4786)
  14. #include "esphttp.hpp"
  15. #include "platform.h"
  16. #include "espprotocol.hpp"
  17. #include "espbinding.hpp"
  18. #ifdef _USE_OPENLDAP
  19. #include "ldapsecurity.ipp"
  20. #endif
  21. typedef IXslProcessor * (*getXslProcessor_func)();
  22. static atomic_t gActiveRequests;
  23. long ActiveRequests::getCount()
  24. {
  25. return atomic_read(&gActiveRequests);
  26. }
  27. void ActiveRequests::inc()
  28. {
  29. atomic_inc(&gActiveRequests);
  30. }
  31. void ActiveRequests::dec()
  32. {
  33. atomic_dec(&gActiveRequests);
  34. }
  35. CEspApplicationPort::CEspApplicationPort(bool viewcfg, CEspProtocol* prot) : viewConfig(viewcfg), rootAuth(false), navWidth(165), navResize(false), navScroll(false), protocol(prot)
  36. {
  37. build_ver = getBuildVersion();
  38. hxsl = LoadSharedObject(SharedObjectPrefix "xmllib" SharedObjectExtension, true, false);
  39. if (!hxsl)
  40. OWARNLOG("Loading xmllib shared library failed!");
  41. else
  42. {
  43. getXslProcessor_func xslfactory = (getXslProcessor_func) GetSharedProcedure(hxsl, "getXslProcessor");
  44. if (!xslfactory)
  45. OWARNLOG("Loading procedure from xmllib shared library failed!");
  46. else
  47. xslp.setown(xslfactory());
  48. }
  49. }
  50. void CEspApplicationPort::appendBinding(CEspBindingEntry* entry, bool isdefault)
  51. {
  52. WriteLockBlock wblock(rwLock);
  53. bindings.append(*entry);
  54. if (isdefault)
  55. defBinding = entry;
  56. EspHttpBinding *httpbind = dynamic_cast<EspHttpBinding *>(entry->queryBinding());
  57. if (httpbind)
  58. {
  59. if (!rootAuth)
  60. rootAuth = httpbind->rootAuthRequired();
  61. int width=0;
  62. bool resizable=false;
  63. bool scroll=false;
  64. httpbind->getNavSettings(width, resizable, scroll);
  65. if (navWidth<width)
  66. navWidth=width;
  67. if (!navResize)
  68. navResize=resizable;
  69. if (!navScroll)
  70. navScroll=scroll;
  71. }
  72. }
  73. void CEspApplicationPort::removeBinding(IEspRpcBinding* binding)
  74. {
  75. CEspBindingEntry* targetEntry = nullptr;
  76. {
  77. WriteLockBlock wblock(rwLock);
  78. ForEachItemInRev(i, bindings)
  79. {
  80. IEspRpcBinding* currentBinding = bindings.item(i).queryBinding();
  81. if (currentBinding && currentBinding == binding)
  82. {
  83. if (defBinding == &bindings.item(i))
  84. defBinding = nullptr;
  85. bindings.remove(i);
  86. break;
  87. }
  88. }
  89. }
  90. }
  91. const StringBuffer &CEspApplicationPort::getAppFrameHtml(time_t &modified, const char *inner, StringBuffer &html, IEspContext* ctx)
  92. {
  93. if (!xslp)
  94. throw MakeStringException(0,"Error - CEspApplicationPort XSLT processor not initialized");
  95. bool embedded_url=(inner&&*inner);
  96. StringBuffer params;
  97. bool needRefresh = true;
  98. if (!getUrlParams(ctx->queryRequestParameters(), params))
  99. {
  100. if (params.length()==0)
  101. needRefresh = false;
  102. if (ctx->getClientVersion()>0)
  103. {
  104. params.appendf("%cver_=%g", params.length()?'&':'?', ctx->getClientVersion());
  105. needRefresh = true;
  106. }
  107. }
  108. if (needRefresh || embedded_url || !appFrameHtml.length())
  109. {
  110. int passwordDaysRemaining = scPasswordExpired;//-1 means dont display change password screen
  111. #ifdef _USE_OPENLDAP
  112. ISecUser* user = ctx->queryUser();
  113. ISecManager* secmgr = ctx->querySecManager();
  114. if(user && secmgr)
  115. {
  116. passwordDaysRemaining = user->getPasswordDaysRemaining();//-1 if expired, -2 if never expires
  117. int passwordExpirationDays = (int)secmgr->getPasswordExpirationWarningDays();
  118. if (passwordDaysRemaining == scPasswordNeverExpires || passwordDaysRemaining > passwordExpirationDays)
  119. passwordDaysRemaining = scPasswordExpired;
  120. }
  121. #endif
  122. StringBuffer xml;
  123. StringBuffer encoded_inner;
  124. if(inner && *inner)
  125. encodeXML(inner, encoded_inner);
  126. // replace & with &amps;
  127. params.replaceString("&","&amp;");
  128. xml.appendf("<EspApplicationFrame title=\"%s\" navWidth=\"%d\" navResize=\"%d\" navScroll=\"%d\" inner=\"%s\" params=\"%s\" passwordDays=\"%d\"/>",
  129. getESPContainer()->getFrameTitle(), navWidth, navResize, navScroll, (inner&&*inner) ? encoded_inner.str() : "?main", params.str(), passwordDaysRemaining);
  130. Owned<IXslTransform> xform = xslp->createXslTransform();
  131. xform->loadXslFromFile(StringBuffer(getCFD()).append("./xslt/appframe.xsl").str());
  132. xform->setXmlSource(xml.str(), xml.length()+1);
  133. xform->transform( (needRefresh || embedded_url) ? html.clear() : appFrameHtml.clear());
  134. }
  135. if (!needRefresh && !embedded_url)
  136. html.clear().append(appFrameHtml.str());
  137. static time_t startup_time = time(NULL);
  138. modified = startup_time;
  139. return html;
  140. }
  141. const StringBuffer &CEspApplicationPort::getTitleBarHtml(IEspContext& ctx, bool rawXml)
  142. {
  143. if (xslp)
  144. {
  145. VStringBuffer titleBarXml("<EspHeader><BuildVersion>%s</BuildVersion><ConfigAccess>%d</ConfigAccess>", build_ver, viewConfig);
  146. const char* authMethod = ctx.getAuthenticationMethod();
  147. if (authMethod && !strieq(authMethod, "none") && (ctx.getDomainAuthType() != AuthPerRequestOnly))
  148. titleBarXml.append("<LogOut>1</LogOut>");
  149. const char* user = ctx.queryUserId();
  150. if (user && *user)
  151. titleBarXml.appendf("<LoginId>%s</LoginId>", user);
  152. titleBarXml.append("</EspHeader>");
  153. if (rawXml)
  154. {
  155. titleBarHtml.set(titleBarXml);
  156. }
  157. else
  158. {
  159. Owned<IXslTransform> xform = xslp->createXslTransform();
  160. xform->loadXslFromFile(StringBuffer(getCFD()).append("./xslt/espheader.xsl").str());
  161. xform->setXmlSource(titleBarXml.str(), titleBarXml.length()+1);
  162. xform->transform(titleBarHtml.clear());
  163. }
  164. }
  165. return titleBarHtml;
  166. }
  167. const StringBuffer &CEspApplicationPort::getNavBarContent(IEspContext &context, StringBuffer &content, StringBuffer &contentType, bool rawxml)
  168. {
  169. if (xslp)
  170. {
  171. Owned<IPropertyTree> navtree=createPTree("EspNavigationData");
  172. {
  173. ReadLockBlock rblock(rwLock);
  174. ForEachItemIn(idx, bindings)
  175. bindings.item(idx).queryBinding()->getNavigationData(context, *navtree.get());
  176. }
  177. StringBuffer xml;
  178. buildNavTreeXML(navtree.get(), xml);
  179. if (rawxml)
  180. {
  181. content.swapWith(xml);
  182. contentType.clear().append(HTTP_TYPE_APPLICATION_XML_UTF8);
  183. }
  184. else
  185. {
  186. const char* viewType = navtree->queryProp("@viewType");
  187. Owned<IXslTransform> xform = xslp->createXslTransform();
  188. StringBuffer xslsource;
  189. if (viewType && *viewType)
  190. {
  191. xslsource.append(getCFD()).appendf("./xslt/%s.xsl", stricmp(viewType, "tree") != 0 ? viewType: "navigation");
  192. }
  193. else
  194. {
  195. xslsource.append(getCFD()).append("./xslt/nav.xsl");
  196. }
  197. xform->loadXslFromFile(xslsource.str());
  198. xform->setXmlSource(xml.str(), xml.length()+1);
  199. xform->transform(content);
  200. contentType.clear().append("text/html; charset=UTF-8");
  201. }
  202. }
  203. return content;
  204. }
  205. const StringBuffer &CEspApplicationPort::getDynNavData(IEspContext &context, IProperties *params, StringBuffer &content,
  206. StringBuffer &contentType, bool& bVolatile)
  207. {
  208. Owned<IPropertyTree> navtree=createPTree("EspDynNavData");
  209. bVolatile = false;
  210. {
  211. ReadLockBlock rblock(rwLock);
  212. ForEachItemIn(idx, bindings)
  213. bindings.item(idx).queryBinding()->getDynNavData(context, params, *navtree.get());
  214. }
  215. if (!bVolatile)
  216. bVolatile = navtree->getPropBool("@volatile", false);
  217. contentType.clear().append(HTTP_TYPE_APPLICATION_XML_UTF8);
  218. return toXML(navtree.get(), content.clear());
  219. }
  220. int CEspApplicationPort::onGetNavEvent(IEspContext &context, IHttpMessage* request, IHttpMessage* response)
  221. {
  222. int handled=0;
  223. ReadLockBlock rblock(rwLock);
  224. for (int idx = 0; !handled && idx < bindings.length(); idx++)
  225. handled = bindings.item(idx).queryBinding()->onGetNavEvent(context, request, response);
  226. return handled;
  227. }
  228. int CEspApplicationPort::onBuildSoapRequest(IEspContext &context, IHttpMessage* ireq, IHttpMessage* iresp)
  229. {
  230. return 0;
  231. }
  232. void CEspApplicationPort::buildNavTreeXML(IPropertyTree* navtree, StringBuffer& xmlBuf, bool insideFolder)
  233. {
  234. if (!navtree)
  235. return;
  236. //Find out the menu items which do not request a specific position
  237. //Also find out the maximum position being requested
  238. unsigned positionMax = 0;
  239. StringArray itemsGroup1;
  240. Owned<IPropertyTreeIterator> items = navtree->getElements("*");
  241. ForEach(*items)
  242. {
  243. IPropertyTree &item = items->query();
  244. unsigned position = (unsigned) item.getPropInt("@relPosition", 0);
  245. if (position > positionMax)
  246. {
  247. positionMax = position;
  248. }
  249. else if (position < 1)
  250. {//if the item does not request a position, add it to the 'itemsGroup1'.
  251. StringBuffer itemXML;
  252. if (!insideFolder)
  253. buildNavTreeXML(&item, itemXML, true);
  254. else
  255. toXML(&item, itemXML);
  256. itemsGroup1.append(itemXML);
  257. }
  258. }
  259. xmlBuf.appendf("<%s", navtree->queryName());
  260. Owned<IAttributeIterator> attrs = navtree->getAttributes();
  261. ForEach(*attrs)
  262. {
  263. const char *attrname = attrs->queryName()+1;
  264. const char *attrvaluee = attrs->queryValue();
  265. if (attrname && *attrname && attrvaluee && *attrvaluee)
  266. xmlBuf.appendf(" %s=\"%s\"", attrname, attrvaluee);
  267. }
  268. xmlBuf.append(">\n");
  269. unsigned positionInGroup1 = 0;
  270. unsigned itemCountInGroup1 = itemsGroup1.length();
  271. //append the menu items based on the position requested
  272. unsigned position = 1;
  273. while (position <= positionMax)
  274. {
  275. bool foundOne = false;
  276. //process the item(s) which asks for this position
  277. StringBuffer xPath;
  278. xPath.appendf("*[@relPosition=%d]", position);
  279. Owned<IPropertyTreeIterator> items1 = navtree->getElements(xPath.str());
  280. ForEach(*items1)
  281. {
  282. IPropertyTree &item = items1->query();
  283. StringBuffer itemXML;
  284. if (!insideFolder)
  285. buildNavTreeXML(&item, itemXML, true);
  286. else
  287. toXML(&item, itemXML);
  288. xmlBuf.append(itemXML.str());
  289. foundOne = true;
  290. }
  291. //If no one asks for this position, pick one from the itemsGroup1
  292. if (!foundOne && (positionInGroup1 < itemCountInGroup1))
  293. {
  294. StringBuffer itemXML(itemsGroup1.item(positionInGroup1));
  295. xmlBuf.append(itemXML.str());
  296. positionInGroup1++;
  297. }
  298. position++;
  299. }
  300. //Check any item left inside the itemsGroup1 and append it into the xml
  301. while (positionInGroup1 < itemCountInGroup1)
  302. {
  303. StringBuffer itemXML(itemsGroup1.item(positionInGroup1));
  304. xmlBuf.append(itemXML.str());
  305. positionInGroup1++;
  306. }
  307. xmlBuf.appendf("</%s>\n", navtree->queryName());
  308. }
  309. IPropertyTree *CEspBinding::ensureNavFolder(IPropertyTree &root, const char *name, const char *tooltip, const char *menuname, bool sort, unsigned relPosition)
  310. {
  311. StringBuffer xpath;
  312. xpath.appendf("Folder[@name=\"%s\"]", name);
  313. IPropertyTree *ret = root.queryPropTree(xpath.str());
  314. if (!ret)
  315. {
  316. ret=createPTree("Folder");
  317. ret->addProp("@name", name);
  318. ret->addProp("@tooltip", tooltip);
  319. ret->setProp("@menu", menuname);
  320. if (sort)
  321. ret->addPropBool("@sort", true);
  322. ret->addPropInt("@relPosition", relPosition);
  323. root.addPropTree("Folder", ret);
  324. }
  325. return ret;
  326. }
  327. IPropertyTree *CEspBinding::ensureNavMenu(IPropertyTree &root, const char *name)
  328. {
  329. StringBuffer xpath;
  330. xpath.appendf("Menu[@name=\"%s\"]", name);
  331. IPropertyTree *ret = root.queryPropTree(xpath.str());
  332. if (!ret)
  333. {
  334. ret=createPTree("Menu");
  335. ret->addProp("@name", name);
  336. root.addPropTree("Menu", ret);
  337. }
  338. return ret;
  339. }
  340. IPropertyTree *CEspBinding::ensureNavMenuItem(IPropertyTree &root, const char *name, const char *tooltip, const char *action)
  341. {
  342. StringBuffer xpath;
  343. xpath.appendf("MenuItem[@name=\"%s\"]", name);
  344. IPropertyTree *ret = root.queryPropTree(xpath.str());
  345. if (!ret)
  346. {
  347. ret=createPTree("MenuItem");
  348. ret->addProp("@name", name);
  349. ret->addProp("@tooltip", tooltip);
  350. ret->addProp("@action", action);
  351. root.addPropTree("MenuItem", ret);
  352. }
  353. return ret;
  354. }
  355. IPropertyTree *CEspBinding::ensureNavDynFolder(IPropertyTree &root, const char *name, const char *tooltip, const char *params, const char *menuname)
  356. {
  357. StringBuffer xpath;
  358. xpath.appendf("DynamicFolder[@name=\"%s\"]", name);
  359. IPropertyTree *ret = root.queryPropTree(xpath.str());
  360. if (!ret)
  361. {
  362. ret=createPTree("DynamicFolder");
  363. ret->addProp("@name", name);
  364. ret->addProp("@tooltip", tooltip);
  365. ret->addProp("@params", params);
  366. ret->setProp("@menu", menuname);
  367. root.addPropTree("DynamicFolder", ret);
  368. }
  369. return ret;
  370. }
  371. IPropertyTree *CEspBinding::ensureNavLink(IPropertyTree &folder, const char *name, const char *path, const char *tooltip, const char *menuname, const char *navPath, unsigned relPosition, bool force)
  372. {
  373. StringBuffer xpath;
  374. xpath.appendf("Link[@name=\"%s\"]", name);
  375. bool addNew = true;
  376. IPropertyTree *ret = folder.queryPropTree(xpath.str());
  377. if (ret)
  378. {
  379. bool forced = ret->getPropBool("@force");
  380. if (forced || !force)
  381. return ret;
  382. addNew = false;
  383. }
  384. if (addNew)
  385. ret=createPTree("Link");
  386. ret->setProp("@name", name);
  387. ret->setProp("@tooltip", tooltip);
  388. ret->setProp("@path", path);
  389. ret->setProp("@menu", menuname);
  390. ret->setProp("@navPath", navPath);
  391. ret->setPropInt("@relPosition", relPosition);
  392. ret->setPropBool("@force", force);
  393. if (addNew)
  394. folder.addPropTree("Link", ret);
  395. return ret;
  396. }
  397. IPropertyTree *CEspBinding::addNavException(IPropertyTree &folder, const char *message/*=NULL*/, int code/*=0*/, const char *source/*=NULL*/)
  398. {
  399. IPropertyTree *ret = folder.addPropTree("Exception", createPTree());
  400. ret->addProp("@message", message ? message : "Unknown exception");
  401. ret->setPropInt("@code", code);
  402. ret->setProp("@source", source);
  403. return ret;
  404. }
  405. void CEspBinding::getNavigationData(IEspContext &context, IPropertyTree & data)
  406. {
  407. IEspWsdlSections *wsdl = dynamic_cast<IEspWsdlSections *>(this);
  408. if (wsdl)
  409. {
  410. StringBuffer serviceName, params;
  411. wsdl->getServiceName(serviceName);
  412. if (!getUrlParams(context.queryRequestParameters(), params))
  413. {
  414. if (context.getClientVersion()>0)
  415. params.appendf("%cver_=%g", params.length()?'&':'?', context.getClientVersion());
  416. }
  417. StringBuffer encodedparams;
  418. if (params.length())
  419. encodeUtf8XML(params.str(), encodedparams, 0);
  420. if (params.length())
  421. params.setCharAt(0,'&'); //the entire params string will follow the initial param: "?form"
  422. VStringBuffer folderpath("Folder[@name='%s']", serviceName.str());
  423. IPropertyTree *folder = data.queryPropTree(folderpath.str());
  424. if(!folder)
  425. {
  426. folder=createPTree("Folder");
  427. folder->addProp("@name", serviceName.str());
  428. folder->addProp("@info", serviceName.str());
  429. folder->addProp("@urlParams", encodedparams);
  430. if (showSchemaLinks())
  431. folder->addProp("@showSchemaLinks", "true");
  432. folder->addPropBool("@isDynamicBinding", isDynamicBinding());
  433. folder->addPropBool("@isBound", isBound());
  434. data.addPropTree("Folder", folder);
  435. }
  436. MethodInfoArray methods;
  437. wsdl->getQualifiedNames(context, methods);
  438. ForEachItemIn(idx, methods)
  439. {
  440. CMethodInfo &method = methods.item(idx);
  441. IPropertyTree *link=createPTree("Link");
  442. link->addProp("@name", method.m_label.str());
  443. link->addProp("@info", method.m_label.str());
  444. StringBuffer path;
  445. path.appendf("../%s/%s?form%s", serviceName.str(), method.m_label.str(),params.str());
  446. link->addProp("@path", path.str());
  447. folder->addPropTree("Link", link);
  448. }
  449. }
  450. }
  451. void CEspBinding::getDynNavData(IEspContext &context, IProperties *params, IPropertyTree & data)
  452. {
  453. }
  454. #ifdef _USE_OPENLDAP
  455. void CEspApplicationPort::onUpdatePasswordInput(IEspContext &context, StringBuffer& html)
  456. {
  457. StringBuffer xml;
  458. if (context.queryUserId())
  459. xml.appendf("<UpdatePassword><username>%s</username><Code>-1</Code></UpdatePassword>", context.queryUserId());
  460. else
  461. xml.appendf("<UpdatePassword><Code>2</Code><Massage>Can't find user in esp context. Please check if the user was properly logged in.</Massage></UpdatePassword>");
  462. Owned<IXslTransform> xform = xslp->createXslTransform();
  463. xform->loadXslFromFile(StringBuffer(getCFD()).append("./xslt/passwordupdate.xsl").str());
  464. xform->setXmlSource(xml.str(), xml.length()+1);
  465. xform->transform( html);
  466. return;
  467. }
  468. unsigned CEspApplicationPort::onUpdatePassword(IEspContext &context, IHttpMessage* request, StringBuffer& html)
  469. {
  470. StringBuffer xml, message;
  471. unsigned returnCode = updatePassword(context, request, message);
  472. if (context.queryUserId())
  473. xml.appendf("<UpdatePassword><username>%s</username>", context.queryUserId());
  474. else
  475. xml.appendf("<UpdatePassword><username/>");
  476. xml.appendf("<Code>%d</Code><Message>%s</Message></UpdatePassword>", returnCode, message.str());
  477. Owned<IXslTransform> xform = xslp->createXslTransform();
  478. xform->loadXslFromFile(StringBuffer(getCFD()).append("./xslt/passwordupdate.xsl").str());
  479. xform->setXmlSource(xml.str(), xml.length()+1);
  480. xform->transform( html);
  481. return returnCode;
  482. }
  483. unsigned CEspApplicationPort::updatePassword(IEspContext &context, IHttpMessage* request, StringBuffer& message)
  484. {
  485. ISecManager* secmgr = context.querySecManager();
  486. if(!secmgr)
  487. {
  488. message.append("Security manager is not found. Please check if the system authentication is set up correctly.");
  489. return 2;
  490. }
  491. ISecUser* user = context.queryUser();
  492. if(!user)
  493. {
  494. message.append("Can't find user in esp context. Please check if the user was properly logged in.");
  495. return 2;
  496. }
  497. CHttpRequest *httpRequest=dynamic_cast<CHttpRequest*>(request);
  498. IProperties *params = httpRequest->getParameters();
  499. if (!params)
  500. {
  501. message.append("No parameter is received. Please check user input.");
  502. return 1;
  503. }
  504. const char* username = params->queryProp("username");
  505. const char* oldpass = params->queryProp("oldpass");
  506. const char* newpass1 = params->queryProp("newpass1");
  507. const char* newpass2 = params->queryProp("newpass2");
  508. if(!username || !streq(username, user->getName()))
  509. {
  510. message.append("Incorrect username has been received.");
  511. return 1;
  512. }
  513. if(!streq(newpass1, newpass2))
  514. {
  515. message.append("Password re-entry doesn't match.");
  516. return 1;
  517. }
  518. if(streq(oldpass, newpass1))
  519. {
  520. message.append("New password can't be the same as current password.");
  521. return 1;
  522. }
  523. bool returnFlag = false;
  524. try
  525. {
  526. ISecCredentials& cred = user->credentials();
  527. if (isEmptyString(cred.getPassword()))
  528. cred.setPassword(oldpass);
  529. returnFlag = secmgr->updateUserPassword(*user, newpass1, oldpass);//provide the entered current password, not the cached one
  530. }
  531. catch(IException* e)
  532. {
  533. StringBuffer emsg;
  534. e->errorMessage(emsg);
  535. message.append(emsg.str());
  536. return 2;
  537. }
  538. if(!returnFlag)
  539. {
  540. message.append("Failed in changing password.");
  541. return 2;
  542. }
  543. message.append("Your password has been changed successfully.");
  544. return 0;
  545. }
  546. #endif
  547. CEspProtocol::CEspProtocol()
  548. {
  549. m_viewConfig=false;
  550. m_MaxRequestEntityLength = DEFAULT_MAX_REQUEST_ENTITY_LENGTH;
  551. }
  552. CEspProtocol::~CEspProtocol()
  553. {
  554. clear();
  555. if(m_persistentHandler)
  556. m_persistentHandler->stop(true);
  557. }
  558. bool CEspProtocol::notifySelected(ISocket *sock,unsigned selected)
  559. {
  560. return notifySelected(sock, selected, nullptr, false);
  561. }
  562. const char * CEspProtocol::getProtocolName()
  563. {
  564. return "ESP Protocol";
  565. }
  566. void CEspProtocol::addBindingMap(ISocket *sock, IEspRpcBinding* binding, bool isdefault)
  567. {
  568. CEspBindingEntry *entry = new CEspBindingEntry(sock, binding);
  569. char name[256];
  570. int port = sock->name(name, 255);
  571. {
  572. WriteLockBlock wblock(rwLock);
  573. CApplicationPortMap::iterator apport_it = m_portmap.find(port);
  574. CEspApplicationPort *apport = nullptr;
  575. if (apport_it!=m_portmap.end())
  576. {
  577. apport = (*apport_it).second;
  578. apport->appendBinding(entry, isdefault);
  579. }
  580. else
  581. {
  582. apport = new CEspApplicationPort(m_viewConfig, this);
  583. apport->appendBinding(entry, isdefault);
  584. CApplicationPortMap::value_type vt(port, apport);
  585. m_portmap.insert(vt);
  586. }
  587. }
  588. }
  589. CEspApplicationPort* CEspProtocol::queryApplicationPort(int port)
  590. {
  591. ReadLockBlock rblock(rwLock);
  592. CApplicationPortMap::iterator apport_it = m_portmap.find(port);
  593. return (apport_it != m_portmap.end()) ? (*apport_it).second : NULL;
  594. }
  595. void CEspProtocol::addPersistent(ISocket* sock)
  596. {
  597. if (m_persistentHandler != nullptr)
  598. m_persistentHandler->add(sock);
  599. }
  600. void CEspProtocol::initPersistentHandler(IPropertyTree * proc_cfg)
  601. {
  602. const char* idleTimeStr = nullptr;
  603. const char* maxReqsStr = nullptr;
  604. if (proc_cfg != nullptr)
  605. {
  606. idleTimeStr = proc_cfg->queryProp("@maxPersistentIdleTime");
  607. maxReqsStr = proc_cfg->queryProp("@maxPersistentRequests");
  608. }
  609. //To disable persistent connections, set maxPersistentIdleTime or maxPersistentRequests to 0
  610. int maxIdleTime = DEFAULT_MAX_PERSISTENT_IDLE_TIME;
  611. if (idleTimeStr != nullptr && *idleTimeStr != '\0')
  612. maxIdleTime = atoi(idleTimeStr);
  613. int maxReqs = DEFAULT_MAX_PERSISTENT_REQUESTS;
  614. if (maxReqsStr != nullptr && *maxReqsStr != '\0')
  615. maxReqs = atoi(maxReqsStr);
  616. if (maxIdleTime == 0 || maxReqs == 0)
  617. {
  618. OWARNLOG("Persistent connection won't be enabled because maxPersistentIdleTime or maxPersistentRequests is set to 0");
  619. return;
  620. }
  621. m_persistentHandler.setown(createPersistentHandler(this, maxIdleTime, maxReqs, static_cast<PersistentLogLevel>(getEspLogLevel())));
  622. }
  623. int CEspProtocol::removeBindingMap(int port, IEspRpcBinding* binding)
  624. {
  625. WriteLockBlock wblock(rwLock);
  626. CApplicationPortMap::iterator apport_it = m_portmap.find(port);
  627. int left = 0;
  628. if (apport_it!=m_portmap.end())
  629. {
  630. CEspApplicationPort* apport = (*apport_it).second;
  631. apport->removeBinding(binding);
  632. left = apport->getBindingCount();
  633. if (left == 0)
  634. {
  635. delete apport;
  636. m_portmap.erase(apport_it);
  637. }
  638. }
  639. return left;
  640. }
  641. int CEspProtocol::countBindings(int port)
  642. {
  643. ReadLockBlock rblock(rwLock);
  644. CEspApplicationPort* apport = queryApplicationPort(port);
  645. if (!apport)
  646. return 0;
  647. else
  648. return apport->getBindingCount();
  649. }