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.Principal;
023 import java.util.ArrayList;
024 import java.util.List;
025 import java.util.ResourceBundle;
026
027 import javax.servlet.http.HttpServletRequest;
028
029 import org.apache.wiki.WikiContext;
030 import org.apache.wiki.WikiEngine;
031 import org.apache.wiki.WikiSession;
032 import org.apache.wiki.auth.AuthenticationManager;
033 import org.apache.wiki.auth.GroupPrincipal;
034 import org.apache.wiki.auth.UserManager;
035 import org.apache.wiki.auth.WikiSecurityException;
036 import org.apache.wiki.auth.authorize.Role;
037 import org.apache.wiki.auth.user.UserProfile;
038 import org.apache.wiki.i18n.InternationalizationManager;
039 import org.apache.wiki.preferences.Preferences;
040 import 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 */
075 public 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 StringBuffer sb = new StringBuffer();
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 StringBuffer sb = new StringBuffer();
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 }