001/* 002 Licensed to the Apache Software Foundation (ASF) under one 003 or more contributor license agreements. See the NOTICE file 004 distributed with this work for additional information 005 regarding copyright ownership. The ASF licenses this file 006 to you under the Apache License, Version 2.0 (the 007 "License"); you may not use this file except in compliance 008 with the License. You may obtain a copy of the License at 009 010 http://www.apache.org/licenses/LICENSE-2.0 011 012 Unless required by applicable law or agreed to in writing, 013 software distributed under the License is distributed on an 014 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 KIND, either express or implied. See the License for the 016 specific language governing permissions and limitations 017 under the License. 018 */ 019package org.apache.wiki; 020 021import java.security.Permission; 022import java.security.Principal; 023import java.util.HashMap; 024import java.util.PropertyPermission; 025 026import javax.servlet.http.HttpServletRequest; 027import javax.servlet.http.HttpSession; 028import javax.servlet.jsp.PageContext; 029 030import org.apache.log4j.Logger; 031import org.apache.wiki.auth.NoSuchPrincipalException; 032import org.apache.wiki.auth.UserManager; 033import org.apache.wiki.auth.WikiPrincipal; 034import org.apache.wiki.auth.permissions.AllPermission; 035import org.apache.wiki.auth.user.UserDatabase; 036import org.apache.wiki.tags.WikiTagBase; 037import org.apache.wiki.ui.Command; 038import org.apache.wiki.ui.CommandResolver; 039import org.apache.wiki.ui.GroupCommand; 040import org.apache.wiki.ui.Installer; 041import org.apache.wiki.ui.PageCommand; 042import org.apache.wiki.ui.WikiCommand; 043import org.apache.wiki.util.TextUtil; 044 045/** 046 * <p>Provides state information throughout the processing of a page. A 047 * WikiContext is born when the JSP pages that are the main entry 048 * points, are invoked. The JSPWiki engine creates the new 049 * WikiContext, which basically holds information about the page, the 050 * handling engine, and in which context (view, edit, etc) the 051 * call was done.</p> 052 * <p>A WikiContext also provides request-specific variables, which can 053 * be used to communicate between plugins on the same page, or 054 * between different instances of the same plugin. A WikiContext 055 * variable is valid until the processing of the page has ended. For 056 * an example, please see the Counter plugin.</p> 057 * <p>When a WikiContext is created, it automatically associates a 058 * {@link WikiSession} object with the user's HttpSession. The 059 * WikiSession contains information about the user's authentication 060 * status, and is consulted by {@link #getCurrentUser()}. 061 * object</p> 062 * <p>Do not cache the page object that you get from the WikiContext; always 063 * use getPage()!</p> 064 * 065 * @see org.apache.wiki.plugin.Counter 066 * 067 */ 068public class WikiContext 069 implements Cloneable, Command 070{ 071 private Command m_command = null; 072 073 private WikiPage m_page; 074 private WikiPage m_realPage; 075 private WikiEngine m_engine; 076 private String m_template = "default"; 077 078 private HashMap<String,Object> m_variableMap = new HashMap<>(); 079 080 /** Stores the HttpServletRequest. May be null, if the request did not come from a servlet. */ 081 protected HttpServletRequest m_request = null; 082 083 private WikiSession m_session = null; 084 085 /** User is administering JSPWiki (Install, SecurityConfig). */ 086 public static final String INSTALL = WikiCommand.INSTALL.getRequestContext(); 087 088 /** The VIEW context - the user just wants to view the page contents. */ 089 public static final String VIEW = PageCommand.VIEW.getRequestContext(); 090 091 /** User wants to view or administer workflows. */ 092 public static final String WORKFLOW = WikiCommand.WORKFLOW.getRequestContext(); 093 094 /** The EDIT context - the user is editing the page. */ 095 public static final String EDIT = PageCommand.EDIT.getRequestContext(); 096 097 /** User is preparing for a login/authentication. */ 098 public static final String LOGIN = WikiCommand.LOGIN.getRequestContext(); 099 100 /** User is preparing to log out. */ 101 public static final String LOGOUT = WikiCommand.LOGOUT.getRequestContext(); 102 103 /** JSPWiki wants to display a message. */ 104 public static final String MESSAGE = WikiCommand.MESSAGE.getRequestContext(); 105 106 /** User is viewing a DIFF between the two versions of the page. */ 107 public static final String DIFF = PageCommand.DIFF.getRequestContext(); 108 109 /** User is viewing page history. */ 110 public static final String INFO = PageCommand.INFO.getRequestContext(); 111 112 /** User is previewing the changes he just made. */ 113 public static final String PREVIEW = PageCommand.PREVIEW.getRequestContext(); 114 115 /** User has an internal conflict, and does quite not know what to 116 do. Please provide some counseling. */ 117 public static final String CONFLICT = PageCommand.CONFLICT.getRequestContext(); 118 119 /** An error has been encountered and the user needs to be informed. */ 120 public static final String ERROR = WikiCommand.ERROR.getRequestContext(); 121 122 /** User is uploading something. */ 123 public static final String UPLOAD = PageCommand.UPLOAD.getRequestContext(); 124 125 /** User is commenting something. */ 126 public static final String COMMENT = PageCommand.COMMENT.getRequestContext(); 127 128 /** User is searching for content. */ 129 public static final String FIND = WikiCommand.FIND.getRequestContext(); 130 131 /** User wishes to create a new group */ 132 public static final String CREATE_GROUP = WikiCommand.CREATE_GROUP.getRequestContext(); 133 134 /** User is deleting an existing group. */ 135 public static final String DELETE_GROUP = GroupCommand.DELETE_GROUP.getRequestContext(); 136 137 /** User is editing an existing group. */ 138 public static final String EDIT_GROUP = GroupCommand.EDIT_GROUP.getRequestContext(); 139 140 /** User is viewing an existing group */ 141 public static final String VIEW_GROUP = GroupCommand.VIEW_GROUP.getRequestContext(); 142 143 /** User is editing preferences */ 144 public static final String PREFS = WikiCommand.PREFS.getRequestContext(); 145 146 /** User is renaming a page. */ 147 public static final String RENAME = PageCommand.RENAME.getRequestContext(); 148 149 /** User is deleting a page or an attachment. */ 150 public static final String DELETE = PageCommand.DELETE.getRequestContext(); 151 152 /** User is downloading an attachment. */ 153 public static final String ATTACH = PageCommand.ATTACH.getRequestContext(); 154 155 /** RSS feed is being generated. */ 156 public static final String RSS = PageCommand.RSS.getRequestContext(); 157 158 /** This is not a JSPWiki context, use it to access static files. */ 159 public static final String NONE = PageCommand.NONE.getRequestContext(); 160 161 /** Same as NONE; this is just a clarification. */ 162 public static final String OTHER = PageCommand.OTHER.getRequestContext(); 163 164 /** User is doing administrative things. */ 165 public static final String ADMIN = WikiCommand.ADMIN.getRequestContext(); 166 167 private static final Logger log = Logger.getLogger( WikiContext.class ); 168 169 private static final Permission DUMMY_PERMISSION = new PropertyPermission( "os.name", "read" ); 170 171 /** 172 * Create a new WikiContext for the given WikiPage. Delegates to 173 * {@link #WikiContext(WikiEngine, HttpServletRequest, WikiPage)}. 174 * @param engine The WikiEngine that is handling the request. 175 * @param page The WikiPage. If you want to create a 176 * WikiContext for an older version of a page, you must use this 177 * constructor. 178 */ 179 public WikiContext( WikiEngine engine, WikiPage page ) 180 { 181 this( engine, null, findCommand( engine, null, page ) ); 182 } 183 184 /** 185 * <p> 186 * Creates a new WikiContext for the given WikiEngine, Command and 187 * HttpServletRequest. 188 * </p> 189 * <p> 190 * This constructor will also look up the HttpSession associated with the 191 * request, and determine if a WikiSession object is present. If not, a new 192 * one is created. 193 * </p> 194 * @param engine The WikiEngine that is handling the request 195 * @param request The HttpServletRequest that should be associated with this 196 * context. This parameter may be <code>null</code>. 197 * @param command the command 198 * @throws IllegalArgumentException if <code>engine</code> or 199 * <code>command</code> are <code>null</code> 200 */ 201 public WikiContext( WikiEngine engine, HttpServletRequest request, Command command ) 202 throws IllegalArgumentException 203 { 204 super(); 205 if ( engine == null || command == null ) 206 { 207 throw new IllegalArgumentException( "Parameter engine and command must not be null." ); 208 } 209 210 m_engine = engine; 211 m_request = request; 212 m_session = WikiSession.getWikiSession( engine, request ); 213 m_command = command; 214 215 // If PageCommand, get the WikiPage 216 if( command instanceof PageCommand ) 217 { 218 m_page = (WikiPage)((PageCommand)command).getTarget(); 219 } 220 221 // If page not supplied, default to front page to avoid NPEs 222 if( m_page == null ) 223 { 224 m_page = m_engine.getPage( m_engine.getFrontPage() ); 225 226 // Front page does not exist? 227 if( m_page == null ) 228 { 229 m_page = new WikiPage( m_engine, m_engine.getFrontPage() ); 230 } 231 } 232 233 m_realPage = m_page; 234 235 // Special case: retarget any empty 'view' PageCommands to the front page 236 if ( PageCommand.VIEW.equals( command ) && command.getTarget() == null ) 237 { 238 m_command = command.targetedCommand( m_page ); 239 } 240 241 // Debugging... 242 if( log.isDebugEnabled() ) 243 { 244 HttpSession session = ( request == null ) ? null : request.getSession( false ); 245 String sid = ( session == null ) ? "(null)" : session.getId(); 246 log.debug( "Creating WikiContext for session ID=" + sid + "; target=" + getName() ); 247 } 248 249 // Figure out what template to use 250 setDefaultTemplate( request ); 251 } 252 253 /** 254 * Creates a new WikiContext for the given WikiEngine, WikiPage and 255 * HttpServletRequest. This method simply looks up the appropriate Command 256 * using {@link #findCommand(WikiEngine, HttpServletRequest, WikiPage)} and 257 * delegates to 258 * {@link #WikiContext(WikiEngine, HttpServletRequest, Command)}. 259 * @param engine The WikiEngine that is handling the request 260 * @param request The HttpServletRequest that should be associated with this 261 * context. This parameter may be <code>null</code>. 262 * @param page The WikiPage. If you want to create a WikiContext for an 263 * older version of a page, you must supply this parameter 264 */ 265 public WikiContext(WikiEngine engine, HttpServletRequest request, WikiPage page) 266 { 267 this( engine, request, findCommand( engine, request, page ) ); 268 } 269 270 /** 271 * {@inheritDoc} 272 * @see org.apache.wiki.ui.Command#getContentTemplate() 273 */ 274 @Override 275 public String getContentTemplate() 276 { 277 return m_command.getContentTemplate(); 278 } 279 280 /** 281 * {@inheritDoc} 282 * @see org.apache.wiki.ui.Command#getJSP() 283 */ 284 @Override 285 public String getJSP() 286 { 287 return m_command.getContentTemplate(); 288 } 289 290 /** 291 * Sets a reference to the real page whose content is currently being 292 * rendered. 293 * <p> 294 * Sometimes you may want to render the page using some other page's context. 295 * In those cases, it is highly recommended that you set the setRealPage() 296 * to point at the real page you are rendering. Please see InsertPageTag 297 * for an example. 298 * <p> 299 * Also, if your plugin e.g. does some variable setting, be aware that if it 300 * is embedded in the LeftMenu or some other page added with InsertPageTag, 301 * you should consider what you want to do - do you wish to really reference 302 * the "master" page or the included page. 303 * 304 * @param page The real page which is being rendered. 305 * @return The previous real page 306 * @since 2.3.14 307 * @see org.apache.wiki.tags.InsertPageTag 308 */ 309 public WikiPage setRealPage( WikiPage page ) 310 { 311 WikiPage old = m_realPage; 312 m_realPage = page; 313 updateCommand( m_command.getRequestContext() ); 314 return old; 315 } 316 317 /** 318 * Gets a reference to the real page whose content is currently being rendered. 319 * If your plugin e.g. does some variable setting, be aware that if it 320 * is embedded in the LeftMenu or some other page added with InsertPageTag, 321 * you should consider what you want to do - do you wish to really reference 322 * the "master" page or the included page. 323 * <p> 324 * For example, in the default template, there is a page called "LeftMenu". 325 * Whenever you access a page, e.g. "Main", the master page will be Main, and 326 * that's what the getPage() will return - regardless of whether your plugin 327 * resides on the LeftMenu or on the Main page. However, getRealPage() 328 * will return "LeftMenu". 329 * 330 * @return A reference to the real page. 331 * @see org.apache.wiki.tags.InsertPageTag 332 * @see org.apache.wiki.parser.JSPWikiMarkupParser 333 */ 334 public WikiPage getRealPage() 335 { 336 return m_realPage; 337 } 338 339 /** 340 * Figure out to which page we are really going to. Considers 341 * special page names from the jspwiki.properties, and possible aliases. 342 * This method forwards requests to 343 * {@link org.apache.wiki.ui.CommandResolver#getSpecialPageReference(String)}. 344 * @return A complete URL to the new page to redirect to 345 * @since 2.2 346 */ 347 348 public String getRedirectURL() 349 { 350 String pagename = m_page.getName(); 351 String redirURL = m_engine.getCommandResolver().getSpecialPageReference( pagename ); 352 353 if( redirURL == null ) 354 { 355 String alias = (String)m_page.getAttribute( WikiPage.ALIAS ); 356 357 if( alias != null ) 358 { 359 redirURL = getViewURL( alias ); 360 } 361 else 362 { 363 redirURL = (String)m_page.getAttribute( WikiPage.REDIRECT ); 364 } 365 } 366 367 return redirURL; 368 } 369 370 /** 371 * Returns the handling engine. 372 * 373 * @return The wikiengine owning this context. 374 */ 375 public WikiEngine getEngine() 376 { 377 return m_engine; 378 } 379 380 /** 381 * Returns the page that is being handled. 382 * 383 * @return the page which was fetched. 384 */ 385 public WikiPage getPage() 386 { 387 return m_page; 388 } 389 390 /** 391 * Sets the page that is being handled. 392 * 393 * @param page The wikipage 394 * @since 2.1.37. 395 */ 396 public void setPage( WikiPage page ) 397 { 398 m_page = page; 399 updateCommand( m_command.getRequestContext() ); 400 } 401 402 /** 403 * Returns the request context. 404 * @return The name of the request context (e.g. VIEW). 405 */ 406 @Override 407 public String getRequestContext() 408 { 409 return m_command.getRequestContext(); 410 } 411 412 /** 413 * Sets the request context. See above for the different 414 * request contexts (VIEW, EDIT, etc.) 415 * 416 * @param arg The request context (one of the predefined contexts.) 417 */ 418 public void setRequestContext( String arg ) 419 { 420 updateCommand( arg ); 421 } 422 423 /** 424 * {@inheritDoc} 425 * @see org.apache.wiki.ui.Command#getTarget() 426 */ 427 @Override 428 public Object getTarget() 429 { 430 return m_command.getTarget(); 431 } 432 433 /** 434 * {@inheritDoc} 435 * @see org.apache.wiki.ui.Command#getURLPattern() 436 */ 437 @Override 438 public String getURLPattern() 439 { 440 return m_command.getURLPattern(); 441 } 442 443 /** 444 * Gets a previously set variable. 445 * 446 * @param key The variable name. 447 * @return The variable contents. 448 */ 449 public Object getVariable( String key ) 450 { 451 return m_variableMap.get( key ); 452 } 453 454 /** 455 * Sets a variable. The variable is valid while the WikiContext is valid, 456 * i.e. while page processing continues. The variable data is discarded 457 * once the page processing is finished. 458 * 459 * @param key The variable name. 460 * @param data The variable value. 461 */ 462 public void setVariable( String key, Object data ) 463 { 464 m_variableMap.put( key, data ); 465 updateCommand( m_command.getRequestContext() ); 466 } 467 468 /** 469 * This is just a simple helper method which will first check the context 470 * if there is already an override in place, and if there is not, 471 * it will then check the given properties. 472 * 473 * @param key What key are we searching for? 474 * @param defValue Default value for the boolean 475 * @return {@code true} or {@code false}. 476 */ 477 public boolean getBooleanWikiProperty( final String key, final boolean defValue ) { 478 Object bool = getVariable( key ); 479 if( bool != null ) { 480 return TextUtil.isPositive( (String) bool ); 481 } 482 483 return TextUtil.getBooleanProperty( getEngine().getWikiProperties(), key, defValue ); 484 } 485 486 /** 487 * This method will safely return any HTTP parameters that 488 * might have been defined. You should use this method instead 489 * of peeking directly into the result of getHttpRequest(), since 490 * this method is smart enough to do all of the right things, 491 * figure out UTF-8 encoded parameters, etc. 492 * 493 * @since 2.0.13. 494 * @param paramName Parameter name to look for. 495 * @return HTTP parameter, or null, if no such parameter existed. 496 */ 497 public String getHttpParameter( String paramName ) 498 { 499 String result = null; 500 501 if( m_request != null ) 502 { 503 result = m_request.getParameter( paramName ); 504 } 505 506 return result; 507 } 508 509 /** 510 * If the request did originate from a HTTP request, 511 * then the HTTP request can be fetched here. However, it the request 512 * did NOT originate from a HTTP request, then this method will 513 * return null, and YOU SHOULD CHECK FOR IT! 514 * 515 * @return Null, if no HTTP request was done. 516 * @since 2.0.13. 517 */ 518 public HttpServletRequest getHttpRequest() 519 { 520 return m_request; 521 } 522 523 /** 524 * Sets the template to be used for this request. 525 * 526 * @param dir The template name 527 * @since 2.1.15. 528 */ 529 public void setTemplate( String dir ) 530 { 531 m_template = dir; 532 } 533 534 /** 535 * Returns the target of this wiki context: a page, group name or JSP. If 536 * the associated Command is a PageCommand, this method returns the page's 537 * name. Otherwise, this method delegates to the associated Command's 538 * {@link org.apache.wiki.ui.Command#getName()} method. Calling classes 539 * can rely on the results of this method for looking up canonically-correct 540 * page or group names. Because it does not automatically assume that the 541 * wiki context is a PageCommand, calling this method is inherently safer 542 * than calling <code>getPage().getName()</code>. 543 * @return the name of the target of this wiki context 544 * @see org.apache.wiki.ui.PageCommand#getName() 545 * @see org.apache.wiki.ui.GroupCommand#getName() 546 */ 547 @Override 548 public String getName() 549 { 550 if ( m_command instanceof PageCommand ) 551 { 552 return m_page != null ? m_page.getName() : "<no page>"; 553 } 554 return m_command.getName(); 555 } 556 557 /** 558 * Gets the template that is to be used throughout this request. 559 * @since 2.1.15. 560 * @return template name 561 */ 562 public String getTemplate() 563 { 564 return m_template; 565 } 566 567 /** 568 * Convenience method that gets the current user. Delegates the 569 * lookup to the WikiSession associated with this WikiContect. 570 * May return null, in case the current 571 * user has not yet been determined; or this is an internal system. 572 * If the WikiSession has not been set, <em>always</em> returns null. 573 * 574 * @return The current user; or maybe null in case of internal calls. 575 */ 576 public Principal getCurrentUser() 577 { 578 if (m_session == null) 579 { 580 // This shouldn't happen, really... 581 return WikiPrincipal.GUEST; 582 } 583 return m_session.getUserPrincipal(); 584 } 585 586 /** 587 * A shortcut to generate a VIEW url. 588 * 589 * @param page The page to which to link. 590 * @return An URL to the page. This honours the current absolute/relative setting. 591 */ 592 public String getViewURL( String page ) 593 { 594 return getURL( VIEW, page, null ); 595 } 596 597 /** 598 * Creates an URL for the given request context. 599 * 600 * @param context e.g. WikiContext.EDIT 601 * @param page The page to which to link 602 * @return An URL to the page, honours the absolute/relative setting in jspwiki.properties 603 */ 604 public String getURL( String context, 605 String page ) 606 { 607 return getURL( context, page, null ); 608 } 609 610 /** 611 * Returns an URL from a page. It this WikiContext instance was constructed 612 * with an actual HttpServletRequest, we will attempt to construct the 613 * URL using HttpUtil, which preserves the HTTPS portion if it was used. 614 * 615 * @param context The request context (e.g. WikiContext.UPLOAD) 616 * @param page The page to which to link 617 * @param params A list of parameters, separated with "&" 618 * 619 * @return An URL to the given context and page. 620 */ 621 public String getURL( String context, 622 String page, 623 String params ) 624 { 625 boolean absolute = "absolute".equals(m_engine.getVariable( this, WikiEngine.PROP_REFSTYLE )); 626 627 // FIXME: is rather slow 628 return m_engine.getURL( context, 629 page, 630 params, 631 absolute ); 632 633 } 634 635 /** 636 * Returns the Command associated with this WikiContext. 637 * @return the command 638 */ 639 public Command getCommand() 640 { 641 return m_command; 642 } 643 644 /** 645 * Returns a shallow clone of the WikiContext. 646 * 647 * @since 2.1.37. 648 * @return A shallow clone of the WikiContext 649 */ 650 @Override 651 public Object clone() 652 { 653 try 654 { 655 // super.clone() must always be called to make sure that inherited objects 656 // get the right type 657 WikiContext copy = (WikiContext)super.clone(); 658 659 copy.m_engine = m_engine; 660 copy.m_command = m_command; 661 662 copy.m_template = m_template; 663 copy.m_variableMap = m_variableMap; 664 copy.m_request = m_request; 665 copy.m_session = m_session; 666 copy.m_page = m_page; 667 copy.m_realPage = m_realPage; 668 return copy; 669 } 670 catch( CloneNotSupportedException e ){} // Never happens 671 672 return null; 673 } 674 675 /** 676 * Creates a deep clone of the WikiContext. This is useful when you want 677 * to be sure that you don't accidentally mess with page attributes, etc. 678 * 679 * @since 2.8.0 680 * @return A deep clone of the WikiContext. 681 */ 682 @SuppressWarnings("unchecked") 683 public WikiContext deepClone() 684 { 685 try 686 { 687 // super.clone() must always be called to make sure that inherited objects 688 // get the right type 689 WikiContext copy = (WikiContext)super.clone(); 690 691 // No need to deep clone these 692 copy.m_engine = m_engine; 693 copy.m_command = m_command; // Static structure 694 695 copy.m_template = m_template; 696 copy.m_variableMap = (HashMap<String,Object>)m_variableMap.clone(); 697 copy.m_request = m_request; 698 copy.m_session = m_session; 699 copy.m_page = (WikiPage)m_page.clone(); 700 copy.m_realPage = (WikiPage)m_realPage.clone(); 701 return copy; 702 } 703 catch( CloneNotSupportedException e ){} // Never happens 704 705 return null; 706 } 707 708 /** 709 * Returns the WikiSession associated with the context. 710 * This method is guaranteed to always return a valid WikiSession. 711 * If this context was constructed without an associated 712 * HttpServletRequest, it will return {@link WikiSession#guestSession(WikiEngine)}. 713 * 714 * @return The WikiSession associate with this context. 715 */ 716 public WikiSession getWikiSession() 717 { 718 return m_session; 719 } 720 721 /** 722 * This method can be used to find the WikiContext programmatically 723 * from a JSP PageContext. We check the request context. 724 * The wiki context, if it exists, 725 * is looked up using the key 726 * {@link org.apache.wiki.tags.WikiTagBase#ATTR_CONTEXT}. 727 * 728 * @since 2.4 729 * @param pageContext the JSP page context 730 * @return Current WikiContext, or null, of no context exists. 731 */ 732 public static WikiContext findContext( PageContext pageContext ) 733 { 734 HttpServletRequest request = (HttpServletRequest) pageContext.getRequest(); 735 WikiContext context = (WikiContext)request.getAttribute( WikiTagBase.ATTR_CONTEXT ); 736 return context; 737 } 738 739 /** 740 * Returns the permission required to successfully execute this context. 741 * For example, the a wiki context of VIEW for a certain page means that 742 * the PagePermission "view" is required for the page. In some cases, no 743 * particular permission is required, in which case a dummy permission will 744 * be returned ({@link java.util.PropertyPermission}<code> "os.name", 745 * "read"</code>). This method is guaranteed to always return a valid, 746 * non-null permission. 747 * @return the permission 748 * @since 2.4 749 */ 750 @Override 751 public Permission requiredPermission() 752 { 753 // This is a filthy rotten hack -- absolutely putrid 754 if ( WikiCommand.INSTALL.equals( m_command ) ) 755 { 756 // See if admin users exists 757 try 758 { 759 UserManager userMgr = m_engine.getUserManager(); 760 UserDatabase userDb = userMgr.getUserDatabase(); 761 userDb.findByLoginName( Installer.ADMIN_ID ); 762 } 763 catch ( NoSuchPrincipalException e ) 764 { 765 return DUMMY_PERMISSION; 766 } 767 return new AllPermission( m_engine.getApplicationName() ); 768 } 769 770 // TODO: we should really break the contract so that this 771 // method returns null, but until then we will use this hack 772 if ( m_command.requiredPermission() == null ) 773 { 774 return DUMMY_PERMISSION; 775 } 776 777 return m_command.requiredPermission(); 778 } 779 780 /** 781 * Associates a target with the current Command and returns 782 * the new targeted Command. If the Command associated with this 783 * WikiContext is already "targeted", it is returned instead. 784 * @see org.apache.wiki.ui.Command#targetedCommand(java.lang.Object) 785 * 786 * {@inheritDoc} 787 */ 788 @Override 789 public Command targetedCommand( Object target ) 790 { 791 if ( m_command.getTarget() == null ) 792 { 793 return m_command.targetedCommand( target ); 794 } 795 return m_command; 796 } 797 798 /** 799 * Returns true, if the current user has administrative permissions (i.e. the omnipotent 800 * AllPermission). 801 * 802 * @since 2.4.46 803 * @return true, if the user has all permissions. 804 */ 805 public boolean hasAdminPermissions() { 806 return m_engine.getAuthorizationManager().checkPermission( getWikiSession(), new AllPermission(m_engine.getApplicationName()) ); 807 } 808 809 /** 810 * Figures out which template a new WikiContext should be using. 811 * @param request the HTTP request 812 */ 813 protected void setDefaultTemplate( HttpServletRequest request ) 814 { 815 String defaultTemplate = m_engine.getTemplateDir(); 816 817 // Figure out which template we should be using for this page. 818 String template = null; 819 if ( request != null ) 820 { 821 template = request.getParameter( "skin" ); 822 } 823 824 // If request doesn't supply the value, extract from wiki page 825 if( template == null ) 826 { 827 WikiPage page = getPage(); 828 if ( page != null ) 829 { 830 template = (String)page.getAttribute( WikiEngine.PROP_TEMPLATEDIR ); 831 } 832 833 } 834 835 // If something over-wrote the default, set the new value. 836 if ( template != null ) 837 { 838 setTemplate( template ); 839 } 840 else 841 { 842 setTemplate( defaultTemplate ); 843 } 844 } 845 846 /** 847 * Looks up and returns a PageCommand based on a supplied WikiPage and HTTP 848 * request. First, the appropriate Command is obtained by examining the HTTP 849 * request; the default is {@link PageCommand#VIEW}. If the Command is a 850 * PageCommand (and it should be, in most cases), a targeted Command is 851 * created using the (non-<code>null</code>) WikiPage as target. 852 * @param engine the wiki engine 853 * @param request the HTTP request 854 * @param page the wiki page 855 * @return the correct command 856 */ 857 protected static Command findCommand( WikiEngine engine, HttpServletRequest request, WikiPage page ) 858 { 859 String defaultContext = PageCommand.VIEW.getRequestContext(); 860 Command command = engine.getCommandResolver().findCommand( request, defaultContext ); 861 if ( command instanceof PageCommand && page != null ) 862 { 863 command = command.targetedCommand( page ); 864 } 865 return command; 866 } 867 868 /** 869 * Protected method that updates the internally cached Command. 870 * Will always be called when the page name, request context, or variable 871 * changes. 872 * @param requestContext the desired request context 873 * @since 2.4 874 */ 875 protected void updateCommand( String requestContext ) 876 { 877 if ( requestContext == null ) 878 { 879 m_command = PageCommand.NONE; 880 } 881 else 882 { 883 CommandResolver resolver = m_engine.getCommandResolver(); 884 m_command = resolver.findCommand( m_request, requestContext ); 885 } 886 887 if ( m_command instanceof PageCommand && m_page != null ) 888 { 889 m_command = m_command.targetedCommand( m_page ); 890 } 891 } 892 893}