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 */
019 package org.apache.wiki.tags;
020
021 import java.io.IOException;
022 import java.security.Permission;
023
024 import org.apache.commons.lang.StringUtils;
025
026 import org.apache.wiki.WikiPage;
027 import org.apache.wiki.WikiProvider;
028 import org.apache.wiki.WikiSession;
029 import org.apache.wiki.auth.AuthorizationManager;
030 import org.apache.wiki.auth.GroupPrincipal;
031 import org.apache.wiki.auth.permissions.AllPermission;
032 import org.apache.wiki.auth.permissions.GroupPermission;
033 import org.apache.wiki.auth.permissions.PermissionFactory;
034 import org.apache.wiki.auth.permissions.WikiPermission;
035 import org.apache.wiki.ui.Command;
036 import 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 */
064 public 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 }