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.tags; 020 021import java.io.IOException; 022import java.security.Permission; 023 024import org.apache.commons.lang.StringUtils; 025 026import org.apache.wiki.WikiPage; 027import org.apache.wiki.WikiProvider; 028import org.apache.wiki.WikiSession; 029import org.apache.wiki.auth.AuthorizationManager; 030import org.apache.wiki.auth.GroupPrincipal; 031import org.apache.wiki.auth.permissions.AllPermission; 032import org.apache.wiki.auth.permissions.GroupPermission; 033import org.apache.wiki.auth.permissions.PermissionFactory; 034import org.apache.wiki.auth.permissions.WikiPermission; 035import org.apache.wiki.ui.Command; 036import org.apache.wiki.ui.GroupCommand; 037 038/** 039 * Tells whether the user in the current wiki context possesses a particular 040 * permission. The permission is typically a PagePermission (e.g., "edit", "view", 041 * "delete", "comment", "upload"). It may also be a wiki-wide WikiPermission 042 * ("createPages", "createGroups", "editProfile", "editPreferences", "login") 043 * or the administrator permission ("allPermission"). GroupPermissions 044 * (e.g., "viewGroup", "editGroup", "deleteGroup"). 045 * <p> 046 * Since 2.6, it is possible to list several permissions or use negative permissions, 047 * e.g. 048 * <pre> 049 * <wiki:Permission permission="edit|rename|view"> 050 * You have edit, rename, or view permissions! 051 * </wiki:Permission> 052 * </pre> 053 * 054 * or 055 * 056 * <pre> 057 * <wiki:Permission permission="!upload"> 058 * You do not have permission to upload! 059 * </wiki:Permission> 060 * </pre> 061 * 062 * @since 2.0 063 */ 064public class PermissionTag 065 extends WikiTagBase 066{ 067 private static final String ALL_PERMISSION = "allPermission"; 068 private static final String CREATE_GROUPS = "createGroups"; 069 private static final String CREATE_PAGES = "createPages"; 070 private static final String DELETE_GROUP = "deleteGroup"; 071 private static final String EDIT = "edit"; 072 private static final String EDIT_GROUP = "editGroup"; 073 private static final String EDIT_PREFERENCES = "editPreferences"; 074 private static final String EDIT_PROFILE = "editProfile"; 075 private static final String LOGIN = "login"; 076 private static final String VIEW_GROUP = "viewGroup"; 077 078 private static final long serialVersionUID = 3761412993048982325L; 079 080 private String[] m_permissionList; 081 082 /** 083 * Initializes the tag. 084 */ 085 @Override 086 public void initTag() 087 { 088 super.initTag(); 089 m_permissionList = null; 090 } 091 092 /** 093 * Sets the permissions to look for (case sensitive). See above for the format. 094 * 095 * @param permission A list of permissions 096 */ 097 public void setPermission( String permission ) 098 { 099 m_permissionList = StringUtils.split(permission,'|'); 100 } 101 102 /** 103 * Checks a single permission. 104 * 105 * @param permission 106 * @return true if granted, false if not 107 */ 108 private boolean checkPermission( String permission ) 109 { 110 WikiSession session = m_wikiContext.getWikiSession(); 111 WikiPage page = m_wikiContext.getPage(); 112 AuthorizationManager mgr = m_wikiContext.getEngine().getAuthorizationManager(); 113 boolean gotPermission = false; 114 115 if ( CREATE_GROUPS.equals( permission ) || CREATE_PAGES.equals( permission ) 116 || EDIT_PREFERENCES.equals( permission ) || EDIT_PROFILE.equals( permission ) 117 || LOGIN.equals( permission ) ) 118 { 119 gotPermission = mgr.checkPermission( session, new WikiPermission( page.getWiki(), permission ) ); 120 } 121 else if ( VIEW_GROUP.equals( permission ) 122 || EDIT_GROUP.equals( permission ) 123 || DELETE_GROUP.equals( permission ) ) 124 { 125 Command command = m_wikiContext.getCommand(); 126 gotPermission = false; 127 if ( command instanceof GroupCommand && command.getTarget() != null ) 128 { 129 GroupPrincipal group = (GroupPrincipal)command.getTarget(); 130 String groupName = group.getName(); 131 String action = "view"; 132 if( EDIT_GROUP.equals( permission ) ) 133 { 134 action = "edit"; 135 } 136 else if ( DELETE_GROUP.equals( permission ) ) 137 { 138 action = "delete"; 139 } 140 gotPermission = mgr.checkPermission( session, new GroupPermission( groupName, action ) ); 141 } 142 } 143 else if ( ALL_PERMISSION.equals( permission ) ) 144 { 145 gotPermission = mgr.checkPermission( session, new AllPermission( m_wikiContext.getEngine().getApplicationName() ) ); 146 } 147 else if ( page != null ) 148 { 149 // 150 // Edit tag also checks that we're not trying to edit an 151 // old version: they cannot be edited. 152 // 153 if( EDIT.equals(permission) ) 154 { 155 WikiPage latest = m_wikiContext.getEngine().getPage( page.getName() ); 156 if( page.getVersion() != WikiProvider.LATEST_VERSION && 157 latest.getVersion() != page.getVersion() ) 158 { 159 return false; 160 } 161 } 162 163 Permission p = PermissionFactory.getPagePermission( page, permission ); 164 gotPermission = mgr.checkPermission( session, 165 p ); 166 } 167 168 return gotPermission; 169 } 170 171 /** 172 * Initializes the tag. 173 * @return the result of the tag: SKIP_BODY or EVAL_BODY_CONTINUE 174 * @throws IOException this exception will never be thrown 175 */ 176 @Override 177 public final int doWikiStartTag() 178 throws IOException 179 { 180 for( int i = 0; i < m_permissionList.length; i++ ) 181 { 182 String perm = m_permissionList[i]; 183 184 boolean hasPermission = false; 185 186 if( perm.charAt(0) == '!' ) 187 { 188 hasPermission = !checkPermission( perm.substring(1) ); 189 } 190 else 191 { 192 hasPermission = checkPermission( perm ); 193 } 194 195 if( hasPermission ) 196 return EVAL_BODY_INCLUDE; 197 } 198 199 return SKIP_BODY; 200 } 201}