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