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