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.Principal; 023import java.util.ArrayList; 024import java.util.List; 025import java.util.ResourceBundle; 026 027import javax.servlet.http.HttpServletRequest; 028 029import org.apache.wiki.WikiContext; 030import org.apache.wiki.WikiEngine; 031import org.apache.wiki.WikiSession; 032import org.apache.wiki.auth.AuthenticationManager; 033import org.apache.wiki.auth.GroupPrincipal; 034import org.apache.wiki.auth.UserManager; 035import org.apache.wiki.auth.WikiSecurityException; 036import org.apache.wiki.auth.authorize.Role; 037import org.apache.wiki.auth.user.UserProfile; 038import org.apache.wiki.i18n.InternationalizationManager; 039import org.apache.wiki.preferences.Preferences; 040import org.apache.wiki.util.TextUtil; 041 042/** 043 * <p> 044 * Returns user profile attributes, or empty strings if the user has not been 045 * validated. This tag has a single attribute, "property." 046 * The <code>property</code> attribute may contain one of the following 047 * case-insensitive values: 048 * </p> 049 * <ul> 050 * <li><code>created</code> - creation date</li> 051 * <li><code>email</code> - user's e-mail address</li> 052 * <li><code>fullname</code> - user's full name</li> 053 * <li><code>groups</code> - a sorted list of the groups a user belongs to</li> 054 * <li><code>loginname</code> - user's login name. If the current user does not have 055 * a profile, the user's login principal (such as one provided by a container 056 * login module, user cookie, or anonyous IP address), will supply the login 057 * name property</li> 058 * <li><code>roles</code> - a sorted list of the roles a user possesses</li> 059 * <li><code>wikiname</code> - user's wiki name</li> 060 * <li><code>modified</code> - last modification date</li> 061 * <li><code>exists</code> - evaluates the body of the tag if user's profile exists 062 * in the user database 063 * <li><code>new</code> - evaluates the body of the tag if user's profile does not 064 * exist in the user database 065 * <li><code>canChangeLoginName</code> - always true if custom auth used; also true for container auth 066 * and current UserDatabase.isSharedWithContainer() is true.</li> 067 * <li><code>canChangePassword</code> - always true if custom auth used; also true for container auth 068 * and current UserDatabase.isSharedWithContainer() is true.</li> 069 * </ul> 070 * <p>In addition, the values <code>exists</code>, <code>new</code>, <code>canChangeLoginName</code> 071 * and <code>canChangeLoginName</code> can also be prefixed with <code>!</code> to indicate the 072 * negative condition (for example, <code>!exists</code>).</p> 073 * @since 2.3 074 */ 075public class UserProfileTag extends WikiTagBase 076{ 077 private static final long serialVersionUID = 3258410625431582003L; 078 079 public static final String BLANK = "(not set)"; 080 081 private static final String CREATED = "created"; 082 083 private static final String EMAIL = "email"; 084 085 private static final String EXISTS = "exists"; 086 087 private static final String NOT_EXISTS= "!exists"; 088 089 private static final String FULLNAME = "fullname"; 090 091 private static final String GROUPS = "groups"; 092 093 private static final String LOGINNAME = "loginname"; 094 095 private static final String MODIFIED = "modified"; 096 097 private static final String NEW = "new"; 098 099 private static final String NOT_NEW = "!new"; 100 101 private static final String ROLES = "roles"; 102 103 private static final String WIKINAME = "wikiname"; 104 105 private static final String CHANGE_LOGIN_NAME = "canchangeloginname"; 106 107 private static final String NOT_CHANGE_LOGIN_NAME = "!canchangeloginname"; 108 109 private static final String CHANGE_PASSWORD = "canchangepassword"; 110 111 private static final String NOT_CHANGE_PASSWORD = "!canchangepassword"; 112 113 private String m_prop; 114 115 public void initTag() 116 { 117 super.initTag(); 118 m_prop = null; 119 } 120 121 public final int doWikiStartTag() throws IOException, WikiSecurityException 122 { 123 UserManager manager = m_wikiContext.getEngine().getUserManager(); 124 UserProfile profile = manager.getUserProfile( m_wikiContext.getWikiSession() ); 125 String result = null; 126 127 if ( EXISTS.equals( m_prop ) || NOT_NEW.equals( m_prop ) ) 128 { 129 return profile.isNew() ? SKIP_BODY : EVAL_BODY_INCLUDE; 130 } 131 else if ( NEW.equals( m_prop ) || NOT_EXISTS.equals( m_prop ) ) 132 { 133 return profile.isNew() ? EVAL_BODY_INCLUDE : SKIP_BODY; 134 } 135 136 else if ( CREATED.equals( m_prop ) && profile.getCreated() != null ) 137 { 138 result = profile.getCreated().toString(); 139 } 140 else if ( EMAIL.equals( m_prop ) ) 141 { 142 result = profile.getEmail(); 143 } 144 else if ( FULLNAME.equals( m_prop ) ) 145 { 146 result = profile.getFullname(); 147 } 148 else if ( GROUPS.equals( m_prop ) ) 149 { 150 result = printGroups( m_wikiContext ); 151 } 152 else if ( LOGINNAME.equals( m_prop ) ) 153 { 154 result = profile.getLoginName(); 155 } 156 else if ( MODIFIED.equals( m_prop ) && profile.getLastModified() != null ) 157 { 158 result = profile.getLastModified().toString(); 159 } 160 else if ( ROLES.equals( m_prop ) ) 161 { 162 result = printRoles( m_wikiContext ); 163 } 164 else if ( WIKINAME.equals( m_prop ) ) 165 { 166 result = profile.getWikiName(); 167 168 if( result == null ) 169 { 170 // 171 // Default back to the declared user name 172 // 173 WikiEngine engine = this.m_wikiContext.getEngine(); 174 WikiSession wikiSession = WikiSession.getWikiSession( engine, (HttpServletRequest)pageContext.getRequest() ); 175 Principal user = wikiSession.getUserPrincipal(); 176 177 if( user != null ) 178 { 179 result = user.getName(); 180 } 181 } 182 } 183 else if ( CHANGE_PASSWORD.equals( m_prop ) || CHANGE_LOGIN_NAME.equals( m_prop ) ) 184 { 185 AuthenticationManager authMgr = m_wikiContext.getEngine().getAuthenticationManager(); 186 if ( !authMgr.isContainerAuthenticated() ) 187 { 188 return EVAL_BODY_INCLUDE; 189 } 190 } 191 else if ( NOT_CHANGE_PASSWORD.equals( m_prop ) || NOT_CHANGE_LOGIN_NAME.equals( m_prop ) ) 192 { 193 AuthenticationManager authMgr = m_wikiContext.getEngine().getAuthenticationManager(); 194 if ( authMgr.isContainerAuthenticated() ) 195 { 196 return EVAL_BODY_INCLUDE; 197 } 198 } 199 200 if ( result != null ) 201 { 202 pageContext.getOut().print( TextUtil.replaceEntities(result) ); 203 } 204 return SKIP_BODY; 205 } 206 207 public void setProperty( String property ) 208 { 209 m_prop = property.toLowerCase().trim(); 210 } 211 212 /** 213 * Returns a sorted list of the {@link org.apache.wiki.auth.authorize.Group} objects a user possesses 214 * in his or her WikiSession. The result is computed by consulting 215 * {@link org.apache.wiki.WikiSession#getRoles()} 216 * and extracting those that are of type Group. 217 * @return the list of groups, sorted by name 218 */ 219 public static String printGroups( WikiContext context ) 220 { 221 Principal[] roles = context.getWikiSession().getRoles(); 222 List<String> tempRoles = new ArrayList<String>(); 223 ResourceBundle rb = Preferences.getBundle( context, InternationalizationManager.CORE_BUNDLE ); 224 225 for ( Principal role : roles ) 226 { 227 if( role instanceof GroupPrincipal ) 228 { 229 tempRoles.add( role.getName() ); 230 } 231 } 232 if ( tempRoles.size() == 0 ) 233 { 234 return rb.getString("userprofile.nogroups"); 235 } 236 237 StringBuilder sb = new StringBuilder(); 238 for ( int i = 0; i < tempRoles.size(); i++ ) 239 { 240 String name = tempRoles.get( i ); 241 242 sb.append( name ); 243 if ( i < ( tempRoles.size() - 1 ) ) 244 { 245 sb.append(','); 246 sb.append(' '); 247 } 248 249 } 250 return sb.toString(); 251 } 252 253 /** 254 * Returns a sorted list of the {@link org.apache.wiki.auth.authorize.Role} objects a user possesses 255 * in his or her WikiSession. The result is computed by consulting 256 * {@link org.apache.wiki.WikiSession#getRoles()} 257 * and extracting those that are of type Role. 258 * @return the list of roles, sorted by name 259 */ 260 public static String printRoles( WikiContext context ) 261 { 262 Principal[] roles = context.getWikiSession().getRoles(); 263 List<String> tempRoles = new ArrayList<String>(); 264 ResourceBundle rb = Preferences.getBundle( context, InternationalizationManager.CORE_BUNDLE ); 265 266 for ( Principal role : roles ) 267 { 268 if ( role instanceof Role ) 269 { 270 tempRoles.add( role.getName() ); 271 } 272 } 273 if ( tempRoles.size() == 0 ) 274 { 275 return rb.getString( "userprofile.noroles" ); 276 } 277 278 StringBuilder sb = new StringBuilder(); 279 for ( int i = 0; i < tempRoles.size(); i++ ) 280 { 281 String name = tempRoles.get( i ); 282 283 sb.append( name ); 284 if ( i < ( tempRoles.size() - 1 ) ) 285 { 286 sb.append(','); 287 sb.append(' '); 288 } 289 290 } 291 return sb.toString(); 292 } 293}