001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.config; 020 021import java.io.ByteArrayInputStream; 022import java.io.File; 023import java.io.IOException; 024import java.io.InputStream; 025import java.io.UnsupportedEncodingException; 026import java.net.MalformedURLException; 027import java.net.URL; 028import java.util.ArrayList; 029import java.util.HashSet; 030import java.util.Iterator; 031import java.util.List; 032import java.util.Map; 033import java.util.Map.Entry; 034import java.util.Set; 035 036import javax.servlet.ServletException; 037 038import lucee.commons.digest.MD5; 039import lucee.commons.io.FileUtil; 040import lucee.commons.io.IOUtil; 041import lucee.commons.io.SystemUtil; 042import lucee.commons.io.cache.Cache; 043import lucee.commons.io.log.log4j.appender.ConsoleAppender; 044import lucee.commons.io.log.log4j.appender.RollingResourceAppender; 045import lucee.commons.io.log.log4j.layout.ClassicLayout; 046import lucee.commons.io.res.Resource; 047import lucee.commons.io.res.ResourceProvider; 048import lucee.commons.io.res.filter.ResourceNameFilter; 049import lucee.commons.io.res.type.s3.S3ResourceProvider; 050import lucee.commons.io.res.util.ResourceUtil; 051import lucee.commons.lang.ClassException; 052import lucee.commons.lang.ClassUtil; 053import lucee.commons.lang.ExceptionUtil; 054import lucee.commons.lang.StringUtil; 055import lucee.commons.lang.SystemOut; 056import lucee.commons.net.HTTPUtil; 057import lucee.commons.net.IPRange; 058import lucee.commons.net.URLEncoder; 059import lucee.commons.net.http.HTTPEngine; 060import lucee.commons.net.http.HTTPResponse; 061import lucee.loader.engine.CFMLEngineFactory; 062import lucee.loader.util.ExtensionFilter; 063import lucee.runtime.Info; 064import lucee.runtime.PageContext; 065import lucee.runtime.cache.CacheConnection; 066import lucee.runtime.cache.eh.EHCache; 067import lucee.runtime.cfx.CFXTagException; 068import lucee.runtime.cfx.CFXTagPool; 069import lucee.runtime.converter.ConverterException; 070import lucee.runtime.converter.WDDXConverter; 071import lucee.runtime.db.DataSource; 072import lucee.runtime.exp.ApplicationException; 073import lucee.runtime.exp.ExpressionException; 074import lucee.runtime.exp.HTTPException; 075import lucee.runtime.exp.PageException; 076import lucee.runtime.exp.SecurityException; 077import lucee.runtime.extension.Extension; 078import lucee.runtime.extension.RHExtension; 079import lucee.runtime.functions.cache.Util; 080import lucee.runtime.functions.other.CreateObject; 081import lucee.runtime.functions.other.CreateUUID; 082import lucee.runtime.functions.other.URLEncodedFormat; 083import lucee.runtime.functions.string.Hash; 084import lucee.runtime.gateway.GatewayEntry; 085import lucee.runtime.gateway.GatewayEntryImpl; 086import lucee.runtime.listener.AppListenerUtil; 087import lucee.runtime.net.ntp.NtpClient; 088import lucee.runtime.op.Caster; 089import lucee.runtime.op.Decision; 090import lucee.runtime.orm.ORMConfiguration; 091import lucee.runtime.orm.ORMConfigurationImpl; 092import lucee.runtime.reflection.Reflector; 093import lucee.runtime.security.SecurityManager; 094import lucee.runtime.security.SecurityManagerImpl; 095import lucee.runtime.security.SerialNumber; 096import lucee.runtime.text.xml.XMLCaster; 097import lucee.runtime.text.xml.XMLUtil; 098import lucee.runtime.type.Array; 099import lucee.runtime.type.ArrayImpl; 100import lucee.runtime.type.Collection.Key; 101import lucee.runtime.type.KeyImpl; 102import lucee.runtime.type.Query; 103import lucee.runtime.type.QueryImpl; 104import lucee.runtime.type.Struct; 105import lucee.runtime.type.dt.TimeSpan; 106import lucee.runtime.type.scope.Cluster; 107import lucee.runtime.type.scope.ClusterNotSupported; 108import lucee.runtime.type.scope.ClusterRemote; 109import lucee.runtime.type.scope.ScopeContext; 110import lucee.runtime.type.util.ArrayUtil; 111import lucee.runtime.type.util.ComponentUtil; 112import lucee.runtime.type.util.ListUtil; 113import lucee.runtime.video.VideoExecuter; 114import lucee.runtime.video.VideoExecuterNotSupported; 115import lucee.transformer.library.function.FunctionLibException; 116import lucee.transformer.library.tag.TagLibException; 117 118import org.apache.log4j.HTMLLayout; 119import org.apache.log4j.Level; 120import org.apache.log4j.PatternLayout; 121import org.apache.log4j.xml.XMLLayout; 122import org.apache.xerces.parsers.DOMParser; 123import org.w3c.dom.DOMException; 124import org.w3c.dom.Document; 125import org.w3c.dom.Element; 126import org.xml.sax.InputSource; 127import org.xml.sax.SAXException; 128 129import com.allaire.cfx.CustomTag; 130 131/** 132 * 133 */ 134public final class ConfigWebAdmin { 135 136 //private static final Object NULL = new Object(); 137 private ConfigImpl config; 138 private Document doc; 139 private String password; 140 //private SecurityManager accessorx; 141 142 143 /** 144 * 145 * @param config 146 * @param password 147 * @return returns a new instance of the class 148 * @throws SAXException 149 * @throws IOException 150 */ 151 public static ConfigWebAdmin newInstance(ConfigImpl config, String password) throws SAXException, IOException { 152 return new ConfigWebAdmin(config, password); 153 } 154 155 156 private void checkWriteAccess() throws SecurityException { 157 ConfigWebUtil.checkGeneralWriteAccess(config,password); 158 } 159 private void checkReadAccess() throws SecurityException { 160 ConfigWebUtil.checkGeneralReadAccess(config,password); 161 } 162 163 /** 164 * @param password 165 * @throws IOException 166 * @throws DOMException 167 * @throws ExpressionException 168 */ 169 public void setPassword(Password password) throws SecurityException, DOMException, IOException { 170 checkWriteAccess(); 171 Password.store(doc.getDocumentElement(), password, false); 172 } 173 174 public void setVersion(double version) { 175 setVersion(doc,version); 176 177 } 178 public static void setVersion(Document doc,double version) { 179 Element root=doc.getDocumentElement(); 180 String str = Caster.toString(version); 181 if(str.length()>3)str=str.substring(0,3); 182 root.setAttribute("version",str); 183 184 } 185 /*public void setId(String id) { 186 187 Element root=doc.getDocumentElement(); 188 if(!StringUtil.isEmpty(root.getAttribute("id"))) return; 189 root.setAttribute("id",id); 190 try { 191 store(config); 192 } 193 catch (Exception e) {} 194 }*/ 195 196 /** 197 * @param contextPath 198 * @param password 199 * @throws FunctionLibException 200 * @throws TagLibException 201 * @throws IOException 202 * @throws ClassNotFoundException 203 * @throws SAXException 204 * @throws PageException 205 */ 206 public void removePassword(String contextPath) throws PageException, SAXException, ClassException, IOException, TagLibException, FunctionLibException { 207 checkWriteAccess(); 208 if(contextPath==null || contextPath.length()==0 || !(config instanceof ConfigServerImpl)) { 209 // config.setPassword(password); do nothing! 210 } 211 else { 212 ConfigServerImpl cs=(ConfigServerImpl)config; 213 ConfigWebImpl cw=cs.getConfigWebImpl(contextPath); 214 if(cw!=null)cw.updatePassword(false,cw.getPassword(),null); 215 } 216 } 217 218 private ConfigWebAdmin(ConfigImpl config, String password) throws SAXException, IOException { 219 this.config=config; 220 this.password=password; 221 doc=loadDocument(config.getConfigFile()); 222 //setId(config.getId()); 223 } 224 225 public static void checkForChangesInConfigFile(Config config) { 226 ConfigImpl ci=(ConfigImpl) config; 227 if(!ci.checkForChangesInConfigFile()) return; 228 229 Resource file = config.getConfigFile(); 230 long diff=file.lastModified()-ci.lastModified(); 231 if(diff<10 && diff>-10) return; 232 // reload 233 try { 234 ConfigWebAdmin admin = ConfigWebAdmin.newInstance(ci, null); 235 admin.reload(ci, false); 236 SystemOut.printDate(ci.getOutWriter(), "reloaded the configuration ["+file+"] automaticly"); 237 } 238 catch (Throwable t) { 239 ExceptionUtil.rethrowIfNecessary(t); 240 t.printStackTrace(); 241 } 242 } 243 244 245 246 private void addResourceProvider(String scheme,String clazz,String arguments) throws SecurityException { 247 checkWriteAccess(); 248 249 Element resources=_getRootElement("resources"); 250 Element[] rpElements = ConfigWebFactory.getChildren(resources,"resource-provider"); 251 String s; 252 // update 253 if(rpElements!=null) { 254 for(int i=0;i<rpElements.length;i++) { 255 s=rpElements[i].getAttribute("scheme"); 256 if(!StringUtil.isEmpty(s) && s.equalsIgnoreCase(scheme)) { 257 rpElements[i].setAttribute("class", clazz); 258 rpElements[i].setAttribute("scheme", scheme); 259 rpElements[i].setAttribute("arguments", arguments); 260 return; 261 } 262 } 263 } 264 // Insert 265 Element el=doc.createElement("resource-provider"); 266 resources.appendChild(XMLCaster.toRawNode(el)); 267 el.setAttribute("class", clazz); 268 el.setAttribute("scheme", scheme); 269 el.setAttribute("arguments", arguments); 270 } 271 272 273 /** 274 * load XML Document from XML File 275 * @param config 276 * @param xmlFile XML File to read 277 * @return returns the Document 278 * @throws SAXException 279 * @throws IOException 280 */ 281 private static Document loadDocument(Resource xmlFile) throws SAXException, IOException { 282 DOMParser parser = new DOMParser(); 283 InputStream is=null; 284 try { 285 is = IOUtil.toBufferedInputStream(xmlFile.getInputStream()); 286 InputSource source = new InputSource(is); 287 parser.parse(source); 288 } 289 finally { 290 IOUtil.closeEL(is); 291 } 292 return parser.getDocument(); 293 } 294 295 private static synchronized void _store(ConfigImpl config) throws PageException, SAXException, ClassException, IOException, TagLibException, FunctionLibException { 296 ConfigWebAdmin admin = new ConfigWebAdmin(config, null); 297 admin._reload(config, true); 298 } 299 300 private synchronized void _store() throws PageException, SAXException, ClassException, IOException, TagLibException, FunctionLibException { 301 _reload(config, true); 302 } 303 304 public synchronized void store() throws PageException, SAXException, ClassException, IOException, TagLibException, FunctionLibException { 305 reload(config, true); 306 } 307 308 private synchronized void reload(ConfigImpl config, boolean storeInMemoryData) throws PageException, SAXException, ClassException, IOException, TagLibException, FunctionLibException { 309 if(storeInMemoryData)checkWriteAccess(); 310 _reload(config, storeInMemoryData); 311 } 312 313 private synchronized void _reload(ConfigImpl config, boolean storeInMemoryData) throws PageException, SAXException, ClassException, IOException, TagLibException, FunctionLibException { 314 renameOldstyleCFX(); 315 316 createAbort(); 317 if(config instanceof ConfigServerImpl) { 318 if(storeInMemoryData)XMLCaster.writeTo(doc,config.getConfigFile()); 319 320 ConfigServerImpl cs=(ConfigServerImpl) config; 321 ConfigServerFactory.reloadInstance(cs); 322 ConfigWeb[] webs=cs.getConfigWebs(); 323 for(int i=0;i<webs.length;i++) { 324 ConfigWebFactory.reloadInstance((ConfigServerImpl) config,(ConfigWebImpl)webs[i],true); 325 } 326 } 327 else { 328 if(storeInMemoryData)XMLCaster.writeTo(doc,config.getConfigFile()); 329 //SystemUtil.sleep(10); 330 ConfigServerImpl cs=((ConfigWebImpl)config).getConfigServerImpl(); 331 332 ConfigWebFactory.reloadInstance(cs,(ConfigWebImpl)config,false); 333 } 334 } 335 336 337 338 339 private void createAbort() { 340 try { 341 ConfigWebFactory.getChildByName(doc.getDocumentElement(),"cfabort",true); 342 } 343 catch(Throwable t) { 344 ExceptionUtil.rethrowIfNecessary(t); 345 } 346 } 347 348 349 public void setTaskMaxThreads(Integer maxThreads) throws SecurityException { 350 checkWriteAccess(); 351 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 352 if(!hasAccess) 353 throw new SecurityException("no access to update task settings"); 354 Element mail=_getRootElement("remote-clients"); 355 mail.setAttribute("max-threads",Caster.toString(maxThreads,"")); 356 } 357 358 /** 359 * sets Mail Logger to Config 360 * @param logFile 361 * @param level 362 * @throws PageException 363 */ 364 public void setMailLog(String logFile, String level) throws PageException { 365 checkWriteAccess(); 366 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_MAIL); 367 368 if(!hasAccess) 369 throw new SecurityException("no access to update mail server settings"); 370 ConfigWebUtil.getFile(config,config.getRootDirectory(),logFile,FileUtil.TYPE_FILE); 371 372 373 Element logging = ConfigWebFactory.getChildByName(doc.getDocumentElement(), "logging"); 374 Element[] children = XMLUtil.getChildElementsAsArray(logging); 375 Element logger=null; 376 377 for(int i=0;i<children.length;i++){ 378 if(children[i].getTagName().equals("logger") && "mail".equalsIgnoreCase(children[i].getAttribute("name"))) { 379 logger=children[i]; 380 break; 381 } 382 } 383 if(logger==null) { 384 logger = doc.createElement("logger"); 385 logging.appendChild(logger); 386 } 387 logger.setAttribute("name", "mail"); 388 if("console".equalsIgnoreCase(logFile)) { 389 logger.setAttribute("appender", "console"); 390 logger.setAttribute("layout", "pattern"); 391 } 392 else { 393 logger.setAttribute("appender", "resource"); 394 logger.setAttribute("appender-arguments", "path:"+logFile); 395 logger.setAttribute("layout", "classic"); 396 } 397 logger.setAttribute("log-level",level); 398 } 399 400 /** 401 * sets if spool is enable or not 402 * @param spoolEnable 403 * @throws SecurityException 404 */ 405 public void setMailSpoolEnable(Boolean spoolEnable) throws SecurityException { 406 checkWriteAccess(); 407 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_MAIL); 408 409 if(!hasAccess) 410 throw new SecurityException("no access to update mail server settings"); 411 Element mail=_getRootElement("mail"); 412 mail.setAttribute("spool-enable",Caster.toString(spoolEnable,"")); 413 //config.setMailSpoolEnable(spoolEnable); 414 } 415 416 417 418 /* * 419 * sets if er interval is enable or not 420 * @param interval 421 * @throws SecurityException 422 * / 423 public void setMailSpoolInterval(Integer interval) throws SecurityException { 424 checkWriteAccess(); 425 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_MAIL); 426 if(!hasAccess) 427 throw new SecurityException("no access to update mail server settings"); 428 Element mail=_getRootElement("mail"); 429 mail.setAttribute("spool-interval",Caster.toString(interval,"")); 430 //config.setMailSpoolInterval(interval); 431 }*/ 432 433 /** 434 * sets the timeout for the spooler for one job 435 * @param timeout 436 * @throws SecurityException 437 */ 438 public void setMailTimeout(Integer timeout) throws SecurityException { 439 checkWriteAccess(); 440 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_MAIL); 441 if(!hasAccess) 442 throw new SecurityException("no access to update mail server settings"); 443 Element mail=_getRootElement("mail"); 444 mail.setAttribute("timeout",Caster.toString(timeout,"")); 445 //config.setMailTimeout(timeout); 446 } 447 448 /** 449 * sets the charset for the mail 450 * @param timeout 451 * @throws SecurityException 452 */ 453 public void setMailDefaultCharset(String charset) throws PageException { 454 checkWriteAccess(); 455 boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_MAIL); 456 if(!hasAccess) throw new SecurityException("no access to update mail server settings"); 457 458 if(!StringUtil.isEmpty(charset)){ 459 try { 460 IOUtil.checkEncoding(charset); 461 } catch (IOException e) { 462 throw Caster.toPageException(e); 463 } 464 } 465 466 Element mail=_getRootElement("mail"); 467 mail.setAttribute("default-encoding",charset); 468 //config.setMailDefaultEncoding(charset); 469 } 470 471 /** 472 * insert or update a mailserver on system 473 * @param hostName 474 * @param username 475 * @param password 476 * @param port 477 * @param ssl 478 * @param tls 479 * @throws PageException 480 */ 481 public void updateMailServer(String hostName,String username,String password, int port, boolean tls, boolean ssl,long lifeTimeSpan, long idleTimeSpan) throws PageException { 482 checkWriteAccess(); 483 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_MAIL); 484 if(!hasAccess) 485 throw new SecurityException("no access to update mail server settings"); 486 487 /*try { 488 SMTPVerifier.verify(hostName,username,password,port); 489 } catch (SMTPException e) { 490 throw Caster.toPageException(e); 491 }*/ 492 493 Element mail=_getRootElement("mail"); 494 if(port<1) port=21; 495 496 if(hostName==null || hostName.trim().length()==0) 497 throw new ExpressionException("Host (SMTP) can be a empty value"); 498 hostName=hostName.trim(); 499 500 501 Element[] children = ConfigWebFactory.getChildren(mail,"server"); 502 503 // Update 504 Element server=null; 505 for(int i=0;i<children.length;i++) { 506 Element el=children[i]; 507 String smtp=el.getAttribute("smtp"); 508 if(smtp!=null && smtp.equalsIgnoreCase(hostName)) { 509 server=el; 510 break; 511 } 512 } 513 514 // Insert 515 if(server==null) { 516 server = doc.createElement("server"); 517 mail.appendChild(XMLCaster.toRawNode(server)); 518 } 519 server.setAttribute("smtp",hostName); 520 server.setAttribute("username",username); 521 server.setAttribute("password",ConfigWebFactory.encrypt(password)); 522 server.setAttribute("port",Caster.toString(port)); 523 server.setAttribute("tls",Caster.toString(tls)); 524 server.setAttribute("ssl",Caster.toString(ssl)); 525 server.setAttribute("life",Caster.toString(lifeTimeSpan)); 526 server.setAttribute("idle",Caster.toString(idleTimeSpan)); 527 528 } 529 530 /** 531 *removes a mailserver from system 532 * @param hostName 533 * @throws SecurityException 534 */ 535 public void removeMailServer(String hostName) throws SecurityException { 536 checkWriteAccess(); 537 538 Element mail=_getRootElement("mail"); 539 Element[] children = ConfigWebFactory.getChildren(mail,"server"); 540 if(children.length>0) { 541 for(int i=0;i<children.length;i++) { 542 Element el=children[i]; 543 String smtp=el.getAttribute("smtp"); 544 if(smtp!=null && smtp.equalsIgnoreCase(hostName)) { 545 mail.removeChild(children[i]); 546 } 547 } 548 } 549 } 550 551 552 public void removeLogSetting(String name) throws SecurityException { 553 checkWriteAccess(); 554 Element logging=_getRootElement("logging"); 555 Element[] children = ConfigWebFactory.getChildren(logging,"logger"); 556 if(children.length>0) { 557 String _name; 558 for(int i=0;i<children.length;i++) { 559 Element el=children[i]; 560 _name=el.getAttribute("name"); 561 562 if(_name!=null && _name.equalsIgnoreCase(name)) { 563 logging.removeChild(children[i]); 564 } 565 } 566 } 567 } 568 569 static void updateMapping(ConfigImpl config, String virtual, String physical,String archive,String primary, short inspect, boolean toplevel) throws SAXException, IOException, PageException { 570 ConfigWebAdmin admin = new ConfigWebAdmin(config, null); 571 admin._updateMapping(virtual, physical, archive, primary, inspect, toplevel); 572 admin._store(); 573 } 574 575 576 static void updateComponentMapping(ConfigImpl config, String virtual, String physical,String archive,String primary, short inspect) throws SAXException, IOException, PageException { 577 ConfigWebAdmin admin = new ConfigWebAdmin(config, null); 578 admin._updateComponentMapping(virtual, physical, archive, primary, inspect); 579 admin._store(); 580 } 581 582 583 static void updateCustomTagMapping(ConfigImpl config, String virtual, String physical,String archive,String primary, short inspect) throws SAXException, IOException, PageException { 584 ConfigWebAdmin admin = new ConfigWebAdmin(config, null); 585 admin._updateCustomTag(virtual, physical, archive, primary, inspect); 586 admin._store(); 587 } 588 589 /** 590 * insert or update a mapping on system 591 * @param virtual 592 * @param physical 593 * @param archive 594 * @param primary 595 * @param trusted 596 * @param toplevel 597 * @throws ExpressionException 598 * @throws SecurityException 599 */ 600 public void updateMapping(String virtual, String physical,String archive,String primary, short inspect, boolean toplevel) throws ExpressionException, SecurityException { 601 checkWriteAccess(); 602 _updateMapping(virtual, physical, archive, primary, inspect, toplevel); 603 } 604 private void _updateMapping(String virtual, String physical,String archive,String primary, short inspect, boolean toplevel) throws ExpressionException, SecurityException { 605 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_MAPPING); 606 607 virtual=virtual.trim(); 608 if(physical==null) physical=""; 609 else physical=physical.trim(); 610 if(archive==null) archive=""; 611 else archive=archive.trim(); 612 primary=primary.trim(); 613 if(!hasAccess) 614 throw new SecurityException("no access to update mappings"); 615 616 // check virtual 617 if(virtual==null || virtual.length()==0) 618 throw new ExpressionException("virtual path cannot be a empty value"); 619 virtual=virtual.replace('\\','/'); 620 621 if(!virtual.equals("/") && virtual.endsWith("/")) 622 virtual=virtual.substring(0,virtual.length()-1); 623 624 if(virtual.charAt(0)!='/') 625 throw new ExpressionException("virtual path must start with [/]"); 626 boolean isArchive=primary.equalsIgnoreCase("archive"); 627 628 if((physical.length()+archive.length())==0) 629 throw new ExpressionException("physical or archive must have a value"); 630 631 if(isArchive && archive.length()==0 ) isArchive=false; 632 //print.ln("isArchive:"+isArchive); 633 634 if(!isArchive && archive.length()>0 && physical.length()==0 ) isArchive=true; 635 //print.ln("isArchive:"+isArchive); 636 637 638 639 Element mappings=_getRootElement("mappings"); 640 // Update 641 Element[] children = ConfigWebFactory.getChildren(mappings,"mapping"); 642 for(int i=0;i<children.length;i++) { 643 String v=children[i].getAttribute("virtual"); 644 if(v!=null) { 645 if(!v.equals("/") && v.endsWith("/")) 646 v=v.substring(0,v.length()-1); 647 648 if(v.equals(virtual)) { 649 Element el=children[i]; 650 if(physical.length()>0) { 651 el.setAttribute("physical",physical); 652 } 653 else if(el.hasAttribute("physical")) { 654 el.removeAttribute("physical"); 655 } 656 if(archive.length()>0) { 657 el.setAttribute("archive",archive); 658 } 659 else if(el.hasAttribute("archive")) { 660 el.removeAttribute("archive"); 661 } 662 el.setAttribute("primary",isArchive?"archive":"physical"); 663 el.setAttribute("inspect-template",ConfigWebUtil.inspectTemplate(inspect, "")); 664 el.removeAttribute("trusted"); 665 el.setAttribute("toplevel",Caster.toString(toplevel)); 666 return ; 667 } 668 } 669 } 670 671 // Insert 672 Element el=doc.createElement("mapping"); 673 mappings.appendChild(el); 674 el.setAttribute("virtual",virtual); 675 if(physical.length()>0)el.setAttribute("physical",physical); 676 if(archive.length()>0)el.setAttribute("archive",archive); 677 el.setAttribute("primary",isArchive?"archive":"physical"); 678 el.setAttribute("inspect-template",ConfigWebUtil.inspectTemplate(inspect, "")); 679 el.setAttribute("toplevel",Caster.toString(toplevel)); 680 681 // set / to the end 682 children = ConfigWebFactory.getChildren(mappings,"mapping"); 683 for(int i=0;i<children.length;i++) { 684 String v=children[i].getAttribute("virtual"); 685 686 if(v!=null && v.equals("/")) { 687 el=children[i]; 688 mappings.removeChild(el); 689 mappings.appendChild(el); 690 return ; 691 } 692 693 } 694 695 } 696 697 public void updateRestMapping(String virtual, String physical,boolean _default) throws ExpressionException, SecurityException { 698 checkWriteAccess(); 699 boolean hasAccess=true;// TODO ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_REST); 700 virtual=virtual.trim(); 701 physical=physical.trim(); 702 if(!hasAccess) 703 throw new SecurityException("no access to update REST mapping"); 704 705 // check virtual 706 if(virtual==null || virtual.length()==0) 707 throw new ExpressionException("virtual path cannot be a empty value"); 708 virtual=virtual.replace('\\','/'); 709 if(virtual.equals("/")) 710 throw new ExpressionException("virtual path cannot be /"); 711 712 713 if(virtual.endsWith("/")) 714 virtual=virtual.substring(0,virtual.length()-1); 715 716 if(virtual.charAt(0)!='/') virtual="/"+virtual; 717 718 if((physical.length())==0) 719 throw new ExpressionException("physical path cannot be a empty value"); 720 721 Element rest=_getRootElement("rest"); 722 Element[] children = ConfigWebFactory.getChildren(rest,"mapping"); 723 724 // remove existing default 725 if(_default) { 726 for(int i=0;i<children.length;i++) { 727 if(Caster.toBooleanValue(children[i].getAttribute("default"),false)) 728 children[i].setAttribute("default", "false"); 729 } 730 } 731 732 // Update 733 String v; 734 Element el=null; 735 for(int i=0;i<children.length;i++) { 736 v=children[i].getAttribute("virtual"); 737 if(v!=null && v.equals(virtual)) { 738 el=children[i]; 739 } 740 } 741 742 743 // Insert 744 if(el==null) { 745 el=doc.createElement("mapping"); 746 rest.appendChild(el); 747 } 748 749 el.setAttribute("virtual",virtual); 750 el.setAttribute("physical",physical); 751 el.setAttribute("default",Caster.toString(_default)); 752 753 } 754 755 756 /** 757 * delete a mapping on system 758 * @param virtual 759 * @throws ExpressionException 760 * @throws SecurityException 761 */ 762 public void removeMapping(String virtual) throws ExpressionException, SecurityException { 763 checkWriteAccess(); 764 // check parameters 765 if(virtual==null || virtual.length()==0) 766 throw new ExpressionException("virtual path cannot be a empty value"); 767 virtual=virtual.replace('\\','/'); 768 769 if(!virtual.equals("/") && virtual.endsWith("/")) 770 virtual=virtual.substring(0,virtual.length()-1); 771 if(virtual.charAt(0)!='/') 772 throw new ExpressionException("virtual path must start with [/]"); 773 774 775 Element mappings=_getRootElement("mappings"); 776 777 Element[] children = ConfigWebFactory.getChildren(mappings,"mapping"); 778 for(int i=0;i<children.length;i++) { 779 String v=children[i].getAttribute("virtual"); 780 if(v!=null) { 781 if(!v.equals("/") && v.endsWith("/")) 782 v=v.substring(0,v.length()-1); 783 if(v!=null && v.equals(virtual)) { 784 Element el=children[i]; 785 mappings.removeChild(el); 786 } 787 } 788 } 789 } 790 791 792 public void removeRestMapping(String virtual) throws ExpressionException, SecurityException { 793 checkWriteAccess(); 794 // check parameters 795 if(virtual==null || virtual.length()==0) 796 throw new ExpressionException("virtual path cannot be a empty value"); 797 virtual=virtual.replace('\\','/'); 798 if(virtual.equals("/")) 799 throw new ExpressionException("virtual path cannot be /"); 800 801 if(virtual.endsWith("/")) virtual=virtual.substring(0,virtual.length()-1); 802 if(virtual.charAt(0)!='/') virtual="/"+virtual; 803 804 805 806 Element mappings=_getRootElement("rest"); 807 808 Element[] children = ConfigWebFactory.getChildren(mappings,"mapping"); 809 for(int i=0;i<children.length;i++) { 810 String v=children[i].getAttribute("virtual"); 811 if(v!=null) { 812 if(!v.equals("/") && v.endsWith("/")) 813 v=v.substring(0,v.length()-1); 814 if(v!=null && v.equals(virtual)) { 815 Element el=children[i]; 816 mappings.removeChild(el); 817 } 818 } 819 } 820 } 821 822 /** 823 * delete a customtagmapping on system 824 * @param virtual 825 * @throws SecurityException 826 */ 827 public void removeCustomTag(String virtual) throws SecurityException { 828 checkWriteAccess(); 829 830 Element mappings=_getRootElement("custom-tag"); 831 Element[] children = ConfigWebFactory.getChildren(mappings,"mapping"); 832 for(int i=0;i<children.length;i++) { 833 if(virtual.equals(createVirtual(children[i])))mappings.removeChild(children[i]); 834 } 835 } 836 837 public void removeComponentMapping(String virtual) throws SecurityException { 838 checkWriteAccess(); 839 840 Element mappings=_getRootElement("component"); 841 Element[] children = ConfigWebFactory.getChildren(mappings,"mapping"); 842 String v; 843 for(int i=0;i<children.length;i++) { 844 v=createVirtual(children[i]); 845 if(virtual.equals(v))mappings.removeChild(children[i]); 846 } 847 } 848 849 850 851 852 /** 853 * insert or update a mapping for Custom Tag 854 * @param virtual 855 * @param physical 856 * @param archive 857 * @param primary 858 * @param trusted 859 * @throws ExpressionException 860 * @throws SecurityException 861 */ 862 public void updateCustomTag(String virtual,String physical,String archive,String primary, short inspect) throws ExpressionException, SecurityException { 863 checkWriteAccess(); 864 _updateCustomTag(virtual, physical, archive, primary, inspect); 865 } 866 private void _updateCustomTag(String virtual,String physical,String archive,String primary, short inspect) throws ExpressionException, SecurityException { 867 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_CUSTOM_TAG); 868 if(!hasAccess) 869 throw new SecurityException("no access to change custom tag settings"); 870 if(physical==null)physical=""; 871 if(archive==null)archive=""; 872 873 //virtual="/custom-tag"; 874 if(StringUtil.isEmpty(virtual))virtual=createVirtual(physical,archive); 875 876 boolean isArchive=primary.equalsIgnoreCase("archive"); 877 if(isArchive && archive.length()==0 ) { 878 throw new ExpressionException("archive must have a value when primary has value archive"); 879 } 880 if(!isArchive && physical.length()==0 ) { 881 throw new ExpressionException("physical must have a value when primary has value physical"); 882 } 883 884 Element mappings=_getRootElement("custom-tag"); 885 886 // Update 887 String v; 888 Element[] children = ConfigWebFactory.getChildren(mappings,"mapping"); 889 for(int i=0;i<children.length;i++) { 890 Element el=children[i]; 891 v=createVirtual(el); 892 if(v.equals(virtual)) { 893 el.setAttribute("virtual",v); 894 el.setAttribute("physical",physical); 895 el.setAttribute("archive",archive); 896 el.setAttribute("primary",primary.equalsIgnoreCase("archive")?"archive":"physical"); 897 el.setAttribute("inspect-template",ConfigWebUtil.inspectTemplate(inspect, "")); 898 el.removeAttribute("trusted"); 899 return ; 900 } 901 } 902 903 // Insert 904 Element el=doc.createElement("mapping"); 905 mappings.appendChild(el); 906 if(physical.length()>0)el.setAttribute("physical",physical); 907 if(archive.length()>0)el.setAttribute("archive",archive); 908 el.setAttribute("primary",primary.equalsIgnoreCase("archive")?"archive":"physical"); 909 el.setAttribute("inspect-template",ConfigWebUtil.inspectTemplate(inspect, "")); 910 el.setAttribute("virtual",virtual); 911 } 912 913 public void updateComponentMapping(String virtual,String physical,String archive,String primary, short inspect) throws ExpressionException, SecurityException { 914 checkWriteAccess(); 915 _updateComponentMapping(virtual, physical, archive, primary, inspect); 916 } 917 private void _updateComponentMapping(String virtual,String physical,String archive,String primary, short inspect) throws ExpressionException { 918 primary=primary.equalsIgnoreCase("archive")?"archive":"physical"; 919 if(physical==null)physical=""; 920 else physical=physical.trim(); 921 922 if(archive==null)archive=""; 923 else archive=archive.trim(); 924 925 boolean isArchive=primary.equalsIgnoreCase("archive"); 926 if(isArchive && archive.length()==0 ) { 927 throw new ExpressionException("archive must have a value when primary has value archive"); 928 } 929 if(!isArchive && physical.length()==0 ) { 930 throw new ExpressionException("physical must have a value when primary has value physical"); 931 } 932 933 Element mappings=_getRootElement("component"); 934 Element[] children = ConfigWebFactory.getChildren(mappings,"mapping"); 935 Element el; 936 937 /* ignore when exists 938 for(int i=0;i<children.length;i++) { 939 el=children[i]; 940 if(el.getAttribute("physical").equals(physical) && 941 el.getAttribute("archive").equals(archive) && 942 el.getAttribute("primary").equals(primary) && 943 el.getAttribute("trusted").equals(Caster.toString(trusted))){ 944 return; 945 } 946 }*/ 947 948 949 // Update 950 String v; 951 for(int i=0;i<children.length;i++) { 952 el=children[i]; 953 v=createVirtual(el); // if there is no virtual defintion (old records), we use the position 954 if(v.equals(virtual)) { 955 el.setAttribute("virtual",v); // set to make sure it exists for the future 956 el.setAttribute("physical",physical); 957 el.setAttribute("archive",archive); 958 el.setAttribute("primary",primary.equalsIgnoreCase("archive")?"archive":"physical"); 959 el.setAttribute("inspect-template",ConfigWebUtil.inspectTemplate(inspect, "")); 960 el.removeAttribute("trusted"); 961 return ; 962 } 963 } 964 965 // Insert 966 el=doc.createElement("mapping"); 967 mappings.appendChild(el); 968 if(physical.length()>0)el.setAttribute("physical",physical); 969 if(archive.length()>0)el.setAttribute("archive",archive); 970 el.setAttribute("primary",primary.equalsIgnoreCase("archive")?"archive":"physical"); 971 el.setAttribute("inspect-template",ConfigWebUtil.inspectTemplate(inspect, "")); 972 el.setAttribute("virtual",virtual); 973 } 974 975 976 977 978 public static String createVirtual(Element el) { 979 String str = el.getAttribute("virtual"); 980 if(!StringUtil.isEmpty(str)) return str; 981 982 return createVirtual(el.getAttribute("physical"),el.getAttribute("archive")); 983 } 984 public static String createVirtual(String physical,String archive) { 985 return "/"+MD5.getDigestAsString(physical+":"+archive,""); 986 } 987 988 989 /** 990 * insert or update a Java CFX Tag 991 * @param name 992 * @param strClass 993 * @throws PageException 994 */ 995 public void updateJavaCFX(String name,String strClass) throws PageException { 996 checkWriteAccess(); 997 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_CFX_SETTING); 998 999 if(!hasAccess) throw new SecurityException("no access to change cfx settings"); 1000 1001 1002 try { 1003 Class clazz = ClassUtil.loadClass(config.getClassLoader(),strClass); 1004 if(!Reflector.isInstaneOf(clazz, CustomTag.class)) 1005 throw new ExpressionException("class ["+strClass+"] must implement interface ["+CustomTag.class.getName()+"]"); 1006 1007 } 1008 catch (ClassException e) { 1009 1010 throw Caster.toPageException(e); 1011 } 1012 1013 1014 1015 1016 if(name==null || name.length()==0) 1017 throw new ExpressionException("class name can't be a empty value"); 1018 1019 renameOldstyleCFX(); 1020 1021 1022 Element tags=_getRootElement("ext-tags"); 1023 1024 // Update 1025 Element[] children = ConfigWebFactory.getChildren(tags,"ext-tag"); 1026 for(int i=0;i<children.length;i++) { 1027 String n=children[i].getAttribute("name"); 1028 1029 if(n!=null && n.equalsIgnoreCase(name)) { 1030 Element el=children[i]; 1031 if(!"java".equalsIgnoreCase(el.getAttribute("type"))) throw new ExpressionException("there is already a c++ cfx tag with this name"); 1032 el.setAttribute("class",strClass); 1033 el.setAttribute("type","java"); 1034 return ; 1035 } 1036 1037 } 1038 1039 // Insert 1040 Element el=doc.createElement("ext-tag"); 1041 tags.appendChild(el); 1042 el.setAttribute("class",strClass); 1043 el.setAttribute("name",name); 1044 el.setAttribute("type","java"); 1045 } 1046 1047 public void updateCPPCFX(String name, String procedure, String strServerLibrary, boolean keepAlive) throws PageException { 1048 checkWriteAccess(); 1049 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_CFX_SETTING); 1050 1051 if(!hasAccess) throw new SecurityException("no access to change cfx settings"); 1052 1053 // name 1054 if(StringUtil.isEmpty(name)) 1055 throw new ExpressionException("name cannot be a empty value"); 1056 1057 // serverLibrary 1058 if(StringUtil.isEmpty(strServerLibrary)) throw new ExpressionException("serverLibrary cannot be a empty value"); 1059 Resource serverLibrary = ResourceUtil.toResourceExisting(config, strServerLibrary); 1060 1061 // procedure 1062 if(StringUtil.isEmpty(procedure)) throw new ExpressionException("procedure cannot be a empty value"); 1063 1064 renameOldstyleCFX(); 1065 1066 1067 Element tags=_getRootElement("ext-tags"); 1068 1069 // Update 1070 Element[] children = ConfigWebFactory.getChildren(tags,"ext-tag"); 1071 for(int i=0;i<children.length;i++) { 1072 String n=children[i].getAttribute("name"); 1073 1074 if(n!=null && n.equalsIgnoreCase(name)) { 1075 Element el=children[i]; 1076 if(!"cpp".equalsIgnoreCase(el.getAttribute("type"))) throw new ExpressionException("there is already a java cfx tag with this name"); 1077 el.setAttribute("server-library",serverLibrary.getAbsolutePath()); 1078 el.setAttribute("procedure",procedure); 1079 el.setAttribute("keep-alive",Caster.toString(keepAlive)); 1080 el.setAttribute("type","cpp"); 1081 return ; 1082 } 1083 1084 } 1085 1086 // Insert 1087 Element el=doc.createElement("ext-tag"); 1088 tags.appendChild(el); 1089 el.setAttribute("server-library",serverLibrary.getAbsolutePath()); 1090 el.setAttribute("procedure",procedure); 1091 el.setAttribute("keep-alive",Caster.toString(keepAlive)); 1092 el.setAttribute("name",name); 1093 el.setAttribute("type","cpp"); 1094 } 1095 1096 private void renameOldstyleCFX() { 1097 1098 Element tags=_getRootElement("ext-tags",false,true); 1099 if(tags!=null) return; 1100 tags=_getRootElement("cfx-tags",false,true); 1101 if(tags==null) return; 1102 1103 1104 1105 Element newTags = _getRootElement("ext-tags"); 1106 Element[] children = ConfigWebFactory.getChildren(tags,"cfx-tag"); 1107 String type; 1108 // copy 1109 for(int i=0;i<children.length;i++) { 1110 Element el=doc.createElement("ext-tag"); 1111 newTags.appendChild(el); 1112 type=children[i].getAttribute("type"); 1113 // java 1114 if(type.equalsIgnoreCase("java")){ 1115 el.setAttribute("class",children[i].getAttribute("class")); 1116 } 1117 // c++ 1118 else { 1119 el.setAttribute("server-library",children[i].getAttribute("server-library")); 1120 el.setAttribute("procedure",children[i].getAttribute("procedure")); 1121 el.setAttribute("keep-alive",children[i].getAttribute("keep-alive")); 1122 1123 } 1124 el.setAttribute("name",children[i].getAttribute("name")); 1125 el.setAttribute("type",children[i].getAttribute("type")); 1126 } 1127 1128 // remove old 1129 for(int i=0;i<children.length;i++) { 1130 tags.removeChild(children[i]); 1131 } 1132 tags.getParentNode().removeChild(tags); 1133 } 1134 1135 1136 public static boolean fixLFI(Document doc) { 1137 return "lucee-configuration".equals(doc.getDocumentElement().getNodeName()); 1138 1139 } 1140 1141 /** 1142 * make sure every context has a salt 1143 * */ 1144 public static boolean fixSalt(Document doc) { 1145 Element root=doc.getDocumentElement(); 1146 String salt=root.getAttribute("salt"); 1147 if(StringUtil.isEmpty(salt,true) || !Decision.isUUId(salt)) { 1148 //create salt 1149 root.setAttribute("salt",CreateUUID.invoke()); 1150 return true; 1151 } 1152 return false; 1153 } 1154 1155 public static boolean fixPSQ(Document doc) { 1156 1157 Element datasources=ConfigWebFactory.getChildByName(doc.getDocumentElement(),"data-sources",false,true); 1158 if(datasources!=null && datasources.hasAttribute("preserve-single-quote")){ 1159 Boolean b=Caster.toBoolean(datasources.getAttribute("preserve-single-quote"),null); 1160 if(b!=null)datasources.setAttribute("psq",Caster.toString(!b.booleanValue())); 1161 datasources.removeAttribute("preserve-single-quote"); 1162 return true; 1163 } 1164 return false; 1165 } 1166 1167 1168 /** 1169 * the following code remove all logging defintions spread over the complete xml and adds them to the new "logging" tag 1170 * 1171 * @param doc 1172 * @return 1173 */ 1174 1175 public static boolean fixLogging(ConfigServerImpl cs,ConfigImpl config,Document doc) { 1176 1177 if(config.setVersion(doc)>=4.3D) return false; 1178 1179 // datasource 1180 Element src = ConfigWebFactory.getChildByName(doc.getDocumentElement(), "datasource"); 1181 fixLogging(cs,doc,src, "datasource",false,"{lucee-config}/logs/datasource.log"); 1182 1183 1184 setVersion(doc,Caster.toDoubleValue(Info.getVersionAsString().substring(0,3),4.3D)); 1185 1186 1187 if(config.setVersion(doc)>=4.2D) return true; 1188 1189 1190 //setVersion(Caster.toDoubleValue(Info.getVersionAsString().substring(0,3),1.0D)); 1191 1192 1193 // mapping 1194 src = ConfigWebFactory.getChildByName(doc.getDocumentElement(), "mappings"); 1195 fixLogging(cs,doc,src, "mapping",false,"{lucee-config}/logs/mapping.log"); 1196 1197 // rest 1198 src = ConfigWebFactory.getChildByName(doc.getDocumentElement(), "rest"); 1199 fixLogging(cs,doc,src, "rest",false,"{lucee-config}/logs/rest.log"); 1200 1201 // gateway 1202 src = ConfigWebFactory.getChildByName(doc.getDocumentElement(), "gateways"); 1203 fixLogging(cs,doc,src, "gateway",false,"{lucee-config}/logs/gateway.log"); 1204 1205 // remote clients 1206 src = ConfigWebFactory.getChildByName(doc.getDocumentElement(), "remote-clients"); 1207 fixLogging(cs,doc,src, "remoteclient",false,"{lucee-config}/logs/remoteclient.log"); 1208 1209 // orm 1210 src = ConfigWebFactory.getChildByName(doc.getDocumentElement(), "orm"); 1211 fixLogging(cs,doc,src, "orm",false,"{lucee-config}/logs/orm.log"); 1212 1213 // mail 1214 src = ConfigWebFactory.getChildByName(doc.getDocumentElement(), "mail"); 1215 fixLogging(cs,doc,src, "mail",false,"{lucee-config}/logs/mail.log"); 1216 1217 // search 1218 src = ConfigWebFactory.getChildByName(doc.getDocumentElement(), "search"); 1219 fixLogging(cs,doc,src, "search",false,"{lucee-config}/logs/search.log"); 1220 1221 // scheduler 1222 src = ConfigWebFactory.getChildByName(doc.getDocumentElement(), "scheduler"); 1223 fixLogging(cs,doc,src, "scheduler",false,"{lucee-config}/logs/scheduler.log"); 1224 1225 // scope 1226 src = ConfigWebFactory.getChildByName(doc.getDocumentElement(), "scope"); 1227 fixLogging(cs,doc,src, "scope",false,"{lucee-config}/logs/scope.log"); 1228 1229 // application 1230 Element app = src = ConfigWebFactory.getChildByName(doc.getDocumentElement(), "application"); 1231 fixLogging(cs,doc,src, "application","application-log","application-log-level",false,"{lucee-config}/logs/application.log"); 1232 1233 // exception 1234 fixLogging(cs,doc,app, "exception","exception-log","exception-log-level",false,"{lucee-config}/logs/exception.log"); 1235 1236 // trace 1237 fixLogging(cs,doc,app, "trace","trace-log","trace-log-level",false,"{lucee-config}/logs/trace.log"); 1238 1239 // thread 1240 fixLogging(cs,doc,app, "thread","thread-log","thread-log-level",false,"{lucee-config}/logs/thread.log"); 1241 1242 // deploy 1243 fixLogging(cs,doc,app, "deploy","deploy-log","deploy-log-level",false,"{lucee-config}/logs/deploy.log"); 1244 1245 // requesttimeout 1246 fixLogging(cs,doc,app, "requesttimeout","requesttimeout-log","requesttimeout-log-level",false,"{lucee-config}/logs/requesttimeout.log"); 1247 1248 setVersion(doc,Caster.toDoubleValue(Info.getVersionAsString().substring(0,3),4.3D)); 1249 1250 1251 return true; 1252 } 1253 1254 private static boolean fixLogging(ConfigServerImpl cs, Document doc,Element src, String name,boolean deleteSourceAttributes, String defaultValue) { 1255 return fixLogging(cs, doc, src, name, "log", "log-level", deleteSourceAttributes, defaultValue); 1256 } 1257 private static boolean fixLogging(ConfigServerImpl cs, Document doc,Element src, String name,String logName, String levelName,boolean deleteSourceAttributes, String defaultValue) { 1258 1259 1260 String path,level; 1261 // Mapping logging 1262 1263 path = src.getAttribute(logName); 1264 level = src.getAttribute(levelName); 1265 1266 if(StringUtil.isEmpty(path) && !StringUtil.isEmpty(defaultValue) && (cs==null || cs.getLog(name)==null)) { 1267 // ignore defaultValue, when there is a setting in server context 1268 path=defaultValue; 1269 } 1270 if(!StringUtil.isEmpty(path)) { 1271 if(deleteSourceAttributes)src.removeAttribute(logName); 1272 if(deleteSourceAttributes)src.removeAttribute(levelName); 1273 1274 Element logging = ConfigWebFactory.getChildByName(doc.getDocumentElement(), "logging"); 1275 1276 // first of all we have to make sure this is not already existing, if it does we ignore the old settings 1277 Element[] children = XMLUtil.getChildElementsAsArray(logging); 1278 for(int i=0;i<children.length;i++){ 1279 if(children[i].getTagName().equals("logger") && name.equalsIgnoreCase(children[i].getAttribute("name"))) { 1280 return false; 1281 } 1282 } 1283 1284 SystemOut.printDate("move "+name+" logging"); 1285 Element logger = doc.createElement("logger"); 1286 logger.setAttribute("name", name); 1287 if("console".equalsIgnoreCase(path)) { 1288 logger.setAttribute("appender", "console"); 1289 logger.setAttribute("layout", "pattern"); 1290 } 1291 else { 1292 logger.setAttribute("appender", "resource"); 1293 logger.setAttribute("appender-arguments", "path:"+path); 1294 logger.setAttribute("layout", "classic"); 1295 } 1296 1297 if(!StringUtil.isEmpty(level,true))logger.setAttribute("level", level.trim()); 1298 1299 logging.appendChild(logger); 1300 1301 return true; 1302 } 1303 return false; 1304 } 1305 1306 1307 public static boolean fixS3(Document doc) { 1308 Element resources=ConfigWebFactory.getChildByName(doc.getDocumentElement(),"resources",false,true); 1309 1310 Element[] providers = ConfigWebFactory.getChildren(resources,"resource-provider"); 1311 1312 // replace extension class with core class 1313 for(int i=0;i<providers.length;i++) { 1314 if("s3".equalsIgnoreCase(providers[i].getAttribute("scheme"))) { 1315 if("lucee.extension.io.resource.type.s3.S3ResourceProvider".equalsIgnoreCase(providers[i].getAttribute("class"))){ 1316 providers[i].setAttribute("class", S3ResourceProvider.class.getName()); 1317 return true; 1318 } 1319 return false; 1320 } 1321 } 1322 1323 1324 // FUTURE remove this part in upcoming versions 1325 // add s3 when not 1326 Element el=doc.createElement("resource-provider"); 1327 el.setAttribute("scheme", "s3"); 1328 el.setAttribute("class", S3ResourceProvider.class.getName()); 1329 el.setAttribute("arguments", "lock-timeout:10000;"); 1330 resources.appendChild(el); 1331 1332 return true; 1333 } 1334 1335 1336 1337 1338 public void verifyCFX(String name) throws PageException { 1339 CFXTagPool pool=config.getCFXTagPool(); 1340 CustomTag ct=null; 1341 try { 1342 ct = pool.getCustomTag(name); 1343 } 1344 catch (CFXTagException e) { 1345 throw Caster.toPageException(e); 1346 } 1347 finally { 1348 if(ct!=null)pool.releaseCustomTag(ct); 1349 } 1350 1351 } 1352 1353 1354 1355 public void verifyJavaCFX(String name,String strClass) throws PageException { 1356 try { 1357 Class clazz = ClassUtil.loadClass(config.getClassLoader(),strClass); 1358 if(!Reflector.isInstaneOf(clazz, CustomTag.class)) 1359 throw new ExpressionException("class ["+strClass+"] must implement interface ["+CustomTag.class.getName()+"]"); 1360 } 1361 catch (ClassException e) { 1362 throw Caster.toPageException(e); 1363 } 1364 1365 if(StringUtil.startsWithIgnoreCase(name,"cfx_"))name=name.substring(4); 1366 if(StringUtil.isEmpty(name)) 1367 throw new ExpressionException("class name can't be a empty value"); 1368 } 1369 1370 1371 /** 1372 * remove a CFX Tag 1373 * @param name 1374 * @throws ExpressionException 1375 * @throws SecurityException 1376 */ 1377 public void removeCFX(String name) throws ExpressionException, SecurityException { 1378 checkWriteAccess(); 1379 // check parameters 1380 if(name==null || name.length()==0) 1381 throw new ExpressionException("name for CFX Tag can be a empty value"); 1382 1383 renameOldstyleCFX(); 1384 1385 Element mappings=_getRootElement("ext-tags"); 1386 1387 Element[] children = ConfigWebFactory.getChildren(mappings,"ext-tag"); 1388 for(int i=0;i<children.length;i++) { 1389 String n=children[i].getAttribute("name"); 1390 if(n!=null && n.equalsIgnoreCase(name)) { 1391 mappings.removeChild(children[i]); 1392 } 1393 } 1394 } 1395 1396 /** 1397 * update or insert new database connection 1398 * @param name 1399 * @param clazzName 1400 * @param dsn 1401 * @param username 1402 * @param password 1403 * @param host 1404 * @param database 1405 * @param port 1406 * @param connectionLimit 1407 * @param connectionTimeout 1408 * @param blob 1409 * @param clob 1410 * @param allow 1411 * @param storage 1412 * @param custom 1413 * @param literalTimestampWithTSOffset 1414 * @throws ExpressionException 1415 * @throws SecurityException 1416 */ 1417 public void updateDataSource(String name, String newName, String clazzName, String dsn, String username, String password, 1418 String host, String database, int port, int connectionLimit, int connectionTimeout, long metaCacheTimeout, 1419 boolean blob, boolean clob, int allow, boolean validate, boolean storage, String timezone, Struct custom, String dbdriver, boolean literalTimestampWithTSOffset) throws ExpressionException, SecurityException { 1420 1421 checkWriteAccess(); 1422 SecurityManager sm = config.getSecurityManager(); 1423 short access = sm.getAccess(SecurityManager.TYPE_DATASOURCE); 1424 boolean hasAccess=true; 1425 boolean hasInsertAccess=true; 1426 int maxLength=0; 1427 1428 if(access==SecurityManager.VALUE_YES) hasAccess=true; 1429 else if(access==SecurityManager.VALUE_NO) hasAccess=false; 1430 else if(access>=SecurityManager.VALUE_1 && access<=SecurityManager.VALUE_10){ 1431 int existingLength=getDatasourceLength(config); 1432 maxLength=access-SecurityManager.NUMBER_OFFSET; 1433 hasInsertAccess=maxLength>existingLength; 1434 //print.ln("maxLength:"+maxLength); 1435 //print.ln("existingLength:"+existingLength); 1436 } 1437 //print.ln("hasAccess:"+hasAccess); 1438 //print.ln("hasInsertAccess:"+hasInsertAccess); 1439 1440 //boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DATASOURCE); 1441 if(!hasAccess) 1442 throw new SecurityException("no access to update datsource connections"); 1443 1444 // check parameters 1445 if(name==null || name.length()==0) 1446 throw new ExpressionException("name can't be a empty value"); 1447 1448 try { 1449 ClassUtil.loadInstance(clazzName); 1450 } 1451 catch (ClassException e) { 1452 throw new ExpressionException(e.getMessage()); 1453 } 1454 1455 Element datasources=_getRootElement("data-sources"); 1456 1457 // Update 1458 Element[] children = ConfigWebFactory.getChildren(datasources,"data-source"); 1459 for(int i=0;i<children.length;i++) { 1460 String n=children[i].getAttribute("name"); 1461 1462 if(n.equalsIgnoreCase(name)) { 1463 Element el=children[i]; 1464 if(password.equalsIgnoreCase("****************")) 1465 password=el.getAttribute("password"); 1466 1467 if(!StringUtil.isEmpty(newName) && !newName.equals(name)) 1468 el.setAttribute("name",newName); 1469 el.setAttribute("class",clazzName); 1470 el.setAttribute("dsn",dsn); 1471 el.setAttribute("username",username); 1472 el.setAttribute("password",ConfigWebFactory.encrypt(password)); 1473 1474 el.setAttribute("host",host); 1475 if(!StringUtil.isEmpty(timezone))el.setAttribute("timezone",timezone); 1476 else if(el.hasAttribute("timezone")) el.removeAttribute("timezone"); 1477 el.setAttribute("database",database); 1478 el.setAttribute("port",Caster.toString(port)); 1479 el.setAttribute("connectionLimit",Caster.toString(connectionLimit)); 1480 el.setAttribute("connectionTimeout",Caster.toString(connectionTimeout)); 1481 el.setAttribute("metaCacheTimeout",Caster.toString(metaCacheTimeout)); 1482 el.setAttribute("blob",Caster.toString(blob)); 1483 el.setAttribute("clob",Caster.toString(clob)); 1484 el.setAttribute("allow",Caster.toString(allow)); 1485 el.setAttribute("validate",Caster.toString(validate)); 1486 el.setAttribute("storage",Caster.toString(storage)); 1487 el.setAttribute("custom",toStringURLStyle(custom)); 1488 1489 if (!StringUtil.isEmpty( dbdriver )) 1490 el.setAttribute("dbdriver", Caster.toString(dbdriver)); 1491 1492 if (literalTimestampWithTSOffset) 1493 el.setAttribute("literal-timestamp-with-tsoffset", Caster.toString(literalTimestampWithTSOffset)); 1494 else 1495 el.removeAttribute("literal-timestamp-with-tsoffset"); 1496 return; 1497 } 1498 } 1499 1500 if(!hasInsertAccess) 1501 throw new SecurityException("no access to add datasource connections, the maximum count of ["+maxLength+"] datasources is reached"); 1502 1503 // Insert 1504 Element el=doc.createElement("data-source"); 1505 datasources.appendChild(el); 1506 if(!StringUtil.isEmpty(newName)) 1507 el.setAttribute("name",newName); 1508 else 1509 el.setAttribute("name",name); 1510 el.setAttribute("class",clazzName); 1511 el.setAttribute("dsn",dsn); 1512 if(username.length()>0)el.setAttribute("username",username); 1513 if(password.length()>0)el.setAttribute("password",ConfigWebFactory.encrypt(password)); 1514 1515 el.setAttribute("host",host); 1516 if(!StringUtil.isEmpty(timezone))el.setAttribute("timezone",timezone); 1517 el.setAttribute("database",database); 1518 if(port>-1)el.setAttribute("port",Caster.toString(port)); 1519 if(connectionLimit>-1)el.setAttribute("connectionLimit",Caster.toString(connectionLimit)); 1520 if(connectionTimeout>-1)el.setAttribute("connectionTimeout",Caster.toString(connectionTimeout)); 1521 if(metaCacheTimeout>-1)el.setAttribute("metaCacheTimeout",Caster.toString(metaCacheTimeout)); 1522 1523 el.setAttribute("blob",Caster.toString(blob)); 1524 el.setAttribute("clob",Caster.toString(clob)); 1525 el.setAttribute("validate",Caster.toString(validate)); 1526 el.setAttribute("storage",Caster.toString(storage)); 1527 if(allow>-1)el.setAttribute("allow",Caster.toString(allow)); 1528 el.setAttribute("custom",toStringURLStyle(custom)); 1529 1530 if (!StringUtil.isEmpty( dbdriver )) 1531 el.setAttribute("dbdriver", Caster.toString(dbdriver)); 1532 1533 if (literalTimestampWithTSOffset) 1534 el.setAttribute("literal-timestamp-with-tsoffset", Caster.toString(literalTimestampWithTSOffset)); 1535 1536 /* 1537 String host,String database,int port,String connectionLimit, String connectionTimeout, 1538 boolean blob,boolean clob,int allow,Struct custom 1539 ); 1540 */ 1541 } 1542 1543 1544 public void updateGatewayEntry(String id,String className, String cfcPath, String listenerCfcPath,int startupMode,Struct custom, boolean readOnly) throws PageException { 1545 1546 checkWriteAccess(); 1547 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_GATEWAY); 1548 1549 if(!hasAccess) 1550 throw new SecurityException("no access to update gateway entry"); 1551 1552 1553 // check parameters 1554 id=id.trim(); 1555 if(StringUtil.isEmpty(id)) 1556 throw new ExpressionException("id can't be a empty value"); 1557 1558 if(StringUtil.isEmpty(className) && StringUtil.isEmpty(cfcPath)) 1559 throw new ExpressionException("you must define className or cfcPath"); 1560 1561 try { 1562 if(!StringUtil.isEmpty(className)){ 1563 ClassUtil.loadClass(className); 1564 } 1565 } 1566 catch (ClassException e) { 1567 throw new ExpressionException(e.getMessage()); 1568 } 1569 1570 Element parent=_getRootElement("gateways"); 1571 1572 // Update 1573 Element[] children = ConfigWebFactory.getChildren(parent,"gateway"); 1574 for(int i=0;i<children.length;i++) { 1575 String n=children[i].getAttribute("id"); 1576 Element el=children[i]; 1577 if(n.equalsIgnoreCase(id)) { 1578 el.setAttribute("class",className); 1579 el.setAttribute("cfc-path",cfcPath); 1580 el.setAttribute("listener-cfc-path",listenerCfcPath); 1581 el.setAttribute("startup-mode",GatewayEntryImpl.toStartup(startupMode, "automatic")); 1582 el.setAttribute("custom",toStringURLStyle(custom)); 1583 el.setAttribute("read-only",Caster.toString(readOnly)); 1584 return; 1585 } 1586 1587 } 1588 // Insert 1589 Element el=doc.createElement("gateway"); 1590 parent.appendChild(el); 1591 el.setAttribute("id",id); 1592 el.setAttribute("cfc-path",cfcPath); 1593 el.setAttribute("listener-cfc-path",listenerCfcPath); 1594 el.setAttribute("startup-mode",GatewayEntryImpl.toStartup(startupMode, "automatic")); 1595 el.setAttribute("class",className); 1596 el.setAttribute("custom",toStringURLStyle(custom)); 1597 el.setAttribute("read-only",Caster.toString(readOnly)); 1598 1599 } 1600 1601 public void updateCacheConnection(String name, String classname,int _default, Struct custom,boolean readOnly,boolean storage) throws PageException { 1602 1603 checkWriteAccess(); 1604 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_CACHE); 1605 if(!hasAccess) 1606 throw new SecurityException("no access to update cache connection"); 1607 1608 1609 // check parameters 1610 name=name.trim(); 1611 if(StringUtil.isEmpty(name)) 1612 throw new ExpressionException("name can't be a empty value"); 1613 //else if(name.equals("template") || name.equals("object")) 1614 //throw new ExpressionException("name ["+name+"] is not allowed for a cache connection, the following names are reserved words [object,template]"); 1615 1616 try { 1617 Class clazz; 1618 if(classname!=null && classname.endsWith(".EHCacheLite")) clazz=EHCache.class; 1619 else clazz = ClassUtil.loadClass(config.getClassLoader(),classname); 1620 if(!Reflector.isInstaneOf(clazz, Cache.class)) 1621 throw new ExpressionException("class ["+clazz.getName()+"] is not of type ["+Cache.class.getName()+"]"); 1622 } 1623 catch (ClassException e) { 1624 throw new ExpressionException(e.getMessage()); 1625 } 1626 1627 Element parent=_getRootElement("cache"); 1628 1629 if(name.equalsIgnoreCase(parent.getAttribute("default-template"))) 1630 parent.removeAttribute("default-template"); 1631 if(name.equalsIgnoreCase(parent.getAttribute("default-object"))) 1632 parent.removeAttribute("default-object"); 1633 if(name.equalsIgnoreCase(parent.getAttribute("default-query"))) 1634 parent.removeAttribute("default-query"); 1635 if(name.equalsIgnoreCase(parent.getAttribute("default-resource"))) 1636 parent.removeAttribute("default-resource"); 1637 if(name.equalsIgnoreCase(parent.getAttribute("default-function"))) 1638 parent.removeAttribute("default-function"); 1639 if(name.equalsIgnoreCase(parent.getAttribute("default-include"))) 1640 parent.removeAttribute("default-include"); 1641 1642 1643 if(_default==ConfigImpl.CACHE_DEFAULT_OBJECT){ 1644 parent.setAttribute("default-object",name); 1645 } 1646 else if(_default==ConfigImpl.CACHE_DEFAULT_TEMPLATE){ 1647 parent.setAttribute("default-template",name); 1648 } 1649 else if(_default==ConfigImpl.CACHE_DEFAULT_QUERY){ 1650 parent.setAttribute("default-query",name); 1651 } 1652 else if(_default==ConfigImpl.CACHE_DEFAULT_RESOURCE){ 1653 parent.setAttribute("default-resource",name); 1654 } 1655 else if(_default==ConfigImpl.CACHE_DEFAULT_FUNCTION){ 1656 parent.setAttribute("default-function",name); 1657 } 1658 else if(_default==ConfigImpl.CACHE_DEFAULT_INCLUDE){ 1659 parent.setAttribute("default-include",name); 1660 } 1661 1662 // Update 1663 //boolean isUpdate=false; 1664 Element[] children = ConfigWebFactory.getChildren(parent,"connection"); 1665 for(int i=0;i<children.length;i++) { 1666 String n=children[i].getAttribute("name"); 1667 Element el=children[i]; 1668 if(n.equalsIgnoreCase(name)) { 1669 el.setAttribute("class",classname); 1670 //el.setAttribute("default",Caster.toString(_default)); 1671 el.setAttribute("custom",toStringURLStyle(custom)); 1672 el.setAttribute("read-only",Caster.toString(readOnly)); 1673 el.setAttribute("storage",Caster.toString(storage)); 1674 return; 1675 } 1676 1677 } 1678 1679 // Insert 1680 Element el=doc.createElement("connection"); 1681 parent.appendChild(el); 1682 el.setAttribute("name",name); 1683 el.setAttribute("class",classname); 1684 //el.setAttribute("default",Caster.toString(_default)); 1685 el.setAttribute("custom",toStringURLStyle(custom)); 1686 el.setAttribute("read-only",Caster.toString(readOnly)); 1687 el.setAttribute("storage",Caster.toString(storage)); 1688 1689 } 1690 1691 public void removeCacheDefaultConnection(int type) throws PageException { 1692 checkWriteAccess(); 1693 1694 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_CACHE); 1695 if(!hasAccess) 1696 throw new SecurityException("no access to update cache connections"); 1697 1698 Element parent=_getRootElement("cache"); 1699 if(type==ConfigImpl.CACHE_DEFAULT_OBJECT){ 1700 parent.removeAttribute("default-object"); 1701 } 1702 else if(type==ConfigImpl.CACHE_DEFAULT_TEMPLATE){ 1703 parent.removeAttribute("default-template"); 1704 } 1705 else if(type==ConfigImpl.CACHE_DEFAULT_QUERY){ 1706 parent.removeAttribute("default-query"); 1707 } 1708 else if(type==ConfigImpl.CACHE_DEFAULT_RESOURCE){ 1709 parent.removeAttribute("default-resource"); 1710 } 1711 else if(type==ConfigImpl.CACHE_DEFAULT_FUNCTION){ 1712 parent.removeAttribute("default-function"); 1713 } 1714 else if(type==ConfigImpl.CACHE_DEFAULT_INCLUDE){ 1715 parent.removeAttribute("default-include"); 1716 } 1717 } 1718 1719 public void updateCacheDefaultConnection(int type,String name) throws PageException { 1720 checkWriteAccess(); 1721 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_CACHE); 1722 1723 if(!hasAccess) 1724 throw new SecurityException("no access to update cache default connections"); 1725 1726 Element parent=_getRootElement("cache"); 1727 if(type==ConfigImpl.CACHE_DEFAULT_OBJECT){ 1728 parent.setAttribute("default-object", name); 1729 } 1730 else if(type==ConfigImpl.CACHE_DEFAULT_TEMPLATE){ 1731 parent.setAttribute("default-template", name); 1732 } 1733 else if(type==ConfigImpl.CACHE_DEFAULT_QUERY){ 1734 parent.setAttribute("default-query", name); 1735 } 1736 else if(type==ConfigImpl.CACHE_DEFAULT_RESOURCE){ 1737 parent.setAttribute("default-resource", name); 1738 } 1739 else if(type==ConfigImpl.CACHE_DEFAULT_FUNCTION){ 1740 parent.setAttribute("default-function", name); 1741 } 1742 else if(type==ConfigImpl.CACHE_DEFAULT_INCLUDE){ 1743 parent.setAttribute("default-include", name); 1744 } 1745 } 1746 1747 public void removeResourceProvider(Class clazz) throws PageException { 1748 checkWriteAccess(); 1749 SecurityManager sm = config.getSecurityManager(); 1750 short access = sm.getAccess(SecurityManager.TYPE_FILE); 1751 boolean hasAccess=access==SecurityManager.VALUE_YES; 1752 1753 String className=clazz.getName(); 1754 1755 if(!hasAccess) 1756 throw new SecurityException("no access to remove resources"); 1757 1758 Element parent=_getRootElement("resources"); 1759 1760 // remove 1761 Element[] children = ConfigWebFactory.getChildren(parent,"resource-provider"); 1762 for(int i=0;i<children.length;i++) { 1763 String cn=children[i].getAttribute("class"); 1764 if(cn.equalsIgnoreCase(className)) { 1765 parent.removeChild(children[i]); 1766 break; 1767 } 1768 } 1769 } 1770 1771 public void updateResourceProvider(String scheme, Class clazz,Struct arguments) throws PageException { 1772 updateResourceProvider(scheme, clazz, toStringCSSStyle(arguments)); 1773 } 1774 1775 public void updateResourceProvider(String scheme, Class clazz,String arguments) throws PageException { 1776 checkWriteAccess(); 1777 SecurityManager sm = config.getSecurityManager(); 1778 short access = sm.getAccess(SecurityManager.TYPE_FILE); 1779 boolean hasAccess=access==SecurityManager.VALUE_YES; 1780 1781 String className=clazz.getName(); 1782 1783 if(!hasAccess) 1784 throw new SecurityException("no access to update resources"); 1785 1786 // check parameters 1787 if(StringUtil.isEmpty(scheme))throw new ExpressionException("scheme can't be a empty value"); 1788 1789 Element parent=_getRootElement("resources"); 1790 1791 // Update 1792 Element[] children = ConfigWebFactory.getChildren(parent,"resource-provider"); 1793 for(int i=0;i<children.length;i++) { 1794 String cn=children[i].getAttribute("class"); 1795 if(cn.equalsIgnoreCase(className)) { 1796 Element el=children[i]; 1797 el.setAttribute("scheme",scheme); 1798 el.setAttribute("arguments",arguments); 1799 return ; 1800 } 1801 } 1802 1803 // Insert 1804 Element el=doc.createElement("resource-provider"); 1805 parent.appendChild(el); 1806 el.setAttribute("scheme",scheme); 1807 el.setAttribute("arguments",arguments); 1808 el.setAttribute("class",className); 1809 } 1810 1811 public void updateDefaultResourceProvider(Class clazz, String arguments) throws PageException { 1812 checkWriteAccess(); 1813 SecurityManager sm = config.getSecurityManager(); 1814 short access = sm.getAccess(SecurityManager.TYPE_FILE); 1815 boolean hasAccess=access==SecurityManager.VALUE_YES; 1816 1817 String className=clazz.getName(); 1818 1819 if(!hasAccess) 1820 throw new SecurityException("no access to update resources"); 1821 1822 Element parent=_getRootElement("resources"); 1823 1824 // Update 1825 Element[] children = ConfigWebFactory.getChildren(parent,"default-resource-provider"); 1826 for(int i=0;i<children.length;i++) { 1827 Element el=children[i]; 1828 el.setAttribute("arguments",arguments); 1829 return; 1830 } 1831 1832 // Insert 1833 Element el=doc.createElement("default-resource-provider"); 1834 parent.appendChild(el); 1835 el.setAttribute("arguments",arguments); 1836 el.setAttribute("class",className); 1837 } 1838 1839 private int getDatasourceLength(ConfigImpl config) { 1840 Map ds = config.getDataSourcesAsMap(); 1841 Iterator it = ds.keySet().iterator(); 1842 int len=0; 1843 1844 while(it.hasNext()) { 1845 if(!((DataSource)ds.get(it.next())).isReadOnly())len++; 1846 } 1847 return len; 1848 } 1849 1850 1851 private static String toStringURLStyle(Struct sct) { 1852 Iterator<Entry<Key, Object>> it = sct.entryIterator(); 1853 Entry<Key, Object> e; 1854 StringBuilder rtn=new StringBuilder(); 1855 while(it.hasNext()) { 1856 e = it.next(); 1857 if(rtn.length()>0)rtn.append('&'); 1858 rtn.append(URLEncoder.encode(e.getKey().getString())); 1859 rtn.append('='); 1860 rtn.append(URLEncoder.encode(Caster.toString(e.getValue(),""))); 1861 } 1862 return rtn.toString(); 1863 } 1864 1865 private static String toStringCSSStyle(Struct sct) { 1866 //Collection.Key[] keys = sct.keys(); 1867 StringBuilder rtn=new StringBuilder(); 1868 Iterator<Entry<Key, Object>> it = sct.entryIterator(); 1869 Entry<Key, Object> e; 1870 1871 while(it.hasNext()) { 1872 e = it.next(); 1873 if(rtn.length()>0)rtn.append(';'); 1874 rtn.append(encode(e.getKey().getString())); 1875 rtn.append(':'); 1876 rtn.append(encode(Caster.toString(e.getValue(),""))); 1877 } 1878 return rtn.toString(); 1879 } 1880 1881 private static String encode(String str) { 1882 try { 1883 return URLEncodedFormat.invoke(str, "UTF-8",false); 1884 } catch (PageException e) { 1885 return URLEncoder.encode(str); 1886 } 1887 } 1888 1889 1890 public Query getResourceProviders() throws PageException { 1891 checkReadAccess(); 1892 // check parameters 1893 Element parent=_getRootElement("resources"); 1894 Element[] elProviders = ConfigWebFactory.getChildren(parent,"resource-provider"); 1895 Element[] elDefaultProviders = ConfigWebFactory.getChildren(parent,"default-resource-provider"); 1896 ResourceProvider[] providers = config.getResourceProviders(); 1897 ResourceProvider defaultProvider = config.getDefaultResourceProvider(); 1898 1899 Query qry=new QueryImpl(new String[]{"support","scheme","caseSensitive","default","class","arguments"},elProviders.length+elDefaultProviders.length,"resourceproviders"); 1900 int row=1; 1901 for(int i=0;i<elDefaultProviders.length;i++) { 1902 getResourceProviders(new ResourceProvider[]{defaultProvider},qry,elDefaultProviders[i],row++,Boolean.TRUE); 1903 } 1904 for(int i=0;i<elProviders.length;i++) { 1905 getResourceProviders(providers,qry,elProviders[i],row++,Boolean.FALSE); 1906 } 1907 return qry; 1908 } 1909 1910 private void getResourceProviders(ResourceProvider[] providers,Query qry,Element p, int row,Boolean def) throws PageException { 1911 Array support=new ArrayImpl(); 1912 String clazz=p.getAttribute("class"); 1913 qry.setAt("scheme",row,p.getAttribute("scheme")); 1914 qry.setAt("arguments",row,p.getAttribute("arguments")); 1915 qry.setAt("class",row,clazz); 1916 for(int i=0;i<providers.length;i++) { 1917 if(providers[i].getClass().getName().equals(clazz)){ 1918 if(providers[i].isAttributesSupported())support.append("attributes"); 1919 if(providers[i].isModeSupported())support.append("mode"); 1920 qry.setAt("support",row,ListUtil.arrayToList(support, ",")); 1921 qry.setAt("scheme",row,providers[i].getScheme()); 1922 qry.setAt("caseSensitive",row,Caster.toBoolean(providers[i].isCaseSensitive())); 1923 qry.setAt("default",row,def); 1924 break; 1925 } 1926 } 1927 } 1928 1929 1930 /** 1931 * remove a DataSource Connection 1932 * @param name 1933 * @throws ExpressionException 1934 * @throws SecurityException 1935 */ 1936 public void removeDataSource(String name) throws ExpressionException, SecurityException { 1937 checkWriteAccess(); 1938 // check parameters 1939 if(name==null || name.length()==0) 1940 throw new ExpressionException("name for Datasource Connection can be a empty value"); 1941 1942 1943 Element datasources=_getRootElement("data-sources"); 1944 1945 Element[] children = ConfigWebFactory.getChildren(datasources,"data-source"); 1946 for(int i=0;i<children.length;i++) { 1947 String n=children[i].getAttribute("name"); 1948 if(n!=null && n.equalsIgnoreCase(name)) { 1949 datasources.removeChild(children[i]); 1950 } 1951 } 1952 } 1953 1954 public void removeCacheConnection(String name) throws ExpressionException, SecurityException { 1955 checkWriteAccess(); 1956 1957 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_CACHE); 1958 if(!hasAccess) 1959 throw new SecurityException("no access to remove cache connection"); 1960 1961 1962 // check parameters 1963 if(StringUtil.isEmpty(name)) 1964 throw new ExpressionException("name for Cache Connection can be a empty value"); 1965 1966 Element parent=_getRootElement("cache"); 1967 1968 // remove default flag 1969 if(name.equalsIgnoreCase(parent.getAttribute("default-object"))) 1970 parent.removeAttribute("default-object"); 1971 if(name.equalsIgnoreCase(parent.getAttribute("default-template"))) 1972 parent.removeAttribute("default-template"); 1973 if(name.equalsIgnoreCase(parent.getAttribute("default-query"))) 1974 parent.removeAttribute("default-query"); 1975 if(name.equalsIgnoreCase(parent.getAttribute("default-resource"))) 1976 parent.removeAttribute("default-resource"); 1977 1978 // remove element 1979 Element[] children = ConfigWebFactory.getChildren(parent,"connection"); 1980 for(int i=0;i<children.length;i++) { 1981 String n=children[i].getAttribute("name"); 1982 if(n!=null && n.equalsIgnoreCase(name)) { 1983 Map<String, CacheConnection> conns = config.getCacheConnections(); 1984 CacheConnection cc= conns.get(n.toLowerCase()); 1985 if(cc!=null)Util.removeEL(config instanceof ConfigWeb?(ConfigWeb)config:null,cc); 1986 parent.removeChild(children[i]); 1987 } 1988 } 1989 1990 } 1991 1992 1993 public void removeCacheGatewayEntry(String name) throws PageException { 1994 checkWriteAccess(); 1995 1996 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_GATEWAY); 1997 if(!hasAccess) 1998 throw new SecurityException("no access to remove gateway entry"); 1999 2000 if(StringUtil.isEmpty(name)) 2001 throw new ExpressionException("name for Gateway Id can be a empty value"); 2002 2003 Element parent=_getRootElement("gateways"); 2004 2005 // remove element 2006 Element[] children = ConfigWebFactory.getChildren(parent,"gateway"); 2007 for(int i=0;i<children.length;i++) { 2008 String n=children[i].getAttribute("id"); 2009 if(n!=null && n.equalsIgnoreCase(name)) { 2010 Map conns = ((ConfigWebImpl)config).getGatewayEngine().getEntries(); 2011 GatewayEntry ge=(GatewayEntry) conns.get(n); 2012 if(ge!=null){ 2013 ((ConfigWebImpl)config).getGatewayEngine().remove(ge); 2014 } 2015 parent.removeChild(children[i]); 2016 } 2017 } 2018 } 2019 2020 2021 2022 public void removeRemoteClient(String url) throws ExpressionException, SecurityException { 2023 checkWriteAccess(); 2024 2025 // SNSN 2026 2027 2028 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_REMOTE); 2029 if(!hasAccess) 2030 throw new SecurityException("no access to remove remote client settings"); 2031 2032 2033 2034 // check parameters 2035 if(StringUtil.isEmpty(url)) 2036 throw new ExpressionException("url for Remote Client can be a empty value"); 2037 2038 2039 Element clients=_getRootElement("remote-clients"); 2040 2041 Element[] children = ConfigWebFactory.getChildren(clients,"remote-client"); 2042 for(int i=0;i<children.length;i++) { 2043 String n=children[i].getAttribute("url"); 2044 if(n!=null && n.equalsIgnoreCase(url)) { 2045 clients.removeChild(children[i]); 2046 } 2047 } 2048 } 2049 2050 /** 2051 * update PSQ State 2052 * @param psq Preserver Single Quote 2053 * @throws SecurityException 2054 */ 2055 public void updatePSQ(Boolean psq) throws SecurityException { 2056 checkWriteAccess(); 2057 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DATASOURCE); 2058 2059 if(!hasAccess) throw new SecurityException("no access to update datsource connections"); 2060 2061 Element datasources=_getRootElement("data-sources"); 2062 datasources.setAttribute("psq",Caster.toString(psq,"")); 2063 if(datasources.hasAttribute("preserve-single-quote")) 2064 datasources.removeAttribute("preserve-single-quote"); 2065 } 2066 2067 2068 public void updateInspectTemplate(String str) throws SecurityException { 2069 checkWriteAccess(); 2070 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2071 2072 if(!hasAccess) throw new SecurityException("no access to update"); 2073 2074 Element datasources=_getRootElement("java"); 2075 datasources.setAttribute("inspect-template",str); 2076 2077 } 2078 2079 2080 public void updateTypeChecking(Boolean typeChecking) throws SecurityException { 2081 checkWriteAccess(); 2082 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2083 2084 if(!hasAccess) throw new SecurityException("no access to update"); 2085 2086 Element datasources=_getRootElement("application"); 2087 if(typeChecking==null)datasources.removeAttribute("type-checking"); 2088 else datasources.setAttribute("type-checking",Caster.toString(typeChecking.booleanValue())); 2089 2090 } 2091 2092 2093 2094 2095 /** 2096 * sets the scope cascading type 2097 * @param type (ServletConfigImpl.SCOPE_XYZ) 2098 * @throws SecurityException 2099 */ 2100 public void updateScopeCascadingType(String type) throws SecurityException { 2101 checkWriteAccess(); 2102 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2103 2104 if(!hasAccess) throw new SecurityException("no access to update scope setting"); 2105 2106 2107 Element scope=_getRootElement("scope"); 2108 if(type.equalsIgnoreCase("strict")) scope.setAttribute("cascading","strict"); 2109 else if(type.equalsIgnoreCase("small")) scope.setAttribute("cascading","small"); 2110 else if(type.equalsIgnoreCase("standard")) scope.setAttribute("cascading","standard"); 2111 else scope.setAttribute("cascading","standard"); 2112 2113 } 2114 2115 /** 2116 * sets the scope cascading type 2117 * @param type (ServletConfigImpl.SCOPE_XYZ) 2118 * @throws SecurityException 2119 */ 2120 public void updateScopeCascadingType(short type) throws SecurityException { 2121 checkWriteAccess(); 2122 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2123 if(!hasAccess) 2124 throw new SecurityException("no access to update scope setting"); 2125 2126 //lucee.print.ln("********........type:"+type); 2127 Element scope=_getRootElement("scope"); 2128 if(type==ConfigWeb.SCOPE_STRICT) scope.setAttribute("cascading","strict"); 2129 else if(type==ConfigWeb.SCOPE_SMALL) scope.setAttribute("cascading","small"); 2130 else if(type==ConfigWeb.SCOPE_STANDARD) scope.setAttribute("cascading","standard"); 2131 2132 } 2133 2134 /** 2135 * sets if allowed implicid query call 2136 * @param allow 2137 * @throws SecurityException 2138 */ 2139 public void updateAllowImplicidQueryCall(Boolean allow) throws SecurityException { 2140 checkWriteAccess(); 2141 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2142 2143 if(!hasAccess) throw new SecurityException("no access to update scope setting"); 2144 2145 Element scope=_getRootElement("scope"); 2146 scope.setAttribute("cascade-to-resultset",Caster.toString(allow,"")); 2147 2148 } 2149 2150 public void updateMergeFormAndUrl(Boolean merge) throws SecurityException { 2151 checkWriteAccess(); 2152 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2153 2154 if(!hasAccess) throw new SecurityException("no access to update scope setting"); 2155 2156 Element scope=_getRootElement("scope"); 2157 scope.setAttribute("merge-url-form",Caster.toString(merge,"")); 2158 2159 } 2160 2161 /** 2162 * updates request timeout value 2163 * @param span 2164 * @throws SecurityException 2165 * @throws ApplicationException 2166 */ 2167 public void updateRequestTimeout(TimeSpan span) throws SecurityException, ApplicationException { 2168 checkWriteAccess(); 2169 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2170 2171 if(!hasAccess) throw new SecurityException("no access to update scope setting"); 2172 2173 Element scope=_getRootElement("scope"); 2174 2175 Element application=_getRootElement("application"); 2176 if(span!=null){ 2177 if(span.getMillis()<=0) 2178 throw new ApplicationException("value must be a positive number"); 2179 application.setAttribute("requesttimeout",span.getDay()+","+span.getHour()+","+span.getMinute()+","+span.getSecond()); 2180 } 2181 else application.removeAttribute("requesttimeout"); 2182 2183 // remove deprecated attribute 2184 if(scope.hasAttribute("requesttimeout")) 2185 scope.removeAttribute("requesttimeout"); 2186 } 2187 2188 /** 2189 * updates session timeout value 2190 * @param span 2191 * @throws SecurityException 2192 */ 2193 public void updateSessionTimeout(TimeSpan span) throws SecurityException { 2194 checkWriteAccess(); 2195 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2196 2197 if(!hasAccess) throw new SecurityException("no access to update scope setting"); 2198 2199 Element scope=_getRootElement("scope"); 2200 if(span!=null)scope.setAttribute("sessiontimeout",span.getDay()+","+span.getHour()+","+span.getMinute()+","+span.getSecond()); 2201 else scope.removeAttribute("sessiontimeout"); 2202 } 2203 2204 2205 2206 2207 public void updateClientStorage(String storage) throws SecurityException, ApplicationException { 2208 updateStorage("client", storage); 2209 } 2210 2211 2212 public void updateSessionStorage(String storage) throws SecurityException, ApplicationException { 2213 updateStorage("session", storage); 2214 } 2215 2216 2217 private void updateStorage(String storageName,String storage) throws SecurityException, ApplicationException { 2218 checkWriteAccess(); 2219 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2220 2221 if(!hasAccess) throw new SecurityException("no access to update scope setting"); 2222 storage=validateStorage(storage); 2223 2224 2225 Element scope=_getRootElement("scope"); 2226 if(!StringUtil.isEmpty(storage,true))scope.setAttribute(storageName+"storage",storage); 2227 else scope.removeAttribute(storageName+"storage"); 2228 } 2229 2230 2231 2232 private String validateStorage(String storage) throws ApplicationException { 2233 storage=storage.trim().toLowerCase(); 2234 2235 // empty 2236 if(StringUtil.isEmpty(storage,true)) return ""; 2237 2238 // standard storages 2239 if("cookie".equals(storage) || "memory".equals(storage) || "file".equals(storage)) 2240 return storage; 2241 2242 // aliases 2243 if("ram".equals(storage)) return "memory"; 2244 if("registry".equals(storage)) return "file"; 2245 2246 // datasource 2247 DataSource ds = config.getDataSource(storage,null); 2248 if(ds!=null) { 2249 if(ds.isStorage())return storage; 2250 throw new ApplicationException("datasource ["+storage+"] is not enabled to be used as session/client storage"); 2251 } 2252 2253 // cache 2254 CacheConnection cc = Util.getCacheConnection(config, storage,null); 2255 if(cc!=null) { 2256 if(cc.isStorage())return storage; 2257 throw new ApplicationException("cache ["+storage+"] is not enabled to be used as session/client storage"); 2258 } 2259 2260 String sdx=StringUtil.soundex(storage); 2261 2262 // check if a datasource has a similar name 2263 DataSource[] sources = config.getDataSources(); 2264 for(int i=0;i<sources.length;i++){ 2265 if(StringUtil.soundex(sources[i].getName()).equals(sdx)) 2266 throw new ApplicationException("no matching storage for ["+storage+"] found, did you mean ["+sources[i].getName()+"]"); 2267 } 2268 2269 // check if a cache has a similar name 2270 Iterator<String> it = config.getCacheConnections().keySet().iterator(); 2271 String name; 2272 while(it.hasNext()){ 2273 name=it.next(); 2274 if(StringUtil.soundex(name).equals(sdx)) 2275 throw new ApplicationException( "no matching storage for ["+storage+"] found, did you mean ["+name+"]"); 2276 } 2277 2278 2279 throw new ApplicationException("no matching storage for ["+storage+"] found"); 2280 } 2281 2282 2283 /** 2284 * updates session timeout value 2285 * @param span 2286 * @throws SecurityException 2287 */ 2288 public void updateClientTimeout(TimeSpan span) throws SecurityException { 2289 checkWriteAccess(); 2290 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2291 2292 if(!hasAccess) throw new SecurityException("no access to update scope setting"); 2293 2294 Element scope=_getRootElement("scope"); 2295 if(span!=null)scope.setAttribute("clienttimeout",span.getDay()+","+span.getHour()+","+span.getMinute()+","+span.getSecond()); 2296 else scope.removeAttribute("clienttimeout"); 2297 2298 // deprecated 2299 if(scope.hasAttribute("client-max-age"))scope.removeAttribute("client-max-age"); 2300 2301 2302 } 2303 2304 2305 public void updateCFMLWriterType(String writerType) throws SecurityException, ApplicationException { 2306 checkWriteAccess(); 2307 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2308 if(!hasAccess) throw new SecurityException("no access to update scope setting"); 2309 2310 Element scope=_getRootElement("setting"); 2311 writerType=writerType.trim(); 2312 2313 // remove 2314 if(StringUtil.isEmpty(writerType)) { 2315 if(scope.hasAttribute("cfml-writer"))scope.removeAttribute("cfml-writer"); 2316 return; 2317 } 2318 2319 // update 2320 if(!"white-space".equalsIgnoreCase(writerType) && 2321 !"white-space-pref".equalsIgnoreCase(writerType) && 2322 !"regular".equalsIgnoreCase(writerType)) 2323 throw new ApplicationException("invalid writer type defintion ["+writerType+"], valid types are [white-space, white-space-pref, regular]"); 2324 2325 scope.setAttribute("cfml-writer",writerType.toLowerCase()); 2326 } 2327 2328 /*public void updateSuppressWhitespace(Boolean value) throws SecurityException { 2329 checkWriteAccess(); 2330 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2331 2332 if(!hasAccess) throw new SecurityException("no access to update scope setting"); 2333 2334 Element scope=_getRootElement("setting"); 2335 scope.setAttribute("suppress-whitespace",Caster.toString(value,"")); 2336 }*/ 2337 2338 public void updateSuppressContent(Boolean value) throws SecurityException { 2339 checkWriteAccess(); 2340 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2341 2342 if(!hasAccess) throw new SecurityException("no access to update scope setting"); 2343 2344 Element scope=_getRootElement("setting"); 2345 scope.setAttribute("suppress-content",Caster.toString(value,"")); 2346 } 2347 2348 public void updateShowVersion(Boolean value) throws SecurityException { 2349 checkWriteAccess(); 2350 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2351 2352 if(!hasAccess) throw new SecurityException("no access to update scope setting"); 2353 2354 Element scope=_getRootElement("setting"); 2355 scope.setAttribute("show-version",Caster.toString(value,"")); 2356 } 2357 2358 public void updateAllowCompression(Boolean value) throws SecurityException { 2359 checkWriteAccess(); 2360 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2361 2362 if(!hasAccess) throw new SecurityException("no access to update scope setting"); 2363 2364 Element scope=_getRootElement("setting"); 2365 scope.setAttribute("allow-compression",Caster.toString(value,"")); 2366 } 2367 2368 public void updateContentLength(Boolean value) throws SecurityException { 2369 checkWriteAccess(); 2370 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2371 2372 if(!hasAccess) throw new SecurityException("no access to update scope setting"); 2373 2374 Element scope=_getRootElement("setting"); 2375 scope.setAttribute("content-length",Caster.toString(value,"")); 2376 } 2377 2378 2379 public void updateBufferOutput(Boolean value) throws SecurityException { 2380 checkWriteAccess(); 2381 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2382 2383 if(!hasAccess) throw new SecurityException("no access to update scope setting"); 2384 2385 Element scope=_getRootElement("setting"); 2386 scope.setAttribute("buffer-output",Caster.toString(value,"")); 2387 } 2388 2389 /** 2390 * updates request timeout value 2391 * @param span 2392 * @throws SecurityException 2393 */ 2394 public void updateApplicationTimeout(TimeSpan span) throws SecurityException { 2395 checkWriteAccess(); 2396 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2397 2398 if(!hasAccess) throw new SecurityException("no access to update scope setting"); 2399 2400 Element scope=_getRootElement("scope"); 2401 if(span!=null)scope.setAttribute("applicationtimeout",span.getDay()+","+span.getHour()+","+span.getMinute()+","+span.getSecond()); 2402 else scope.removeAttribute("applicationtimeout"); 2403 } 2404 2405 public void updateApplicationListener(String type,String mode) throws SecurityException { 2406 checkWriteAccess(); 2407 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2408 2409 if(!hasAccess) throw new SecurityException("no access to update listener type"); 2410 2411 Element scope=_getRootElement("application"); 2412 scope.setAttribute("listener-type",type.toLowerCase().trim()); 2413 scope.setAttribute("listener-mode",mode.toLowerCase().trim()); 2414 } 2415 2416 public void updateProxy(boolean enabled,String server, int port, String username, String password) throws SecurityException { 2417 checkWriteAccess(); 2418 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2419 2420 if(!hasAccess) throw new SecurityException("no access to update listener type"); 2421 2422 Element proxy=_getRootElement("proxy"); 2423 proxy.setAttribute("enabled",Caster.toString(enabled)); 2424 if(!StringUtil.isEmpty(server)) proxy.setAttribute("server",server); 2425 if(port>0) proxy.setAttribute("port",Caster.toString(port)); 2426 if(!StringUtil.isEmpty(username)) proxy.setAttribute("username",username); 2427 if(!StringUtil.isEmpty(password)) proxy.setAttribute("password",password); 2428 } 2429 2430 /*public void removeProxy() throws SecurityException { 2431 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2432 if(!hasAccess) throw new SecurityException("no access to remove proxy settings"); 2433 2434 Element proxy=_getRootElement("proxy"); 2435 proxy.removeAttribute("server"); 2436 proxy.removeAttribute("port"); 2437 proxy.removeAttribute("username"); 2438 proxy.removeAttribute("password"); 2439 }*/ 2440 2441 /** 2442 * enable or desable session management 2443 * @param sessionManagement 2444 * @throws SecurityException 2445 */ 2446 public void updateSessionManagement(Boolean sessionManagement) throws SecurityException { 2447 checkWriteAccess(); 2448 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2449 2450 if(!hasAccess) 2451 throw new SecurityException("no access to update scope setting"); 2452 2453 Element scope=_getRootElement("scope"); 2454 scope.setAttribute("sessionmanagement",Caster.toString(sessionManagement,"")); 2455 } 2456 2457 /** 2458 * enable or desable client management 2459 * @param clientManagement 2460 * @throws SecurityException 2461 */ 2462 public void updateClientManagement(Boolean clientManagement) throws SecurityException { 2463 checkWriteAccess(); 2464 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2465 2466 if(!hasAccess) 2467 throw new SecurityException("no access to update scope setting"); 2468 2469 Element scope=_getRootElement("scope"); 2470 scope.setAttribute("clientmanagement",Caster.toString(clientManagement,"")); 2471 } 2472 2473 /** 2474 * set if client cookies are enabled or not 2475 * @param clientCookies 2476 * @throws SecurityException 2477 */ 2478 public void updateClientCookies(Boolean clientCookies) throws SecurityException { 2479 checkWriteAccess(); 2480 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2481 if(!hasAccess) 2482 throw new SecurityException("no access to update scope setting"); 2483 2484 Element scope=_getRootElement("scope"); 2485 scope.setAttribute("setclientcookies",Caster.toString(clientCookies,"")); 2486 } 2487 2488 public void updateCGIReadonly(Boolean cgiReadonly) throws SecurityException { 2489 checkWriteAccess(); 2490 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2491 if(!hasAccess) 2492 throw new SecurityException("no access to update scope setting"); 2493 2494 Element scope=_getRootElement("scope"); 2495 scope.setAttribute("cgi-readonly",Caster.toString(cgiReadonly,"")); 2496 } 2497 2498 /** 2499 * set if domain cookies are enabled or not 2500 * @param domainCookies 2501 * @throws SecurityException 2502 */ 2503 public void updateDomaincookies(Boolean domainCookies) throws SecurityException { 2504 checkWriteAccess(); 2505 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2506 if(!hasAccess) 2507 throw new SecurityException("no access to update scope setting"); 2508 2509 Element scope=_getRootElement("scope"); 2510 scope.setAttribute("setdomaincookies",Caster.toString(domainCookies,"")); 2511 } 2512 2513 /** 2514 * update the locale 2515 * @param locale 2516 * @throws SecurityException 2517 */ 2518 public void updateLocale(String locale) throws SecurityException { 2519 checkWriteAccess(); 2520 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2521 if(!hasAccess) 2522 throw new SecurityException("no access to update regional setting"); 2523 2524 Element scope=_getRootElement("regional"); 2525 scope.setAttribute("locale",locale.trim()); 2526 } 2527 2528 public void updateMonitorEnabled(boolean updateMonitorEnabled) throws SecurityException { 2529 checkWriteAccess(); 2530 2531 Element scope=_getRootElement("monitoring"); 2532 scope.setAttribute("enabled",Caster.toString(updateMonitorEnabled)); 2533 } 2534 2535 2536 2537 public void updateScriptProtect(String strScriptProtect) throws SecurityException { 2538 checkWriteAccess(); 2539 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2540 if(!hasAccess) 2541 throw new SecurityException("no access to update script protect"); 2542 2543 Element scope=_getRootElement("application"); 2544 scope.setAttribute("script-protect",strScriptProtect.trim()); 2545 } 2546 2547 public void updateAllowURLRequestTimeout(Boolean allowURLRequestTimeout) throws SecurityException { 2548 checkWriteAccess(); 2549 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2550 if(!hasAccess) 2551 throw new SecurityException("no access to update AllowURLRequestTimeout"); 2552 2553 Element scope=_getRootElement("application"); 2554 scope.setAttribute("allow-url-requesttimeout",Caster.toString(allowURLRequestTimeout,"")); 2555 } 2556 2557 public void updateQueue(Integer max, Integer timeout, Boolean enable) throws SecurityException { 2558 checkWriteAccess(); 2559 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2560 if(!hasAccess) throw new SecurityException("no access to update queue settings"); 2561 2562 Element queue=_getRootElement("queue"); 2563 // max 2564 if(max==null) queue.removeAttribute("max"); 2565 else queue.setAttribute("max",Caster.toString(max,"")); 2566 // total 2567 if(timeout==null) queue.removeAttribute("timeout"); 2568 else queue.setAttribute("timeout",Caster.toString(timeout,"")); 2569 // enable 2570 if(enable==null) queue.removeAttribute("enable"); 2571 else queue.setAttribute("enable",Caster.toString(enable,"")); 2572 } 2573 2574 public void updateScriptProtect(int scriptProtect) throws SecurityException { 2575 updateScriptProtect(AppListenerUtil.translateScriptProtect(scriptProtect)); 2576 } 2577 2578 /** 2579 * update the timeZone 2580 * @param timeZone 2581 * @throws SecurityException 2582 */ 2583 public void updateTimeZone(String timeZone) throws SecurityException { 2584 checkWriteAccess(); 2585 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2586 if(!hasAccess) 2587 throw new SecurityException("no access to update regional setting"); 2588 2589 Element regional=_getRootElement("regional"); 2590 regional.setAttribute("timezone",timeZone.trim()); 2591 2592 } 2593 2594 /** 2595 * update the timeServer 2596 * @param timeServer 2597 * @param useTimeServer 2598 * @throws PageException 2599 */ 2600 public void updateTimeServer(String timeServer, Boolean useTimeServer) throws PageException { 2601 checkWriteAccess(); 2602 if(useTimeServer!=null && useTimeServer.booleanValue() && !StringUtil.isEmpty(timeServer,true)) { 2603 try { 2604 new NtpClient(timeServer).getOffset(); 2605 } catch (IOException e) { 2606 throw new ExpressionException("invalid timeserver (NTP) ["+timeServer+"] "); 2607 } 2608 } 2609 2610 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2611 if(!hasAccess) 2612 throw new SecurityException("no access to update regional setting"); 2613 2614 Element scope=_getRootElement("regional"); 2615 scope.setAttribute("timeserver",timeServer.trim()); 2616 if(useTimeServer!=null)scope.setAttribute("use-timeserver",Caster.toString(useTimeServer)); 2617 else scope.removeAttribute("use-timeserver"); 2618 } 2619 2620 /** 2621 * update the baseComponent 2622 * @param baseComponent 2623 * @throws SecurityException 2624 */ 2625 public void updateBaseComponent(String baseComponent) throws SecurityException { 2626 checkWriteAccess(); 2627 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2628 if(!hasAccess) 2629 throw new SecurityException("no access to update component setting"); 2630 //config.resetBaseComponentPage(); 2631 Element scope=_getRootElement("component"); 2632 //if(baseComponent.trim().length()>0) 2633 scope.setAttribute("base",baseComponent); 2634 } 2635 2636 2637 2638 public void updateComponentDeepSearch(Boolean deepSearch) throws SecurityException { 2639 checkWriteAccess(); 2640 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2641 if(!hasAccess) 2642 throw new SecurityException("no access to update component setting"); 2643 //config.resetBaseComponentPage(); 2644 Element scope=_getRootElement("component"); 2645 //if(baseComponent.trim().length()>0) 2646 if(deepSearch!=null) 2647 scope.setAttribute("deep-search",Caster.toString(deepSearch.booleanValue())); 2648 2649 else { 2650 if(scope.hasAttribute("deep-search")) 2651 scope.removeAttribute("deep-search"); 2652 } 2653 2654 } 2655 2656 2657 public void updateComponentDefaultImport(String componentDefaultImport) throws SecurityException { 2658 checkWriteAccess(); 2659 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2660 if(!hasAccess) 2661 throw new SecurityException("no access to update component setting"); 2662 //config.resetBaseComponentPage(); 2663 Element scope=_getRootElement("component"); 2664 //if(baseComponent.trim().length()>0) 2665 scope.setAttribute("component-default-import",componentDefaultImport); 2666 } 2667 2668 2669 2670 2671 /** 2672 * update the Component Data Member default access type 2673 * @param access 2674 * @throws SecurityException 2675 * @throws ExpressionException 2676 */ 2677 public void updateComponentDataMemberDefaultAccess(String strAccess) throws SecurityException, ExpressionException { 2678 checkWriteAccess(); 2679 2680 2681 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2682 if(!hasAccess) 2683 throw new SecurityException("no access to update component setting"); 2684 2685 Element scope=_getRootElement("component"); 2686 2687 if(StringUtil.isEmpty(strAccess)){ 2688 scope.setAttribute("data-member-default-access",""); 2689 } 2690 else{ 2691 scope.setAttribute("data-member-default-access",ComponentUtil.toStringAccess(ComponentUtil.toIntAccess(strAccess))); 2692 } 2693 } 2694 2695 /** 2696 * update the Component Data Member default access type 2697 * @param accessType 2698 * @throws SecurityException 2699 */ 2700 public void updateTriggerDataMember(Boolean triggerDataMember) throws SecurityException { 2701 checkWriteAccess(); 2702 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2703 if(!hasAccess) 2704 throw new SecurityException("no access to update trigger-data-member"); 2705 2706 Element scope=_getRootElement("component"); 2707 scope.setAttribute("trigger-data-member",Caster.toString(triggerDataMember,"")); 2708 } 2709 2710 public void updateComponentUseShadow(Boolean useShadow) throws SecurityException { 2711 checkWriteAccess(); 2712 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2713 if(!hasAccess) 2714 throw new SecurityException("no access to update use-shadow"); 2715 2716 Element scope=_getRootElement("component"); 2717 scope.setAttribute("use-shadow",Caster.toString(useShadow,"")); 2718 } 2719 2720 public void updateComponentLocalSearch(Boolean componentLocalSearch) throws SecurityException { 2721 checkWriteAccess(); 2722 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2723 if(!hasAccess) 2724 throw new SecurityException("no access to update component Local Search"); 2725 2726 Element scope=_getRootElement("component"); 2727 scope.setAttribute("local-search",Caster.toString(componentLocalSearch,"")); 2728 } 2729 2730 public void updateComponentPathCache(Boolean componentPathCache) throws SecurityException { 2731 checkWriteAccess(); 2732 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2733 if(!hasAccess) 2734 throw new SecurityException("no access to update component Cache Path"); 2735 2736 Element scope=_getRootElement("component"); 2737 if(!Caster.toBooleanValue(componentPathCache,false)) 2738 config.clearComponentCache(); 2739 scope.setAttribute("use-cache-path",Caster.toString(componentPathCache,"")); 2740 } 2741 public void updateCTPathCache(Boolean ctPathCache) throws SecurityException { 2742 checkWriteAccess(); 2743 if(!ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_CUSTOM_TAG)) 2744 throw new SecurityException("no access to update custom tag setting"); 2745 2746 if(!Caster.toBooleanValue(ctPathCache,false)) 2747 config.clearCTCache(); 2748 Element scope=_getRootElement("custom-tag"); 2749 scope.setAttribute("use-cache-path",Caster.toString(ctPathCache,"")); 2750 } 2751 2752 2753 2754 2755 /** 2756 * updates if debugging or not 2757 * @param debug if value is null server setting is used 2758 * @throws SecurityException 2759 */ 2760 public void updateDebug(Boolean debug, Boolean database, Boolean exception, Boolean tracing, Boolean dump, Boolean timer, 2761 Boolean implicitAccess, Boolean queryUsage) throws SecurityException { 2762 checkWriteAccess(); 2763 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DEBUGGING); 2764 if(!hasAccess) 2765 throw new SecurityException("no access to change debugging settings"); 2766 Element debugging=_getRootElement("debugging"); 2767 2768 if(debug!=null)debugging.setAttribute("debug",Caster.toString(debug.booleanValue())); 2769 else debugging.removeAttribute("debug"); 2770 2771 if(database!=null)debugging.setAttribute("database",Caster.toString(database.booleanValue())); 2772 else debugging.removeAttribute("database"); 2773 2774 if(exception!=null)debugging.setAttribute("exception",Caster.toString(exception.booleanValue())); 2775 else debugging.removeAttribute("exception"); 2776 2777 if(tracing!=null)debugging.setAttribute("tracing",Caster.toString(tracing.booleanValue())); 2778 else debugging.removeAttribute("tracing"); 2779 2780 if(dump!=null)debugging.setAttribute("dump",Caster.toString(dump.booleanValue())); 2781 else debugging.removeAttribute("dump"); 2782 2783 if(timer!=null)debugging.setAttribute("timer",Caster.toString(timer.booleanValue())); 2784 else debugging.removeAttribute("timer"); 2785 2786 if(implicitAccess!=null)debugging.setAttribute("implicit-access",Caster.toString(implicitAccess.booleanValue())); 2787 else debugging.removeAttribute("implicit-access"); 2788 2789 if(queryUsage!=null)debugging.setAttribute("query-usage",Caster.toString(queryUsage.booleanValue())); 2790 else debugging.removeAttribute("query-usage"); 2791 2792 2793 } 2794 2795 /** 2796 * updates the DebugTemplate 2797 * @param template 2798 * @throws SecurityException 2799 */ 2800 public void updateDebugTemplate(String template) throws SecurityException { 2801 checkWriteAccess(); 2802 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DEBUGGING); 2803 if(!hasAccess) 2804 throw new SecurityException("no access to change debugging settings"); 2805 2806 Element debugging=_getRootElement("debugging"); 2807 //if(template.trim().length()>0) 2808 debugging.setAttribute("template",template); 2809 } 2810 2811 /** 2812 * updates the ErrorTemplate 2813 * @param template 2814 * @throws SecurityException 2815 */ 2816 public void updateErrorTemplate(int statusCode,String template) throws SecurityException { 2817 checkWriteAccess(); 2818 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DEBUGGING); 2819 if(!hasAccess) 2820 throw new SecurityException("no access to change error settings"); 2821 2822 Element error=_getRootElement("error"); 2823 //if(template.trim().length()>0) 2824 error.setAttribute("template-"+statusCode,template); 2825 } 2826 2827 2828 public void updateErrorStatusCode(Boolean doStatusCode) throws SecurityException { 2829 checkWriteAccess(); 2830 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DEBUGGING); 2831 if(!hasAccess) 2832 throw new SecurityException("no access to change error settings"); 2833 2834 Element error=_getRootElement("error"); 2835 error.setAttribute("status-code",Caster.toString(doStatusCode,"")); 2836 } 2837 2838 /** 2839 * updates the DebugTemplate 2840 * @param template 2841 * @throws SecurityException 2842 */ 2843 public void updateComponentDumpTemplate(String template) throws SecurityException { 2844 checkWriteAccess(); 2845 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 2846 if(!hasAccess) 2847 throw new SecurityException("no access to update component setting"); 2848 2849 Element component=_getRootElement("component"); 2850 //if(template.trim().length()>0) 2851 component.setAttribute("dump-template",template); 2852 } 2853 2854 /* * 2855 * updates the if memory usage will be logged or not 2856 * @param logMemoryUsage 2857 * @throws SecurityException 2858 * / 2859 public void updateLogMemoryUsage(boolean logMemoryUsage) throws SecurityException { 2860 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DEBUGGING); 2861 if(!hasAccess) 2862 throw new SecurityException("no access to change debugging settings"); 2863 2864 Element debugging=_getRootElement("debugging"); 2865 debugging.setAttribute("log-memory-usage",Caster.toString(logMemoryUsage)); 2866 }*/ 2867 2868 /* * 2869 * updates the Memory Logger 2870 * @param memoryLogger 2871 * @throws SecurityException 2872 * / 2873 public void updateMemoryLogger(String memoryLogger) throws SecurityException { 2874 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DEBUGGING); 2875 if(!hasAccess) 2876 throw new SecurityException("no access to change debugging settings"); 2877 2878 Element debugging=_getRootElement("debugging"); 2879 if(memoryLogger.trim().length()>0)debugging.setAttribute("memory-log",memoryLogger); 2880 }*/ 2881 2882 private Element _getRootElement(String name) { 2883 Element el=ConfigWebFactory.getChildByName(doc.getDocumentElement(),name); 2884 if(el==null) { 2885 el=doc.createElement(name); 2886 doc.getDocumentElement().appendChild(el); 2887 } 2888 return el; 2889 } 2890 2891 private Element _getRootElement(String name, boolean insertBefore,boolean doNotCreate) { 2892 return ConfigWebFactory.getChildByName(doc.getDocumentElement(),name,insertBefore,doNotCreate); 2893 } 2894 2895 /** 2896 * @param setting 2897 * @param file 2898 * @param directJavaAccess 2899 * @param mail 2900 * @param datasource 2901 * @param mapping 2902 * @param customTag 2903 * @param cfxSetting 2904 * @param cfxUsage 2905 * @param debugging 2906 * @param search 2907 * @param scheduledTasks 2908 * @param tagExecute 2909 * @param tagImport 2910 * @param tagObject 2911 * @param tagRegistry 2912 * @throws SecurityException 2913 */ 2914 public void updateDefaultSecurity(short setting, short file,Resource[] fileAccess,short directJavaAccess, 2915 short mail, short datasource, short mapping, short remote, short customTag, 2916 short cfxSetting, short cfxUsage, short debugging, 2917 short search, short scheduledTasks, 2918 short tagExecute,short tagImport, short tagObject, short tagRegistry, 2919 short cache, short gateway,short orm, 2920 short accessRead, short accessWrite) throws SecurityException { 2921 checkWriteAccess(); 2922 if(!(config instanceof ConfigServer)) 2923 throw new SecurityException("can't change security settings from this context"); 2924 2925 Element security=_getRootElement("security"); 2926 updateSecurityFileAccess(security,fileAccess,file); 2927 security.setAttribute("setting", SecurityManagerImpl.toStringAccessValue(setting)); 2928 security.setAttribute("file", SecurityManagerImpl.toStringAccessValue(file)); 2929 security.setAttribute("direct_java_access", SecurityManagerImpl.toStringAccessValue(directJavaAccess)); 2930 security.setAttribute("mail", SecurityManagerImpl.toStringAccessValue(mail)); 2931 security.setAttribute("datasource", SecurityManagerImpl.toStringAccessValue(datasource)); 2932 security.setAttribute("mapping", SecurityManagerImpl.toStringAccessValue(mapping)); 2933 security.setAttribute("remote", SecurityManagerImpl.toStringAccessValue(remote)); 2934 security.setAttribute("custom_tag", SecurityManagerImpl.toStringAccessValue(customTag)); 2935 security.setAttribute("cfx_setting", SecurityManagerImpl.toStringAccessValue(cfxSetting)); 2936 security.setAttribute("cfx_usage", SecurityManagerImpl.toStringAccessValue(cfxUsage)); 2937 security.setAttribute("debugging", SecurityManagerImpl.toStringAccessValue(debugging)); 2938 security.setAttribute("search", SecurityManagerImpl.toStringAccessValue(search)); 2939 security.setAttribute("scheduled_task", SecurityManagerImpl.toStringAccessValue(scheduledTasks)); 2940 2941 security.setAttribute("tag_execute", SecurityManagerImpl.toStringAccessValue(tagExecute)); 2942 security.setAttribute("tag_import", SecurityManagerImpl.toStringAccessValue(tagImport)); 2943 security.setAttribute("tag_object", SecurityManagerImpl.toStringAccessValue(tagObject)); 2944 security.setAttribute("tag_registry", SecurityManagerImpl.toStringAccessValue(tagRegistry)); 2945 security.setAttribute("cache", SecurityManagerImpl.toStringAccessValue(cache)); 2946 security.setAttribute("gateway", SecurityManagerImpl.toStringAccessValue(gateway)); 2947 security.setAttribute("orm", SecurityManagerImpl.toStringAccessValue(orm)); 2948 2949 security.setAttribute("access_read", SecurityManagerImpl.toStringAccessRWValue(accessRead)); 2950 security.setAttribute("access_write", SecurityManagerImpl.toStringAccessRWValue(accessWrite)); 2951 2952 2953 2954 } 2955 2956 private void removeSecurityFileAccess(Element parent) { 2957 Element[] children = ConfigWebFactory.getChildren(parent,"file-access"); 2958 2959 // remove existing 2960 if(!ArrayUtil.isEmpty(children)){ 2961 for(int i=children.length-1;i>=0;i--){ 2962 parent.removeChild(children[i]); 2963 } 2964 } 2965 } 2966 2967 private void updateSecurityFileAccess(Element parent,Resource[] fileAccess, short file) { 2968 removeSecurityFileAccess(parent); 2969 2970 // insert 2971 if(!ArrayUtil.isEmpty(fileAccess) && file!=SecurityManager.VALUE_ALL){ 2972 Element fa; 2973 for(int i=0;i<fileAccess.length;i++){ 2974 fa=doc.createElement("file-access"); 2975 fa.setAttribute("path", fileAccess[i].getAbsolutePath()); 2976 parent.appendChild(fa); 2977 } 2978 } 2979 2980 } 2981 2982 2983 /** 2984 * update a security manager that match the given id 2985 * @param id 2986 * @param setting 2987 * @param file 2988 * @param file_access 2989 * @param directJavaAccess 2990 * @param mail 2991 * @param datasource 2992 * @param mapping 2993 * @param customTag 2994 * @param cfxSetting 2995 * @param cfxUsage 2996 * @param debugging 2997 * @param search 2998 * @param scheduledTasks 2999 * @param tagExecute 3000 * @param tagImport 3001 * @param tagObject 3002 * @param tagRegistry 3003 * @throws SecurityException 3004 * @throws ApplicationException 3005 */ 3006 public void updateSecurity(String id, short setting, short file,Resource[] fileAccess, short directJavaAccess, 3007 short mail, short datasource, short mapping, short remote, short customTag, 3008 short cfxSetting, short cfxUsage, short debugging, 3009 short search, short scheduledTasks, 3010 short tagExecute,short tagImport, short tagObject, short tagRegistry, 3011 short cache,short gateway,short orm, 3012 short accessRead, short accessWrite) throws SecurityException, ApplicationException { 3013 checkWriteAccess(); 3014 if(!(config instanceof ConfigServer)) 3015 throw new SecurityException("can't change security settings from this context"); 3016 3017 Element security=_getRootElement("security"); 3018 Element[] children = ConfigWebFactory.getChildren(security,"accessor"); 3019 Element accessor=null; 3020 for(int i=0;i<children.length;i++) { 3021 if(id.equals(children[i].getAttribute("id"))) { 3022 accessor=children[i]; 3023 } 3024 } 3025 if(accessor==null) throw new ApplicationException("there is noc Security Manager for id ["+id+"]"); 3026 updateSecurityFileAccess(accessor,fileAccess,file); 3027 3028 accessor.setAttribute("setting", SecurityManagerImpl.toStringAccessValue(setting)); 3029 accessor.setAttribute("file", SecurityManagerImpl.toStringAccessValue(file)); 3030 accessor.setAttribute("direct_java_access", SecurityManagerImpl.toStringAccessValue(directJavaAccess)); 3031 accessor.setAttribute("mail", SecurityManagerImpl.toStringAccessValue(mail)); 3032 accessor.setAttribute("datasource", SecurityManagerImpl.toStringAccessValue(datasource)); 3033 accessor.setAttribute("mapping", SecurityManagerImpl.toStringAccessValue(mapping)); 3034 accessor.setAttribute("remote", SecurityManagerImpl.toStringAccessValue(remote)); 3035 accessor.setAttribute("custom_tag", SecurityManagerImpl.toStringAccessValue(customTag)); 3036 accessor.setAttribute("cfx_setting", SecurityManagerImpl.toStringAccessValue(cfxSetting)); 3037 accessor.setAttribute("cfx_usage", SecurityManagerImpl.toStringAccessValue(cfxUsage)); 3038 accessor.setAttribute("debugging", SecurityManagerImpl.toStringAccessValue(debugging)); 3039 accessor.setAttribute("search", SecurityManagerImpl.toStringAccessValue(search)); 3040 accessor.setAttribute("scheduled_task", SecurityManagerImpl.toStringAccessValue(scheduledTasks)); 3041 accessor.setAttribute("cache", SecurityManagerImpl.toStringAccessValue(cache)); 3042 accessor.setAttribute("gateway", SecurityManagerImpl.toStringAccessValue(gateway)); 3043 accessor.setAttribute("orm", SecurityManagerImpl.toStringAccessValue(orm)); 3044 3045 accessor.setAttribute("tag_execute", SecurityManagerImpl.toStringAccessValue(tagExecute)); 3046 accessor.setAttribute("tag_import", SecurityManagerImpl.toStringAccessValue(tagImport)); 3047 accessor.setAttribute("tag_object", SecurityManagerImpl.toStringAccessValue(tagObject)); 3048 accessor.setAttribute("tag_registry", SecurityManagerImpl.toStringAccessValue(tagRegistry)); 3049 3050 accessor.setAttribute("access_read", SecurityManagerImpl.toStringAccessRWValue(accessRead)); 3051 accessor.setAttribute("access_write", SecurityManagerImpl.toStringAccessRWValue(accessWrite)); 3052 } 3053 3054 3055 3056 3057 /** 3058 * @return returns the default password 3059 * @throws SecurityException 3060 */ 3061 public Password getDefaultPassword() throws SecurityException { 3062 checkReadAccess(); 3063 if(config instanceof ConfigServerImpl) { 3064 return ((ConfigServerImpl)config).getDefaultPassword(); 3065 } 3066 throw new SecurityException("can't access default password within this context"); 3067 } 3068 /** 3069 * @param password 3070 * @throws SecurityException 3071 * @throws IOException 3072 * @throws DOMException 3073 */ 3074 public void updateDefaultPassword(String password) throws SecurityException, DOMException, IOException { 3075 checkWriteAccess(); 3076 ((ConfigServerImpl)config).setDefaultPassword(Password.hashAndStore(doc.getDocumentElement(),password,true)); 3077 3078 } 3079 3080 public void removeDefaultPassword() throws SecurityException { 3081 checkWriteAccess(); 3082 Element root=doc.getDocumentElement(); 3083 Password.remove(root,true); 3084 ((ConfigServerImpl)config).setDefaultPassword(null); 3085 } 3086 3087 /** 3088 * session type update 3089 * @param type 3090 * @throws SecurityException 3091 */ 3092 public void updateSessionType(String type) throws SecurityException { 3093 checkWriteAccess(); 3094 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 3095 if(!hasAccess) throw new SecurityException("no access to update scope setting"); 3096 3097 type=type.toLowerCase().trim(); 3098 3099 Element scope=_getRootElement("scope"); 3100 scope.setAttribute("session-type",type); 3101 } 3102 3103 public void updateLocalMode(String mode) throws SecurityException { 3104 checkWriteAccess(); 3105 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING); 3106 if(!hasAccess) throw new SecurityException("no access to update scope setting"); 3107 3108 mode=mode.toLowerCase().trim(); 3109 Element scope=_getRootElement("scope"); 3110 scope.setAttribute("local-mode",mode); 3111 } 3112 3113 3114 3115 3116 public void updateRestList(Boolean list) throws SecurityException { 3117 checkWriteAccess(); 3118 boolean hasAccess=true;// TODO ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_REST); 3119 if(!hasAccess) throw new SecurityException("no access to update rest setting"); 3120 3121 3122 Element rest=_getRootElement("rest"); 3123 if(list==null) { 3124 if(rest.hasAttribute("list"))rest.removeAttribute("list"); 3125 } 3126 else rest.setAttribute("list", Caster.toString(list.booleanValue())); 3127 } 3128 3129 /*public void updateRestAllowChanges(Boolean allowChanges) throws SecurityException { 3130 checkWriteAccess(); 3131 boolean hasAccess=true;// TODO ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_REST); 3132 if(!hasAccess) throw new SecurityException("no access to update rest setting"); 3133 3134 3135 Element rest=_getRootElement("rest"); 3136 if(allowChanges==null) { 3137 if(rest.hasAttribute("allow-changes"))rest.removeAttribute("allow-changes"); 3138 } 3139 else rest.setAttribute("allow-changes", Caster.toString(allowChanges.booleanValue())); 3140 }*/ 3141 3142 3143 /** 3144 * updates update settingd for lucee 3145 * @param type 3146 * @param location 3147 * @throws SecurityException 3148 */ 3149 public void updateUpdate(String type, String location) throws SecurityException { 3150 checkWriteAccess(); 3151 3152 if(!(config instanceof ConfigServer)) { 3153 throw new SecurityException("can't change update setting from this context, access is denied"); 3154 } 3155 Element update=_getRootElement("update"); 3156 update.setAttribute("type",type); 3157 try { 3158 location=HTTPUtil.toURL(location,true).toString(); 3159 } 3160 catch (Throwable e) { 3161 ExceptionUtil.rethrowIfNecessary(e); 3162 } 3163 update.setAttribute("location",location); 3164 } 3165 3166 /** 3167 * creates a individual security manager based on the default security manager 3168 * @param id 3169 * @throws DOMException 3170 * @throws PageException 3171 */ 3172 public void createSecurityManager(String password,String id) throws DOMException, PageException { 3173 checkWriteAccess(); 3174 ConfigServerImpl cs=(ConfigServerImpl) config.getConfigServer(password); 3175 SecurityManagerImpl dsm = (SecurityManagerImpl) cs.getDefaultSecurityManager().cloneSecurityManager(); 3176 cs.setSecurityManager(id,dsm); 3177 3178 Element security=_getRootElement("security"); 3179 Element accessor=null; 3180 3181 Element[] children = ConfigWebFactory.getChildren(security,"accessor"); 3182 for(int i=0;i<children.length;i++) { 3183 if(id.equals(children[i].getAttribute("id"))) { 3184 accessor=children[i]; 3185 } 3186 } 3187 if(accessor==null) { 3188 accessor=doc.createElement("accessor"); 3189 security.appendChild(accessor); 3190 } 3191 3192 updateSecurityFileAccess(accessor,dsm.getCustomFileAccess(),dsm.getAccess(SecurityManager.TYPE_FILE)); 3193 3194 3195 accessor.setAttribute("id",id); 3196 accessor.setAttribute("setting", SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_SETTING))); 3197 accessor.setAttribute("file", SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_FILE))); 3198 accessor.setAttribute("direct_java_access", SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS))); 3199 accessor.setAttribute("mail", SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_MAIL))); 3200 accessor.setAttribute("datasource", SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_DATASOURCE))); 3201 accessor.setAttribute("mapping", SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_MAPPING))); 3202 accessor.setAttribute("custom_tag", SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_CUSTOM_TAG))); 3203 accessor.setAttribute("cfx_setting", SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_CFX_SETTING))); 3204 accessor.setAttribute("cfx_usage", SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_CFX_USAGE))); 3205 accessor.setAttribute("debugging", SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_DEBUGGING))); 3206 accessor.setAttribute("cache", SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManagerImpl.TYPE_CACHE))); 3207 accessor.setAttribute("gateway", SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManagerImpl.TYPE_GATEWAY))); 3208 accessor.setAttribute("orm", SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManagerImpl.TYPE_ORM))); 3209 3210 accessor.setAttribute("tag_execute", SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_TAG_EXECUTE))); 3211 accessor.setAttribute("tag_import", SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_TAG_IMPORT))); 3212 accessor.setAttribute("tag_object", SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_TAG_OBJECT))); 3213 accessor.setAttribute("tag_registry", SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_TAG_REGISTRY))); 3214 3215 } 3216 3217 3218 /** 3219 * remove security manager matching given id 3220 * @param id 3221 * @throws PageException 3222 */ 3223 public void removeSecurityManager(String password,String id) throws PageException { 3224 checkWriteAccess(); 3225 ((ConfigServerImpl)config.getConfigServer(password)).removeSecurityManager(id); 3226 3227 Element security=_getRootElement("security"); 3228 3229 3230 Element[] children = ConfigWebFactory.getChildren(security,"accessor"); 3231 for(int i=0;i<children.length;i++) { 3232 if(id.equals(children[i].getAttribute("id"))) { 3233 security.removeChild(children[i]); 3234 } 3235 } 3236 } 3237 3238 /** 3239 * run update from cfml engine 3240 * @throws PageException 3241 */ 3242 public void runUpdate(String password) throws PageException { 3243 checkWriteAccess(); 3244 ConfigServerImpl cs = (ConfigServerImpl) config.getConfigServer(password); 3245 CFMLEngineFactory factory = cs.getCFMLEngine().getCFMLEngineFactory(); 3246 synchronized(factory){ 3247 try { 3248 factory.update(cs.getPassword().password); 3249 } 3250 catch (Exception e) { 3251 throw Caster.toPageException(e); 3252 } 3253 } 3254 3255 } 3256 3257 /** 3258 * run update from cfml engine 3259 * @throws PageException 3260 */ 3261 public void removeLatestUpdate(String password) throws PageException { 3262 _removeUpdate(password,true); 3263 } 3264 3265 public void removeUpdate(String password) throws PageException { 3266 _removeUpdate(password,false); 3267 } 3268 3269 private void _removeUpdate(String password,boolean onlyLatest) throws PageException { 3270 checkWriteAccess(); 3271 ConfigServerImpl cs = (ConfigServerImpl) config.getConfigServer(password); 3272 try { 3273 CFMLEngineFactory factory = cs.getCFMLEngine().getCFMLEngineFactory(); 3274 3275 if(onlyLatest){ 3276 try{ 3277 factory.removeLatestUpdate(cs.getPassword().password); 3278 } 3279 catch(Throwable t) { 3280 ExceptionUtil.rethrowIfNecessary(t); 3281 removeLatestUpdateOld(factory,cs.getPassword().password); 3282 } 3283 } 3284 else factory.removeUpdate(cs.getPassword().password); 3285 3286 3287 } 3288 catch (Exception e) { 3289 throw Caster.toPageException(e); 3290 } 3291 } 3292 3293 private String getCoreExtension() { 3294 return "lco"; 3295 } 3296 3297 private boolean isNewerThan(int left, int right) { 3298 return left>right; 3299 } 3300 3301 private boolean removeLatestUpdateOld(CFMLEngineFactory factory, String password) throws IOException, ServletException { 3302 File patchDir = new File(factory.getResourceRoot(),"patches"); 3303 if(!patchDir.exists())patchDir.mkdirs(); 3304 3305 File[] patches=patchDir.listFiles(new ExtensionFilter(new String[]{"."+getCoreExtension()})); 3306 File patch=null; 3307 for(int i=0;i<patches.length;i++) { 3308 if(patch==null || isNewerThan(lucee.loader.util.Util.toInVersion(patches[i].getName()),lucee.loader.util.Util.toInVersion(patch.getName()))) { 3309 patch=patches[i]; 3310 } 3311 } 3312 if(patch!=null && !patch.delete())patch.deleteOnExit(); 3313 factory.restart(password); 3314 return true; 3315 } 3316 3317 3318 /*private Resource getPatchDirectory(CFMLEngine engine) throws IOException { 3319 //File f=engine.getCFMLEngineFactory().getResourceRoot(); 3320 Resource res = ResourcesImpl.getFileResourceProvider().getResource(engine.getCFMLEngineFactory().getResourceRoot().getAbsolutePath()); 3321 Resource pd = res.getRealResource("patches"); 3322 if(!pd.exists())pd.mkdirs(); 3323 return pd; 3324 }*/ 3325 3326 3327 3328 3329 /** 3330 * run update from cfml engine 3331 * @throws PageException 3332 */ 3333 public void restart(String password) throws PageException { 3334 checkWriteAccess(); 3335 ConfigServerImpl cs = (ConfigServerImpl) config.getConfigServer(password); 3336 CFMLEngineFactory factory = cs.getCFMLEngine().getCFMLEngineFactory(); 3337 synchronized(factory){ 3338 try { 3339 factory.restart(cs.getPassword().password); 3340 } 3341 catch (Exception e) { 3342 throw Caster.toPageException(e); 3343 } 3344 } 3345 } 3346 3347 public void updateWebCharset(String charset) throws PageException { 3348 checkWriteAccess(); 3349 3350 Element element = _getRootElement("charset"); 3351 if(StringUtil.isEmpty(charset)){ 3352 if(config instanceof ConfigWeb) 3353 element.removeAttribute("web-charset"); 3354 else 3355 element.setAttribute("web-charset", "UTF-8"); 3356 } 3357 else { 3358 charset=checkCharset(charset); 3359 element.setAttribute("web-charset", charset); 3360 } 3361 3362 element = _getRootElement("regional"); 3363 element.removeAttribute("default-encoding");// remove deprecated attribute 3364 3365 } 3366 3367 public void updateResourceCharset(String charset) throws PageException { 3368 checkWriteAccess(); 3369 3370 Element element = _getRootElement("charset"); 3371 if(StringUtil.isEmpty(charset)){ 3372 element.removeAttribute("resource-charset"); 3373 } 3374 else { 3375 charset=checkCharset(charset); 3376 element.setAttribute("resource-charset", charset); 3377 3378 } 3379 3380 // update charset 3381 3382 } 3383 3384 public void updateTemplateCharset(String charset) throws PageException { 3385 3386 checkWriteAccess(); 3387 3388 Element element = _getRootElement("charset"); 3389 if(StringUtil.isEmpty(charset,true)){ 3390 element.removeAttribute("template-charset"); 3391 } 3392 else { 3393 charset=checkCharset(charset); 3394 element.setAttribute("template-charset", charset); 3395 } 3396 } 3397 3398 private String checkCharset(String charset) throws PageException{ 3399 charset=charset.trim(); 3400 if("system".equalsIgnoreCase(charset)) 3401 charset=SystemUtil.getCharset().name(); 3402 else if("jre".equalsIgnoreCase(charset)) 3403 charset=SystemUtil.getCharset().name(); 3404 else if("os".equalsIgnoreCase(charset)) 3405 charset=SystemUtil.getCharset().name(); 3406 3407 // check access 3408 boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_SETTING); 3409 if(!hasAccess) { 3410 throw new SecurityException("no access to update regional setting"); 3411 } 3412 3413 // check encoding 3414 try { 3415 IOUtil.checkEncoding(charset); 3416 } 3417 catch (IOException e) {throw Caster.toPageException(e);} 3418 return charset; 3419 } 3420 3421 3422 private Resource getStoragDir(Config config) { 3423 Resource storageDir = config.getConfigDir().getRealResource("storage"); 3424 if(!storageDir.exists())storageDir.mkdirs(); 3425 return storageDir; 3426 } 3427 3428 public void storageSet(Config config,String key, Object value) throws ConverterException, IOException, SecurityException { 3429 checkWriteAccess(); 3430 Resource storageDir = getStoragDir(config); 3431 Resource storage=storageDir.getRealResource(key+".wddx"); 3432 3433 WDDXConverter converter =new WDDXConverter(config.getTimeZone(),true,true); 3434 String wddx=converter.serialize(value); 3435 IOUtil.write(storage, wddx, "UTF-8", false); 3436 } 3437 3438 3439 public Object storageGet(Config config, String key) throws ConverterException, IOException, SecurityException { 3440 checkReadAccess(); 3441 Resource storageDir = getStoragDir(config); 3442 Resource storage=storageDir.getRealResource(key+".wddx"); 3443 if(!storage.exists()) throw new IOException("there is no storage with name "+key); 3444 WDDXConverter converter =new WDDXConverter(config.getTimeZone(),true,true); 3445 return converter.deserialize(IOUtil.toString(storage,"UTF-8"), true); 3446 } 3447 3448 3449 public void updateCustomTagDeepSearch(boolean customTagDeepSearch) throws SecurityException { 3450 checkWriteAccess(); 3451 if(!ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_CUSTOM_TAG)) 3452 throw new SecurityException("no access to update custom tag setting"); 3453 3454 Element element = _getRootElement("custom-tag"); 3455 element.setAttribute("custom-tag-deep-search",Caster.toString(customTagDeepSearch)); 3456 } 3457 3458 public void resetId() throws PageException { 3459 checkWriteAccess(); 3460 Resource res=config.getConfigDir().getRealResource("id"); 3461 try { 3462 if(res.exists())res.remove(false); 3463 } catch (IOException e) { 3464 throw Caster.toPageException(e); 3465 } 3466 3467 } 3468 3469 public void updateCustomTagLocalSearch(boolean customTagLocalSearch) throws SecurityException { 3470 checkWriteAccess(); 3471 if(!ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_CUSTOM_TAG)) 3472 throw new SecurityException("no access to update custom tag setting"); 3473 3474 Element element = _getRootElement("custom-tag"); 3475 element.setAttribute("custom-tag-local-search",Caster.toString(customTagLocalSearch)); 3476 } 3477 3478 3479 3480 public void updateCustomTagExtensions(String extensions) throws PageException { 3481 checkWriteAccess(); 3482 if(!ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_CUSTOM_TAG)) 3483 throw new SecurityException("no access to update custom tag setting"); 3484 3485 // check 3486 Array arr = ListUtil.listToArrayRemoveEmpty(extensions, ','); 3487 ListUtil.trimItems(arr); 3488 //throw new ApplicationException("you must define at least one extension"); 3489 3490 3491 // update charset 3492 Element element = _getRootElement("custom-tag"); 3493 element.setAttribute("extensions",ListUtil.arrayToList(arr, ",")); 3494 } 3495 3496 3497 public void updateRemoteClient(String label,String url, String type, 3498 String securityKey, String usage, String adminPassword, String serverUsername, String serverPassword, 3499 String proxyServer, String proxyUsername, String proxyPassword, String proxyPort) throws PageException { 3500 checkWriteAccess(); 3501 3502 // SNSN 3503 3504 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_REMOTE); 3505 if(!hasAccess) 3506 throw new SecurityException("no access to update remote client settings"); 3507 3508 3509 Element clients=_getRootElement("remote-clients"); 3510 3511 if(StringUtil.isEmpty(url)) throw new ExpressionException("url can be a empty value"); 3512 if(StringUtil.isEmpty(securityKey)) throw new ExpressionException("securityKey can be a empty value"); 3513 if(StringUtil.isEmpty(adminPassword)) throw new ExpressionException("adminPassword can be a empty value"); 3514 url=url.trim(); 3515 securityKey=securityKey.trim(); 3516 adminPassword=adminPassword.trim(); 3517 3518 Element[] children = ConfigWebFactory.getChildren(clients,"remote-client"); 3519 3520 // Update 3521 for(int i=0;i<children.length;i++) { 3522 Element el=children[i]; 3523 String _url=el.getAttribute("url"); 3524 if(_url!=null && _url.equalsIgnoreCase(url)) { 3525 el.setAttribute("label",label); 3526 el.setAttribute("type",type); 3527 el.setAttribute("usage",usage); 3528 el.setAttribute("server-username",serverUsername); 3529 el.setAttribute("proxy-server",proxyServer); 3530 el.setAttribute("proxy-username",proxyUsername); 3531 el.setAttribute("proxy-port",proxyPort); 3532 el.setAttribute("security-key",ConfigWebFactory.encrypt(securityKey)); 3533 el.setAttribute("admin-password",ConfigWebFactory.encrypt(adminPassword)); 3534 el.setAttribute("server-password",ConfigWebFactory.encrypt(serverPassword)); 3535 el.setAttribute("proxy-password",ConfigWebFactory.encrypt(proxyPassword)); 3536 return ; 3537 } 3538 } 3539 3540 // Insert 3541 Element el = doc.createElement("remote-client"); 3542 3543 el.setAttribute("label",label); 3544 el.setAttribute("url",url); 3545 el.setAttribute("type",type); 3546 el.setAttribute("usage",usage); 3547 el.setAttribute("server-username",serverUsername); 3548 el.setAttribute("proxy-server",proxyServer); 3549 el.setAttribute("proxy-username",proxyUsername); 3550 el.setAttribute("proxy-port",proxyPort); 3551 el.setAttribute("security-key",ConfigWebFactory.encrypt(securityKey)); 3552 el.setAttribute("admin-password",ConfigWebFactory.encrypt(adminPassword)); 3553 el.setAttribute("server-password",ConfigWebFactory.encrypt(serverPassword)); 3554 el.setAttribute("proxy-password",ConfigWebFactory.encrypt(proxyPassword)); 3555 3556 3557 clients.appendChild(el); 3558 } 3559 3560 public void updateMonitor(String className,String type, String name, boolean logEnabled) throws PageException { 3561 checkWriteAccess(); 3562 3563 Element parent=_getRootElement("monitoring"); 3564 3565 3566 Element[] children = ConfigWebFactory.getChildren(parent,"monitor"); 3567 Element monitor=null; 3568 // Update 3569 for(int i=0;i<children.length;i++) { 3570 Element el=children[i]; 3571 String _name=el.getAttribute("name"); 3572 if(_name!=null && _name.equalsIgnoreCase(name)) { 3573 monitor=el; 3574 break; 3575 } 3576 } 3577 3578 // Insert 3579 if(monitor==null) { 3580 monitor = doc.createElement("monitor"); 3581 parent.appendChild(monitor); 3582 } 3583 3584 monitor.setAttribute("class",className); 3585 monitor.setAttribute("type",type); 3586 monitor.setAttribute("name",name); 3587 monitor.setAttribute("log",Caster.toString(logEnabled)); 3588 } 3589 3590 3591 3592 3593 public void updateExecutionLog(String className, Struct args, boolean enabled) { 3594 Element el=_getRootElement("execution-log"); 3595 el.setAttribute("class",className); 3596 el.setAttribute("arguments",toStringCSSStyle(args)); 3597 el.setAttribute("enabled",Caster.toString(enabled)); 3598 } 3599 3600 3601 3602 3603 3604 3605 public void removeMonitor(String name) throws PageException { 3606 checkWriteAccess(); 3607 3608 Element parent=_getRootElement("monitoring"); 3609 3610 3611 Element[] children = ConfigWebFactory.getChildren(parent,"monitor"); 3612 // Update 3613 for(int i=0;i<children.length;i++) { 3614 Element el=children[i]; 3615 String _name=el.getAttribute("name"); 3616 if(_name!=null && _name.equalsIgnoreCase(name)) { 3617 parent.removeChild(el); 3618 } 3619 } 3620 3621 } 3622 3623 3624 public void updateExtensionInfo(boolean enabled) { 3625 Element extensions=_getRootElement("extensions"); 3626 extensions.setAttribute("enabled", Caster.toString(enabled)); 3627 } 3628 3629 3630 public void updateExtensionProvider(String strUrl) { 3631 Element extensions=_getRootElement("extensions"); 3632 Element[] children = ConfigWebFactory.getChildren(extensions,"provider"); 3633 strUrl=strUrl.trim(); 3634 3635 // Update 3636 Element el; 3637 String url; 3638 for(int i=0;i<children.length;i++) { 3639 el=children[i]; 3640 url=el.getAttribute("url"); 3641 if( url!=null && url.trim().equalsIgnoreCase(strUrl)) { 3642 //el.setAttribute("cache-timeout",Caster.toString(cacheTimeout)); 3643 return ; 3644 } 3645 } 3646 3647 // Insert 3648 el = doc.createElement("provider"); 3649 3650 el.setAttribute("url",strUrl); 3651 //el.setAttribute("cache-timeout",Caster.toString(cacheTimeout)); 3652 3653 XMLUtil.prependChild(extensions,el); 3654 } 3655 3656 3657 public void removeExtensionProvider(String strUrl) { 3658 Element parent=_getRootElement("extensions"); 3659 Element[] children = ConfigWebFactory.getChildren(parent,"provider"); 3660 strUrl=strUrl.trim(); 3661 Element child; 3662 String url; 3663 for(int i=0;i<children.length;i++) { 3664 child=children[i]; 3665 url=child.getAttribute("url"); 3666 if( url!=null && url.trim().equalsIgnoreCase(strUrl)) { 3667 parent.removeChild(child); 3668 return ; 3669 } 3670 } 3671 } 3672 3673 3674 public void updateExtension(PageContext pc,Extension extension) throws PageException { 3675 checkWriteAccess(); 3676 3677 String uid = createUid(pc,extension.getProvider(),extension.getId()); 3678 3679 Element extensions=_getRootElement("extensions"); 3680 Element[] children = ConfigWebFactory.getChildren(extensions,"extension"); 3681 3682 // Update 3683 Element el; 3684 String provider,id; 3685 for(int i=0;i<children.length;i++) { 3686 el=children[i]; 3687 provider=el.getAttribute("provider"); 3688 id=el.getAttribute("id"); 3689 if(uid.equalsIgnoreCase(createUid(pc,provider, id))) { 3690 setExtensionAttrs(el,extension); 3691 return ; 3692 } 3693 } 3694 3695 // Insert 3696 el = doc.createElement("extension"); 3697 3698 el.setAttribute("provider",extension.getProvider()); 3699 el.setAttribute("id",extension.getId()); 3700 setExtensionAttrs(el,extension); 3701 extensions.appendChild(el); 3702 } 3703 3704 3705 private String createUid(PageContext pc,String provider, String id) throws PageException { 3706 if(Decision.isUUId(id)) { 3707 return Hash.invoke(pc.getConfig(),id,null,null, 1); 3708 } 3709 return Hash.invoke(pc.getConfig(),provider+id,null,null, 1); 3710 } 3711 3712 3713 private void setExtensionAttrs(Element el, Extension extension) { 3714 el.setAttribute("version",extension.getVersion()); 3715 3716 el.setAttribute("config",extension.getStrConfig()); 3717 //el.setAttribute("config",new ScriptConverter().serialize(extension.getConfig())); 3718 3719 el.setAttribute("category",extension.getCategory()); 3720 el.setAttribute("description",extension.getDescription()); 3721 el.setAttribute("image",extension.getImage()); 3722 el.setAttribute("label",extension.getLabel()); 3723 el.setAttribute("name",extension.getName()); 3724 3725 el.setAttribute("author",extension.getAuthor()); 3726 el.setAttribute("type",extension.getType()); 3727 el.setAttribute("codename",extension.getCodename()); 3728 el.setAttribute("video",extension.getVideo()); 3729 el.setAttribute("support",extension.getSupport()); 3730 el.setAttribute("documentation",extension.getDocumentation()); 3731 el.setAttribute("forum",extension.getForum()); 3732 el.setAttribute("mailinglist",extension.getMailinglist()); 3733 el.setAttribute("network",extension.getNetwork()); 3734 el.setAttribute("created",Caster.toString(extension.getCreated(),null)); 3735 3736 3737 } 3738 3739 3740 public void resetORMSetting() throws SecurityException { 3741 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_ORM); 3742 3743 if(!hasAccess) 3744 throw new SecurityException("no access to update ORM Settings"); 3745 3746 3747 3748 Element orm=_getRootElement("orm"); 3749 orm.getParentNode().removeChild(orm); 3750 } 3751 3752 3753 public void updateORMSetting(ORMConfiguration oc) throws SecurityException { 3754 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_ORM); 3755 3756 if(!hasAccess) 3757 throw new SecurityException("no access to update ORM Settings"); 3758 3759 3760 3761 Element orm=_getRootElement("orm"); 3762 orm.setAttribute("autogenmap",Caster.toString(oc.autogenmap(),"true")); 3763 orm.setAttribute("event-handler",Caster.toString(oc.eventHandler(),"")); 3764 orm.setAttribute("event-handling",Caster.toString(oc.eventHandling(),"false")); 3765 orm.setAttribute("naming-strategy",Caster.toString(oc.namingStrategy(),"")); 3766 orm.setAttribute("flush-at-request-end",Caster.toString(oc.flushAtRequestEnd(),"true")); 3767 orm.setAttribute("cache-provider",Caster.toString(oc.getCacheProvider(),"")); 3768 orm.setAttribute("cache-config",Caster.toString(oc.getCacheConfig(),"true")); 3769 orm.setAttribute("catalog",Caster.toString(oc.getCatalog(),"")); 3770 orm.setAttribute("db-create",ORMConfigurationImpl.dbCreateAsString(oc.getDbCreate())); 3771 orm.setAttribute("dialect",Caster.toString(oc.getDialect(),"")); 3772 orm.setAttribute("schema",Caster.toString(oc.getSchema(),"")); 3773 orm.setAttribute("log-sql",Caster.toString(oc.logSQL(),"false")); 3774 orm.setAttribute("save-mapping",Caster.toString(oc.saveMapping(),"false")); 3775 orm.setAttribute("secondary-cache-enable",Caster.toString(oc.secondaryCacheEnabled(),"false")); 3776 orm.setAttribute("use-db-for-mapping",Caster.toString(oc.useDBForMapping(),"true")); 3777 orm.setAttribute("orm-config",Caster.toString(oc.getOrmConfig(),"")); 3778 orm.setAttribute("sql-script",Caster.toString(oc.getSqlScript(),"true")); 3779 3780 if(oc.isDefaultCfcLocation()) { 3781 orm.removeAttribute("cfc-location"); 3782 } 3783 else { 3784 Resource[] locations = oc.getCfcLocations(); 3785 StringBuilder sb=new StringBuilder(); 3786 for(int i=0;i<locations.length;i++) { 3787 if(i!=0)sb.append(","); 3788 sb.append(locations[i].getAbsolutePath()); 3789 } 3790 orm.setAttribute("cfc-location",sb.toString()); 3791 } 3792 3793 3794 orm.setAttribute("sql-script",Caster.toString(oc.getSqlScript(),"true")); 3795 3796 } 3797 3798 3799 public void removeExtension(String provider, String id) throws SecurityException { 3800 checkWriteAccess(); 3801 3802 Element extensions=_getRootElement("extensions"); 3803 Element[] children = ConfigWebFactory.getChildren(extensions,"extension"); 3804 Element child; 3805 String _provider, _id; 3806 for(int i=0;i<children.length;i++) { 3807 child=children[i]; 3808 _provider=child.getAttribute("provider"); 3809 _id=child.getAttribute("id"); 3810 if(_provider!=null && _provider.equalsIgnoreCase(provider) && _id!=null && _id.equalsIgnoreCase(id)) { 3811 extensions.removeChild(child); 3812 } 3813 } 3814 } 3815 3816 public void verifyExtensionProvider(String strUrl) throws PageException { 3817 HTTPResponse method=null; 3818 try { 3819 URL url = HTTPUtil.toURL(strUrl+"?wsdl",true); 3820 method = HTTPEngine.get(url, null, null, 2000,HTTPEngine.MAX_REDIRECT, null, null, null, null); 3821 } 3822 catch (MalformedURLException e) { 3823 throw new ApplicationException("url defintion ["+strUrl+"] is invalid"); 3824 } 3825 catch (IOException e) { 3826 throw new ApplicationException("can't invoke ["+strUrl+"]",e.getMessage()); 3827 } 3828 3829 if(method.getStatusCode()!=200){int code=method.getStatusCode(); 3830 String text=method.getStatusText(); 3831 String msg=code+" "+text; 3832 throw new HTTPException(msg,null,code,text,method.getURL()); 3833 } 3834 //Object o = 3835 CreateObject.doWebService(null, strUrl+"?wsdl"); 3836 3837 } 3838 3839 3840 public void updateTLD(Resource resTld) throws IOException { 3841 updateLD(config.getTldFile(),resTld); 3842 } 3843 public void updateFLD(Resource resFld) throws IOException { 3844 updateLD(config.getFldFile(),resFld); 3845 } 3846 3847 private void updateLD(Resource dir,Resource res) throws IOException { 3848 if(!dir.exists())dir.createDirectory(true); 3849 3850 Resource file = dir.getRealResource(res.getName()); 3851 if(file.length()!=res.length()){ 3852 ResourceUtil.copy(res, file); 3853 } 3854 } 3855 3856 static void updateTLD(Config config,InputStream is,String name, boolean closeStream) throws IOException { 3857 updateLD(config.getTldFile(),is,name,closeStream); 3858 } 3859 static void updateFLD(Config config,InputStream is,String name, boolean closeStream) throws IOException { 3860 updateLD(config.getFldFile(),is,name,closeStream); 3861 } 3862 3863 private static void updateLD(Resource dir,InputStream is,String name, boolean closeStream) throws IOException { 3864 if(!dir.exists())dir.createDirectory(true); 3865 Resource file = dir.getRealResource(name); 3866 IOUtil.copy(is, file.getOutputStream(), closeStream, true); 3867 } 3868 3869 public void removeTLD(String name) throws IOException { 3870 removeLD(config.getTldFile(),name); 3871 } 3872 3873 public void removeTLDs(String[] names) throws IOException { 3874 if(ArrayUtil.isEmpty(names)) return; 3875 Resource file = config.getTldFile(); 3876 for(int i=0;i<names.length;i++){ 3877 removeLD(file,names[i]); 3878 } 3879 } 3880 3881 public void removeFLDs(String[] names) throws IOException { 3882 if(ArrayUtil.isEmpty(names)) return; 3883 Resource file = config.getFldFile(); 3884 for(int i=0;i<names.length;i++){ 3885 removeLD(file,names[i]); 3886 } 3887 } 3888 3889 public void removeFLD(String name) throws IOException { 3890 removeLD(config.getFldFile(),name); 3891 } 3892 3893 private void removeLD(Resource dir,String name) throws IOException { 3894 if(dir.isDirectory()){ 3895 Resource[] children = dir.listResources(new MyResourceNameFilter(name)); 3896 for(int i=0;i<children.length;i++){ 3897 children[i].remove(false); 3898 } 3899 } 3900 } 3901 3902 public void updateJar(Resource resJar) throws IOException { 3903 updateJar(config, resJar); 3904 } 3905 private static void updateJar(Config config, Resource resJar) throws IOException { 3906 Resource lib = config.getConfigDir().getRealResource("lib"); 3907 if(!lib.exists())lib.mkdir(); 3908 3909 Resource fileLib = lib.getRealResource(resJar.getName()); 3910 3911 if(fileLib.length()!=resJar.length()){ 3912 IOUtil.closeEL(config.getClassLoader()); 3913 ResourceUtil.copy(resJar, fileLib); 3914 ConfigWebFactory.reloadLib((ConfigImpl) config); 3915 } 3916 } 3917 3918 static void updateJar(Config config, InputStream is, String name,boolean closeStream) throws IOException { 3919 Resource lib = config.getConfigDir().getRealResource("lib"); 3920 if(!lib.exists())lib.mkdir(); 3921 3922 Resource fileLib = lib.getRealResource(name); 3923 3924 IOUtil.closeEL(config.getClassLoader()); 3925 IOUtil.copy(is, fileLib.getOutputStream(), closeStream, true); 3926 ConfigWebFactory.reloadLib((ConfigImpl) config); 3927 } 3928 3929 public void updateRemoteClientUsage(String code, String displayname) { 3930 Struct usage = config.getRemoteClientUsage(); 3931 usage.setEL(code, displayname); 3932 3933 Element extensions=_getRootElement("remote-clients"); 3934 extensions.setAttribute("usage", toStringURLStyle(usage)); 3935 3936 } 3937 3938 public void updateClusterClass(String classname) throws PageException { 3939 if(StringUtil.isEmpty(classname,true)) 3940 classname=ClusterNotSupported.class.getName(); 3941 3942 3943 Class clazz=null; 3944 try { 3945 clazz = ClassUtil.loadClass(config.getClassLoader(),classname); 3946 } catch (ClassException e) { 3947 throw Caster.toPageException(e); 3948 } 3949 if(!Reflector.isInstaneOf(clazz,Cluster.class) && !Reflector.isInstaneOf(clazz,ClusterRemote.class)) 3950 throw new ApplicationException("class ["+clazz.getName()+"] does not implement interface ["+Cluster.class.getName()+"] or ["+ClusterRemote.class.getName()+"]"); 3951 3952 3953 Element scope=_getRootElement("scope"); 3954 scope.setAttribute("cluster-class", clazz.getName()); 3955 ScopeContext.clearClusterScope(); 3956 } 3957 3958 3959 3960 public void updateVideoExecuterClass(String classname) throws PageException { 3961 classname=classname.trim(); 3962 3963 if(StringUtil.isEmpty(classname,true)) 3964 classname=VideoExecuterNotSupported.class.getName(); 3965 3966 Class clazz=null; 3967 try { 3968 clazz = ClassUtil.loadClass(config.getClassLoader(),classname); 3969 } catch (ClassException e) { 3970 throw Caster.toPageException(e); 3971 } 3972 if(!Reflector.isInstaneOf(clazz,VideoExecuter.class)) 3973 throw new ApplicationException("class ["+clazz.getName()+"] does not implement interface ["+VideoExecuter.class.getName()+"]"); 3974 3975 3976 Element app=_getRootElement("video"); 3977 app.setAttribute("video-executer-class", clazz.getName()); 3978 } 3979 public void updateAdminSyncClass(String classname) throws PageException { 3980 classname=classname.trim(); 3981 3982 if(StringUtil.isEmpty(classname,true)) 3983 classname=AdminSyncNotSupported.class.getName(); 3984 3985 Class clazz=null; 3986 try { 3987 clazz = ClassUtil.loadClass(config.getClassLoader(),classname); 3988 } catch (ClassException e) { 3989 throw Caster.toPageException(e); 3990 } 3991 if(!Reflector.isInstaneOf(clazz,AdminSync.class)) 3992 throw new ApplicationException("class ["+clazz.getName()+"] does not implement interface ["+AdminSync.class.getName()+"]"); 3993 3994 3995 Element app=_getRootElement("application"); 3996 app.setAttribute("admin-sync-class", clazz.getName()); 3997 } 3998 3999 4000 4001 public void removeRemoteClientUsage(String code) { 4002 Struct usage = config.getRemoteClientUsage(); 4003 usage.removeEL(KeyImpl.getInstance(code)); 4004 4005 Element extensions=_getRootElement("remote-clients"); 4006 extensions.setAttribute("usage", toStringURLStyle(usage)); 4007 4008 } 4009 4010 public void removeJar(String strNames) throws IOException { 4011 removeJar(ListUtil.listToStringArray(strNames, ',')); 4012 } 4013 public void removeJar(String[] names) throws IOException { 4014 if(ArrayUtil.isEmpty(names)) return; 4015 4016 4017 Resource lib = config.getConfigDir().getRealResource("lib"); 4018 boolean changed=false; 4019 if(lib.isDirectory()){ 4020 for(int n=0;n<names.length;n++){ 4021 Resource[] children = lib.listResources(new MyResourceNameFilter(names[n].trim())); 4022 for(int i=0;i<children.length;i++){ 4023 try { 4024 changed=true; 4025 IOUtil.closeEL(config.getClassLoader()); 4026 children[i].remove(false); 4027 } 4028 catch (IOException ioe) { 4029 if(children[i] instanceof File) 4030 ((File)children[i]).deleteOnExit(); 4031 else{ 4032 ConfigWebFactory.reloadLib(this.config); 4033 throw ioe; 4034 } 4035 } 4036 } 4037 } 4038 } 4039 if(changed){ 4040 ConfigWebFactory.reloadLib(this.config); 4041 //new ResourceClassLoader(lib.listResources(),config.getClass().getClassLoader()); 4042 } 4043 } 4044 4045 class MyResourceNameFilter implements ResourceNameFilter { 4046 private String name; 4047 public MyResourceNameFilter(String name){ 4048 this.name=name; 4049 } 4050 4051 @Override 4052 public boolean accept(Resource parent, String name) { 4053 return name.equals(this.name); 4054 } 4055 } 4056 4057 public void updateSerial(String serial) throws PageException { 4058 4059 checkWriteAccess(); 4060 if(!(config instanceof ConfigServer)) { 4061 throw new SecurityException("can't change serial number from this context, access is denied"); 4062 } 4063 4064 Element root=doc.getDocumentElement(); 4065 if(!StringUtil.isEmpty(serial)){ 4066 serial=serial.trim(); 4067 if(!new SerialNumber(serial).isValid(serial)) 4068 throw new SecurityException("serial number is invalid"); 4069 root.setAttribute("serial-number",serial); 4070 } 4071 else{ 4072 try{ 4073 root.removeAttribute("serial-number"); 4074 } 4075 catch(Throwable t){ 4076 ExceptionUtil.rethrowIfNecessary(t); 4077 } 4078 } 4079 try{ 4080 root.removeAttribute("serial"); 4081 } 4082 catch(Throwable t){ 4083 ExceptionUtil.rethrowIfNecessary(t); 4084 } 4085 } 4086 4087 4088 public boolean updateLabel(String hash, String label) { 4089 // check 4090 if(StringUtil.isEmpty(hash,true)) return false; 4091 if(StringUtil.isEmpty(label,true)) return false; 4092 4093 hash=hash.trim(); 4094 label=label.trim(); 4095 4096 Element labels=_getRootElement("labels"); 4097 4098 // Update 4099 Element[] children = ConfigWebFactory.getChildren(labels,"label"); 4100 for(int i=0;i<children.length;i++) { 4101 String h=children[i].getAttribute("id"); 4102 if(h!=null) { 4103 if(h.equals(hash)) { 4104 Element el=children[i]; 4105 if(label.equals(el.getAttribute("name"))) return false; 4106 el.setAttribute("name",label); 4107 return true; 4108 } 4109 } 4110 } 4111 4112 // Insert 4113 Element el=doc.createElement("label"); 4114 labels.appendChild(el); 4115 el.setAttribute("id",hash); 4116 el.setAttribute("name",label); 4117 4118 return true; 4119 } 4120 4121 4122 public void updateDebugSetting(int maxLogs) throws SecurityException { 4123 checkWriteAccess(); 4124 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DEBUGGING); 4125 if(!hasAccess) 4126 throw new SecurityException("no access to change debugging settings"); 4127 4128 4129 Element debugging=_getRootElement("debugging"); 4130 if(maxLogs==-1) 4131 debugging.removeAttribute("max-records-logged"); 4132 else 4133 debugging.setAttribute("max-records-logged", Caster.toString(maxLogs)); 4134 } 4135 4136 4137 public void updateDebugEntry(String type, String iprange,String label,String path,String fullname, Struct custom) throws SecurityException, IOException { 4138 checkWriteAccess(); 4139 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DEBUGGING); 4140 if(!hasAccess) 4141 throw new SecurityException("no access to change debugging settings"); 4142 4143 // leave this, this method throws a exception when ip range is not valid 4144 IPRange.getInstance(iprange); 4145 4146 String id=MD5.getDigestAsString(label.trim().toLowerCase()); 4147 type=type.trim(); 4148 iprange=iprange.trim(); 4149 label=label.trim(); 4150 4151 Element debugging=_getRootElement("debugging"); 4152 4153 // Update 4154 Element[] children = ConfigWebFactory.getChildren(debugging,"debug-entry"); 4155 Element el=null; 4156 for(int i=0;i<children.length;i++) { 4157 String _id=children[i].getAttribute("id"); 4158 if(_id!=null) { 4159 if(_id.equals(id)) { 4160 el=children[i]; 4161 break; 4162 } 4163 } 4164 } 4165 4166 // Insert 4167 if(el==null) { 4168 el=doc.createElement("debug-entry"); 4169 debugging.appendChild(el); 4170 el.setAttribute("id",id); 4171 } 4172 4173 4174 el.setAttribute("type",type); 4175 el.setAttribute("iprange",iprange); 4176 el.setAttribute("label",label); 4177 el.setAttribute("path",path); 4178 el.setAttribute("fullname",fullname); 4179 el.setAttribute("custom",toStringURLStyle(custom)); 4180 } 4181 4182 4183 4184 4185 public void removeDebugEntry(String id) throws SecurityException { 4186 checkWriteAccess(); 4187 boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DEBUGGING); 4188 if(!hasAccess) 4189 throw new SecurityException("no access to change debugging settings"); 4190 4191 4192 Element debugging=_getRootElement("debugging"); 4193 Element[] children = ConfigWebFactory.getChildren(debugging,"debug-entry"); 4194 String _id; 4195 if(children.length>0) { 4196 for(int i=0;i<children.length;i++) { 4197 Element el=children[i]; 4198 _id=el.getAttribute("id"); 4199 if(_id!=null && _id.equalsIgnoreCase(id)) { 4200 debugging.removeChild(children[i]); 4201 } 4202 } 4203 } 4204 } 4205 4206 4207 public void updateLoginSettings(boolean captcha, boolean rememberMe, int delay) { 4208 4209 Element login=_getRootElement("login"); 4210 login.setAttribute("captcha",Caster.toString(captcha)); 4211 login.setAttribute("rememberme",Caster.toString(rememberMe)); 4212 login.setAttribute("delay",Caster.toString(delay)); 4213 4214 } 4215 4216 4217 4218 4219 public void updateLogSettings(String name, Level level, String appenderClassName, Struct appenderArgs, String layoutClassName, Struct layoutArgs) throws PageException { 4220 checkWriteAccess(); 4221 // TODO 4222 //boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_GATEWAY); 4223 // if(!hasAccess) throw new SecurityException("no access to update gateway entry"); 4224 4225 // check parameters 4226 name=name.trim(); 4227 if(StringUtil.isEmpty(name)) 4228 throw new ApplicationException("name can't be a empty value"); 4229 4230 if(StringUtil.isEmpty(appenderClassName)) 4231 throw new ExpressionException("you must define appender class name"); 4232 if(StringUtil.isEmpty(layoutClassName)) 4233 throw new ExpressionException("you must define layout class name"); 4234 4235 try { 4236 ClassUtil.loadClass(appenderClassName); 4237 ClassUtil.loadClass(layoutClassName); 4238 4239 } 4240 catch (ClassException e) { 4241 throw Caster.toPageException(e); 4242 } 4243 4244 Element parent=_getRootElement("logging"); 4245 4246 // Update 4247 Element[] children = ConfigWebFactory.getChildren(parent,"logger"); 4248 Element el=null; 4249 for(int i=0;i<children.length;i++) { 4250 String n=children[i].getAttribute("name"); 4251 if(name.equalsIgnoreCase(n)) { 4252 el=children[i]; 4253 break; 4254 } 4255 4256 } 4257 // Insert 4258 if(el==null) { 4259 el=doc.createElement("logger"); 4260 parent.appendChild(el); 4261 el.setAttribute("name",name); 4262 } 4263 4264 // appender 4265 if(appenderClassName.equals(ConsoleAppender.class.getName())) appenderClassName="console"; 4266 if(appenderClassName.equals(RollingResourceAppender.class.getName())) appenderClassName="resource"; 4267 // layout 4268 if(layoutClassName.equals(PatternLayout.class.getName())) layoutClassName="pattern"; 4269 if(layoutClassName.equals(ClassicLayout.class.getName())) layoutClassName="classic"; 4270 if(layoutClassName.equals(HTMLLayout.class.getName())) layoutClassName="html"; 4271 if(layoutClassName.equals(XMLLayout.class.getName())) layoutClassName="xml"; 4272 4273 el.setAttribute("level",level.toString()); 4274 el.setAttribute("appender",appenderClassName); 4275 el.setAttribute("appender-arguments",toStringCSSStyle(appenderArgs)); 4276 el.setAttribute("layout",layoutClassName); 4277 el.setAttribute("layout-arguments",toStringCSSStyle(layoutArgs)); 4278 } 4279 4280 4281 public void updateCompilerSettings(Boolean dotNotationUpperCase, Boolean suppressWSBeforeArg, Boolean nullSupport) throws PageException { 4282 4283 Element element = _getRootElement("compiler"); 4284 4285 checkWriteAccess(); 4286 if(dotNotationUpperCase==null){ 4287 if(element.hasAttribute("dot-notation-upper-case")) 4288 element.removeAttribute("dot-notation-upper-case"); 4289 } 4290 else { 4291 element.setAttribute("dot-notation-upper-case", Caster.toString(dotNotationUpperCase)); 4292 } 4293 4294 4295 // remove old settings 4296 if(element.hasAttribute("supress-ws-before-arg")) 4297 element.removeAttribute("supress-ws-before-arg"); 4298 4299 if(suppressWSBeforeArg==null){ 4300 if(element.hasAttribute("suppress-ws-before-arg")) 4301 element.removeAttribute("suppress-ws-before-arg"); 4302 } 4303 else { 4304 element.setAttribute("suppress-ws-before-arg", Caster.toString(suppressWSBeforeArg)); 4305 } 4306 4307 // full null support 4308 if(nullSupport==null){ 4309 if(element.hasAttribute("full-null-support")) 4310 element.removeAttribute("full-null-support"); 4311 } 4312 else { 4313 element.setAttribute("full-null-support", Caster.toString(nullSupport)); 4314 } 4315 4316 4317 4318 } 4319 4320 /*private void updatePlugin(Resource src) throws PageException, IOException { 4321 Resource srcDir = ResourceUtil.toResourceExisting(config, "zip://"+src.getAbsolutePath()); 4322 if(!doAccept(srcDir)) 4323 throw new ApplicationException("plugin ["+src+"] is invalid, missing one of the following files [Action.cfc,language.xml] in root, existing files are ["+lucee.runtime.type.util.ListUtil.arrayToList(srcDir.list(), ", ")+"]"); 4324 4325 String name=ResourceUtil.getName(src.getName()); 4326 4327 Resource dir = config.getConfigDir().getRealResource("context/admin/plugin"); 4328 Resource trgDir = dir.getRealResource(name); 4329 if(trgDir.exists()){ 4330 trgDir.remove(true); 4331 } 4332 4333 ResourceUtil.copyRecursive(srcDir, trgDir); 4334 store(); 4335 } 4336 public static boolean doAccept(Resource res) { 4337 return res.isDirectory() && res.getRealResource("/Action.cfc").isFile() && res.getRealResource("/language.xml").isFile(); 4338 }*/ 4339 4340 4341 static Resource[] updateContext(ConfigImpl config,InputStream is,String relpath, boolean closeStream) throws PageException, IOException, SAXException { 4342 //ConfigWebAdmin admin = new ConfigWebAdmin(config, null); 4343 List<Resource> filesDeployed=new ArrayList<Resource>(); 4344 ConfigWebAdmin._updateContext(config, is, relpath, closeStream, filesDeployed); 4345 return filesDeployed.toArray(new Resource[filesDeployed.size()]); 4346 } 4347 4348 private static void _updateContext(Config config,InputStream is,String relpath, boolean closeStream,List<Resource> filesDeployed) throws PageException, IOException, SAXException { 4349 if(config instanceof ConfigServer) { 4350 ConfigWeb[] webs = ((ConfigServer)config).getConfigWebs(); 4351 if(webs.length==0) return; 4352 if(webs.length==1) { 4353 _updateContext(webs[0], is,relpath,closeStream,filesDeployed); 4354 return; 4355 } 4356 try{ 4357 byte[] barr = IOUtil.toBytes(is); 4358 for(int i=0;i<webs.length;i++){ 4359 _updateContext(webs[i], new ByteArrayInputStream(barr),relpath,true,filesDeployed); 4360 } 4361 } 4362 finally { 4363 if(closeStream)IOUtil.closeEL(is); 4364 } 4365 return ; 4366 } 4367 4368 // ConfigWeb 4369 Resource trg = config.getConfigDir().getRealResource("context").getRealResource(relpath); 4370 if(trg.exists()) trg.remove(true); 4371 Resource p = trg.getParentResource(); 4372 if(!p.isDirectory()) p.createDirectory(true); 4373 IOUtil.copy(is, trg.getOutputStream(false), closeStream,true); 4374 filesDeployed.add(trg); 4375 _store((ConfigImpl)config); 4376 } 4377 public boolean removeContext(Config config, boolean store,String... relpathes) throws PageException, IOException, SAXException { 4378 if(ArrayUtil.isEmpty(relpathes)) return false; 4379 boolean force=false; 4380 for(int i=0;i<relpathes.length;i++){ 4381 if(_removeContext(config, relpathes[i],store)) 4382 force=true; 4383 } 4384 return force; 4385 } 4386 4387 private boolean _removeContext(Config config,String relpath, boolean _store) throws PageException, IOException, SAXException { 4388 4389 if(config instanceof ConfigServer) { 4390 ConfigServer cs = ((ConfigServer)config); 4391 4392 // remove files from deploy folder 4393 Resource deploy = cs.getConfigDir().getRealResource("web-context-deployment"); 4394 Resource trg = deploy.getRealResource(relpath); 4395 4396 if(trg.exists()) { 4397 trg.remove(true); 4398 ResourceUtil.removeEmptyFolders(deploy,null); 4399 } 4400 4401 // remove files from lucee web context 4402 boolean store=false; 4403 ConfigWeb[] webs = cs.getConfigWebs(); 4404 for(int i=0;i<webs.length;i++){ 4405 if(_removeContext(webs[i], relpath,_store)) { 4406 store=true; 4407 } 4408 } 4409 return store; 4410 } 4411 4412 // ConfigWeb 4413 Resource context = config.getConfigDir().getRealResource("context"); 4414 Resource trg = context.getRealResource(relpath); 4415 if(trg.exists()) { 4416 trg.remove(true); 4417 if(_store) ConfigWebAdmin._store((ConfigImpl) config); 4418 ResourceUtil.removeEmptyFolders(context,null); 4419 return true; 4420 } 4421 return false; 4422 } 4423 4424 static Resource[] updateApplication(ConfigImpl config,InputStream is,String relpath, boolean closeStream) throws PageException, IOException, SAXException { 4425 ConfigWebAdmin admin = new ConfigWebAdmin(config, null); 4426 List<Resource> filesDeployed=new ArrayList<Resource>(); 4427 admin._updateApplication(config, is, relpath, closeStream, filesDeployed); 4428 return filesDeployed.toArray(new Resource[filesDeployed.size()]); 4429 } 4430 4431 private void _updateApplication(Config config,InputStream is,String relpath, boolean closeStream,List<Resource> filesDeployed) throws PageException, IOException, SAXException { 4432 if(config instanceof ConfigServer) { 4433 ConfigWeb[] webs = ((ConfigServer)config).getConfigWebs(); 4434 if(webs.length==0) return; 4435 if(webs.length==1) { 4436 _updateApplication(webs[0], is,relpath,closeStream,filesDeployed); 4437 return; 4438 } 4439 try{ 4440 byte[] barr = IOUtil.toBytes(is); 4441 for(int i=0;i<webs.length;i++){ 4442 _updateApplication(webs[i], new ByteArrayInputStream(barr),relpath,true,filesDeployed); 4443 } 4444 } 4445 finally { 4446 if(closeStream)IOUtil.closeEL(is); 4447 } 4448 return ; 4449 } 4450 4451 // ConfigWeb 4452 4453 4454 Resource trg = config.getRootDirectory().getRealResource(relpath); 4455 if(trg.exists()) trg.remove(true); 4456 Resource p = trg.getParentResource(); 4457 if(!p.isDirectory()) p.createDirectory(true); 4458 IOUtil.copy(is, trg.getOutputStream(false), closeStream,true); 4459 filesDeployed.add(trg); 4460 //_store((ConfigImpl)config); 4461 } 4462 4463 private void removeApplications(Config config,String[] relpathes) throws PageException, IOException, SAXException { 4464 if(ArrayUtil.isEmpty(relpathes)) return; 4465 for(int i=0;i<relpathes.length;i++){ 4466 removeApplication(config, relpathes[i]); 4467 } 4468 } 4469 4470 private void removeApplication(Config config,String relpath) throws PageException, IOException, SAXException { 4471 if(config instanceof ConfigServer) { 4472 ConfigWeb[] webs = ((ConfigServer)config).getConfigWebs(); 4473 for(int i=0;i<webs.length;i++){ 4474 removeApplication(webs[i], relpath); 4475 } 4476 4477 return ; 4478 } 4479 4480 // ConfigWeb 4481 Resource trg = config.getRootDirectory().getRealResource(relpath); 4482 if(trg.exists()) trg.remove(true); 4483 } 4484 4485 public static void removeRHExtension(ConfigImpl config,String extensionID) throws SAXException, IOException, PageException { 4486 ConfigWebAdmin admin = new ConfigWebAdmin(config, null); 4487 boolean storeChildren = admin._removeExtension(config, extensionID); 4488 admin._store(); 4489 4490 if(storeChildren && config instanceof ConfigServer) { 4491 ConfigServer cs = (ConfigServer)config; 4492 ConfigWeb[] webs = cs.getConfigWebs(); 4493 for(int i=0;i<webs.length;i++) { 4494 admin._store((ConfigImpl)webs[i]); 4495 } 4496 } 4497 } 4498 4499 4500 public boolean _removeExtension(ConfigImpl config,String extensionID) throws IOException, PageException, SAXException { 4501 if(!Decision.isUUId(extensionID)) throw new IOException("id ["+extensionID+"] is invalid, it has to be a UUID"); 4502 4503 Element extensions=_getRootElement("extensions"); 4504 Element[] children = ConfigWebFactory.getChildren(extensions,"rhextension");// LuceeHandledExtensions 4505 4506 // Update 4507 Element el; 4508 String id; 4509 String[] arr; 4510 boolean storeChildren=false; 4511 for(int i=0;i<children.length;i++) { 4512 el=children[i]; 4513 id=el.getAttribute("id"); 4514 if(extensionID.equalsIgnoreCase(id)) { 4515 4516 // jars 4517 arr=_removeExtensionCheckOtherUsage(children,el,"jars"); 4518 removeJar(arr); 4519 // flds 4520 arr=_removeExtensionCheckOtherUsage(children,el,"flds"); 4521 removeFLDs(arr); 4522 // tlds 4523 arr=_removeExtensionCheckOtherUsage(children,el,"tlds"); 4524 removeTLDs(arr); 4525 // contexts 4526 arr=_removeExtensionCheckOtherUsage(children,el,"contexts"); 4527 storeChildren=removeContext(config,false, arr); 4528 // applications 4529 arr=_removeExtensionCheckOtherUsage(children,el,"applications"); 4530 removeApplications(config, arr); 4531 4532 4533 4534 extensions.removeChild(el); 4535 return storeChildren; 4536 } 4537 } 4538 return false; 4539 } 4540 4541 private String[] _removeExtensionCheckOtherUsage(Element[] children, Element curr,String type) { 4542 String currVal=curr.getAttribute(type); 4543 if(StringUtil.isEmpty(currVal)) return null; 4544 4545 String otherVal; 4546 Element other; 4547 Set<String> currSet = ListUtil.toSet(ListUtil.trimItems(ListUtil.listToStringArray(currVal, ','))); 4548 String[] otherArr; 4549 for(int i=0;i<children.length;i++) { 4550 other=children[i]; 4551 if(other==curr) continue; 4552 otherVal=other.getAttribute(type); 4553 if(StringUtil.isEmpty(otherVal)) continue; 4554 otherArr=ListUtil.trimItems(ListUtil.listToStringArray(otherVal, ',')); 4555 for(int y=0;y<otherArr.length;y++) { 4556 currSet.remove(otherArr[y]); 4557 } 4558 } 4559 return currSet.toArray(new String[currSet.size()]); 4560 } 4561 4562 4563 public static void updateRHExtension(ConfigImpl config,RHExtension rhExtension) throws SAXException, IOException, PageException { 4564 ConfigWebAdmin admin = new ConfigWebAdmin(config, null); 4565 admin._updateExtension(config, rhExtension); 4566 admin._store(); 4567 } 4568 4569 4570 public void _updateExtension(ConfigImpl config,RHExtension ext) throws IOException { 4571 if(!Decision.isUUId(ext.getId())) throw new IOException("id ["+ext.getId()+"] is invalid, it has to be a UUID"); 4572 4573 Element extensions=_getRootElement("extensions"); 4574 Element[] children = ConfigWebFactory.getChildren(extensions,"rhextension");// LuceeHandledExtensions 4575 4576 // Update 4577 Element el; 4578 String provider,id; 4579 for(int i=0;i<children.length;i++) { 4580 el=children[i]; 4581 provider=el.getAttribute("provider"); 4582 id=el.getAttribute("id"); 4583 if(ext.getId().equalsIgnoreCase(id)) { 4584 setExtensionAttrs(el,ext); 4585 return ; 4586 } 4587 } 4588 4589 // Insert 4590 el = doc.createElement("rhextension"); 4591 setExtensionAttrs(el,ext); 4592 extensions.appendChild(el); 4593 4594 } 4595 4596 4597 private void setExtensionAttrs(Element el, RHExtension ext) { 4598 setAttr(el,"id", ext.getId()); 4599 setAttr(el,"name", ext.getName()); 4600 setAttr(el,"version", ext.getVersion()); 4601 setAttr(el,"jars",ListUtil.arrayToList(ext.getJars(), ",")); 4602 setAttr(el,"flds",ListUtil.arrayToList(ext.getFlds(), ",")); 4603 setAttr(el,"tlds",ListUtil.arrayToList(ext.getTlds(), ",")); 4604 setAttr(el,"contexts",ListUtil.arrayToList(ext.getContexts(), ",")); 4605 setAttr(el,"applications",ListUtil.arrayToList(ext.getApplications(), ",")); 4606 } 4607 4608 4609 private void setAttr(Element el, String name, String value) { 4610 if(value==null) value=""; 4611 el.setAttribute(name, value); 4612 } 4613 4614 4615 public void updateAuthKey(String key) throws PageException { 4616 checkWriteAccess(); 4617 key=key.trim(); 4618 4619 // merge new key and existing 4620 ConfigServerImpl cs=(ConfigServerImpl) config; 4621 String[] keys = cs.getAuthenticationKeys(); 4622 Set<String> set=new HashSet<String>(); 4623 for(int i=0;i<keys.length;i++){ 4624 set.add(keys[i]); 4625 } 4626 set.add(key); 4627 4628 4629 Element root=doc.getDocumentElement(); 4630 root.setAttribute("auth-keys",authKeysAsList(set)); 4631 4632 4633 } 4634 4635 public void removeAuthKeys(String key) throws PageException { 4636 checkWriteAccess(); 4637 key=key.trim(); 4638 4639 // remove key 4640 ConfigServerImpl cs=(ConfigServerImpl) config; 4641 String[] keys = cs.getAuthenticationKeys(); 4642 Set<String> set=new HashSet<String>(); 4643 for(int i=0;i<keys.length;i++){ 4644 if(!key.equals(keys[i]))set.add(keys[i]); 4645 } 4646 4647 Element root=doc.getDocumentElement(); 4648 root.setAttribute("auth-keys",authKeysAsList(set)); 4649 } 4650 4651 public void updateAPIKey(String key) throws SecurityException, ApplicationException { 4652 checkWriteAccess(); 4653 key=key.trim(); 4654 if(!Decision.isGUId(key)) 4655 throw new ApplicationException("passed API Key ["+key+"] is not valid"); 4656 Element root=doc.getDocumentElement(); 4657 root.setAttribute("api-key",key); 4658 4659 } 4660 4661 public void removeAPIKey() throws PageException { 4662 checkWriteAccess(); 4663 Element root=doc.getDocumentElement(); 4664 if(root.hasAttribute("api-key")) 4665 root.removeAttribute("api-key"); 4666 } 4667 4668 private String authKeysAsList(Set<String> set) throws PageException { 4669 StringBuilder sb=new StringBuilder(); 4670 Iterator<String> it = set.iterator(); 4671 String key; 4672 while(it.hasNext()){ 4673 key=it.next().trim(); 4674 if(sb.length()>0)sb.append(','); 4675 try { 4676 sb.append(URLEncoder.encode(key, "UTF-8")); 4677 } 4678 catch (UnsupportedEncodingException e) { 4679 throw Caster.toPageException(e); 4680 } 4681 } 4682 return sb.toString(); 4683 } 4684}