View Javadoc
1   /*
2    * This software was designed and created by Jason Carroll.
3    * Copyright (c) 2002, 2003, 2004 Jason Carroll.
4    * The author can be reached at jcarroll@cowsultants.com
5    * ITracker website: http://www.cowsultants.com
6    * ITracker forums: http://www.cowsultants.com/phpBB/index.php
7    *
8    * This program is free software; you can redistribute it and/or modify
9    * it only under the terms of the GNU General Public License as published by
10   * the Free Software Foundation; either version 2 of the License, or
11   * (at your option) any later version.
12   *
13   * This program is distributed in the hope that it will be useful,
14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   * GNU General Public License for more details.
17   */
18  
19  package org.itracker.model.util;
20  
21  import org.itracker.PasswordException;
22  import org.itracker.core.AuthenticationConstants;
23  import org.itracker.core.resources.ITrackerResources;
24  import org.itracker.model.*;
25  import org.itracker.util.Base64Coder;
26  
27  import java.io.UnsupportedEncodingException;
28  import java.security.MessageDigest;
29  import java.security.NoSuchAlgorithmException;
30  import java.util.*;
31  
32  
33  public class UserUtilities implements AuthenticationConstants {
34      protected static final char[] alphabet = new char[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
35  
36      public static final int STATUS_DELETED = -1;
37      public static final int STATUS_ACTIVE = 1;
38      public static final int STATUS_LOCKED = 2;
39  
40      // TODO: Could use an enumeration
41  
42      /**
43       * User Admin Permission.  Currently this is equivalent to super user, since the permission can't be granted, and is only available to an admin.
44       */
45      public static final int PERMISSION_USER_ADMIN = PermissionType.USER_ADMIN.getCode();
46      /**
47       * Product Admin Permission
48       */
49      public static final int PERMISSION_PRODUCT_ADMIN = PermissionType.PRODUCT_ADMIN.getCode();
50      /**
51       * Issue Create Permission
52       */
53      public static final int PERMISSION_CREATE = PermissionType.ISSUE_CREATE.getCode();
54      /**
55       * Issue Edit Permission.  Users with this permission can edit any issue in the project.
56       */
57      public static final int PERMISSION_EDIT = PermissionType.ISSUE_EDIT_ALL.getCode();
58      /**
59       * Issue Close Permission.  Users with this permission can close issues in the project.
60       */
61      public static final int PERMISSION_CLOSE = PermissionType.ISSUE_CLOSE.getCode();
62      /**
63       * Issue Assign to Self Permission.  Users with this permission can assign issues to themselves.
64       */
65      public static final int PERMISSION_ASSIGN_SELF = PermissionType.ISSUE_ASSIGN_SELF.getCode();
66      /**
67       * Issue Assign to Others Permissions.  Users with this permission can assign issues to anyone, given than those users have the ability to recieve the assignment.
68       */
69      public static final int PERMISSION_ASSIGN_OTHERS = PermissionType.ISSUE_ASSIGN_OTHERS.getCode();
70      /**
71       * View All Issues Permission.  Users can view all issues in the project.
72       */
73      public static final int PERMISSION_VIEW_ALL = PermissionType.ISSUE_VIEW_ALL.getCode();
74      /**
75       * View Users Issues Permission.  Users can view thier own issues.  This includes ones they are the creator or owner of.
76       */
77      public static final int PERMISSION_VIEW_USERS = PermissionType.ISSUE_VIEW_USERS.getCode();
78      /**
79       * Edit Users Issues Permission.  Users with this permission can edit any issue they created or own.
80       * They are limited to editing the description, adding history entries, and adding attachments.
81       */
82      public static final int PERMISSION_EDIT_USERS = PermissionType.ISSUE_EDIT_USERS.getCode();
83      /**
84       * Issue Unassign Self Permission.  Users with this permission can unassign issues they own.
85       */
86      public static final int PERMISSION_UNASSIGN_SELF = PermissionType.ISSUE_UNASSIGN_SELF.getCode();
87      /**
88       * Issue Assignable.  Users with this permission can be assigned any issue in the system.  To determine if a user can
89       * be assigned an issue, it will be a combination of users with EDIT_ALL, users with EDIT_USERS if they are the creator,
90       * and users with this permission and EDIT_USERS.
91       */
92      public static final int PERMISSION_ASSIGNABLE = PermissionType.ISSUE_ASSIGNABLE.getCode();
93      /**
94       * Create for Others.  Users with this permission are allowed to create issues on behalf of other users.  The system
95       * will treat the issue as if the other user had created it.  The actual creator will be logged in the audit log.
96       */
97      public static final int PERMISSION_CREATE_OTHERS = PermissionType.ISSUE_CREATE_OTHERS.getCode();
98      /**
99       * Full edit permission.  This defines what levelof editing a user has for an issue.  Without this permission, users will
100      * be limited to editing only the description, attachments, custom fields, and history of an issue.
101      */
102     public static final int PERMISSION_EDIT_FULL = PermissionType.ISSUE_EDIT_FULL.getCode();
103 
104 
105     private static final Integer[] ALL_PERMISSIONS = new Integer[]{
106             PERMISSION_PRODUCT_ADMIN,
107             PERMISSION_CREATE,
108             PERMISSION_EDIT,
109             PERMISSION_CLOSE,
110             PERMISSION_ASSIGN_SELF,
111             PERMISSION_ASSIGN_OTHERS,
112             PERMISSION_VIEW_ALL,
113             PERMISSION_VIEW_USERS,
114             PERMISSION_EDIT_USERS,
115             PERMISSION_UNASSIGN_SELF,
116             PERMISSION_ASSIGNABLE,
117             PERMISSION_CREATE_OTHERS,
118             PERMISSION_EDIT_FULL,
119 
120     };
121     public static final Set<Integer> ALL_PERMISSIONS_SET = Collections.unmodifiableSet(getAllPermissionsSet());
122 
123     private static final Set<Integer> getAllPermissionsSet() {
124         return new HashSet<Integer>(Arrays.asList(ALL_PERMISSIONS));
125     }
126 
127     public static final int REGISTRATION_TYPE_ADMIN = 1;
128     public static final int REGISTRATION_TYPE_SELF = 2;
129     public static final int REGISTRATION_TYPE_IMPORT = 3;
130 
131     public static final int PREF_HIDE_ASSIGNED = 1;
132     public static final int PREF_HIDE_UNASSIGNED = 2;
133     public static final int PREF_HIDE_CREATED = 4;
134     public static final int PREF_HIDE_WATCHED = 8;
135 
136     public UserUtilities() {
137     }
138 
139     public static String getStatusName(int value) {
140         return getStatusName(value, ITrackerResources.getLocale());
141     }
142 
143     public static String getStatusName(int value, Locale locale) {
144         return ITrackerResources.getString(ITrackerResources.KEY_BASE_USER_STATUS + value, locale);
145     }
146 
147     public static HashMap<String, String> getStatusNames() {
148         return getStatusNames(ITrackerResources.getLocale());
149     }
150 
151     public static HashMap<String, String> getStatusNames(Locale locale) {
152         HashMap<String, String> statuses = new HashMap<String, String>();
153         statuses.put(Integer.toString(STATUS_DELETED), getStatusName(STATUS_DELETED, locale));
154         statuses.put(Integer.toString(STATUS_ACTIVE), getStatusName(STATUS_ACTIVE, locale));
155         statuses.put(Integer.toString(STATUS_LOCKED), getStatusName(STATUS_LOCKED, locale));
156         return statuses;
157     }
158 
159     public static String getPermissionName(int value) {
160         return getPermissionName(value, ITrackerResources.getLocale());
161     }
162 
163     public static String getPermissionName(int value, Locale locale) {
164         return ITrackerResources.getString(ITrackerResources.KEY_BASE_PERMISSION + value, locale);
165     }
166 
167     public static List<NameValuePair> getPermissionNames() {
168         return getPermissionNames(ITrackerResources.getLocale());
169     }
170 
171     public static List<NameValuePair> getPermissionNames(Locale locale) {
172         List<NameValuePair> permissions = new ArrayList<>();
173         permissions.add(0, new NameValuePair(getPermissionName(PERMISSION_CREATE, locale), Integer.toString(PERMISSION_CREATE)));
174         permissions.add(1, new NameValuePair(getPermissionName(PERMISSION_CREATE_OTHERS, locale), Integer.toString(PERMISSION_CREATE_OTHERS)));
175         permissions.add(2, new NameValuePair(getPermissionName(PERMISSION_EDIT, locale), Integer.toString(PERMISSION_EDIT)));
176         permissions.add(3, new NameValuePair(getPermissionName(PERMISSION_EDIT_USERS, locale), Integer.toString(PERMISSION_EDIT_USERS)));
177         permissions.add(4, new NameValuePair(getPermissionName(PERMISSION_EDIT_FULL, locale), Integer.toString(PERMISSION_EDIT_FULL)));
178         permissions.add(5, new NameValuePair(getPermissionName(PERMISSION_CLOSE, locale), Integer.toString(PERMISSION_CLOSE)));
179         permissions.add(6, new NameValuePair(getPermissionName(PERMISSION_ASSIGNABLE, locale), Integer.toString(PERMISSION_ASSIGNABLE)));
180         permissions.add(7, new NameValuePair(getPermissionName(PERMISSION_ASSIGN_SELF, locale), Integer.toString(PERMISSION_ASSIGN_SELF)));
181         permissions.add(8, new NameValuePair(getPermissionName(PERMISSION_UNASSIGN_SELF, locale), Integer.toString(PERMISSION_UNASSIGN_SELF)));
182         permissions.add(9, new NameValuePair(getPermissionName(PERMISSION_ASSIGN_OTHERS, locale), Integer.toString(PERMISSION_ASSIGN_OTHERS)));
183         permissions.add(10, new NameValuePair(getPermissionName(PERMISSION_VIEW_ALL, locale), Integer.toString(PERMISSION_VIEW_ALL)));
184         permissions.add(11, new NameValuePair(getPermissionName(PERMISSION_VIEW_USERS, locale), Integer.toString(PERMISSION_VIEW_USERS)));
185         permissions.add(12, new NameValuePair(getPermissionName(PERMISSION_PRODUCT_ADMIN, locale), Integer.toString(PERMISSION_PRODUCT_ADMIN)));
186         return permissions;
187     }
188     public static List<NameValuePair> getPermissionTypeNames(Locale locale) {
189         List<NameValuePair> permissions = new ArrayList<>();
190         permissions.add(0, new NameValuePair(getPermissionName(PERMISSION_CREATE, locale), PermissionType.valueOf(PERMISSION_CREATE).name()));
191         permissions.add(1, new NameValuePair(getPermissionName(PERMISSION_CREATE_OTHERS, locale), PermissionType.valueOf(PERMISSION_CREATE_OTHERS).name()));
192         permissions.add(2, new NameValuePair(getPermissionName(PERMISSION_EDIT, locale), PermissionType.valueOf(PERMISSION_EDIT).name()));
193         permissions.add(3, new NameValuePair(getPermissionName(PERMISSION_EDIT_USERS, locale), PermissionType.valueOf(PERMISSION_EDIT_USERS).name()));
194         permissions.add(4, new NameValuePair(getPermissionName(PERMISSION_EDIT_FULL, locale), PermissionType.valueOf(PERMISSION_EDIT_FULL).name()));
195         permissions.add(5, new NameValuePair(getPermissionName(PERMISSION_CLOSE, locale), PermissionType.valueOf(PERMISSION_CLOSE).name()));
196         permissions.add(6, new NameValuePair(getPermissionName(PERMISSION_ASSIGNABLE, locale), PermissionType.valueOf(PERMISSION_ASSIGNABLE).name()));
197         permissions.add(7, new NameValuePair(getPermissionName(PERMISSION_ASSIGN_SELF, locale), PermissionType.valueOf(PERMISSION_ASSIGN_SELF).name()));
198         permissions.add(8, new NameValuePair(getPermissionName(PERMISSION_UNASSIGN_SELF, locale), PermissionType.valueOf(PERMISSION_UNASSIGN_SELF).name()));
199         permissions.add(9, new NameValuePair(getPermissionName(PERMISSION_ASSIGN_OTHERS, locale), PermissionType.valueOf(PERMISSION_ASSIGN_OTHERS).name()));
200         permissions.add(10, new NameValuePair(getPermissionName(PERMISSION_VIEW_ALL, locale), PermissionType.valueOf(PERMISSION_VIEW_ALL).name()));
201         permissions.add(11, new NameValuePair(getPermissionName(PERMISSION_VIEW_USERS, locale), PermissionType.valueOf(PERMISSION_VIEW_USERS).name()));
202         permissions.add(12, new NameValuePair(getPermissionName(PERMISSION_PRODUCT_ADMIN, locale), PermissionType.valueOf(PERMISSION_PRODUCT_ADMIN).name()));
203         return permissions;
204     }
205 
206     /**
207      * Genrates a new random password.  The password that is returned is in plain text.
208      *
209      * @return a new randon plaintext password
210      */
211     public static String generatePassword() throws PasswordException {
212         StringBuffer buf = new StringBuffer();
213         Random rand = new Random();
214         for (int i = 0; i < 8; i++) {
215             buf.append((rand.nextInt(2) == 0 ? Character.toUpperCase(alphabet[rand.nextInt(34)]) : alphabet[rand.nextInt(34)]));
216         }
217         return buf.toString();
218     }
219 
220     /**
221      * Returns an encrypted (digest) password from a plain text password.
222      *
223      * @param password the plain text password to encrypt.
224      * @return the encrypted password
225      */
226     public static String encryptPassword(String password) throws PasswordException {
227         String hash = null;
228         if (password != null && !password.equals("")) {
229             try {
230                 MessageDigest md = MessageDigest.getInstance("SHA");
231                 md.update(password.getBytes("UTF-8"));
232                 byte raw[] = md.digest();
233                 // TODO: must we really use this BASE64Encoder()? it seems to be not support by jrockit rt.jar
234 //                hash = Base64.encodeBytes(raw);
235                 hash = String.valueOf(Base64Coder.encode(raw));
236 //                hash = (new BASE64Encoder()).encode(raw);
237             } catch (NoSuchAlgorithmException nsae) {
238                 throw new PasswordException(PasswordException.SYSTEM_ERROR);
239             } catch (UnsupportedEncodingException uee) {
240                 throw new PasswordException(PasswordException.SYSTEM_ERROR);
241             }
242         }
243         return hash;
244     }
245 
246 
247     /**
248      * Checks to see if the user is a super user.
249      *
250      * @param permissionsMap map of user permissions by project Id
251      * @return true is the user is a super user
252      */
253     @Deprecated
254     public static boolean isSuperUser(Map<Integer, Set<PermissionType>> permissionsMap) {
255         if (permissionsMap == null) {
256             return false;
257         }
258 
259         // Super user has access to all projects, which is indicated by null. 
260         final Set<PermissionType> permissionTypes = permissionsMap.get(null);
261 
262         return (permissionTypes != null) && permissionTypes.contains(PermissionType.USER_ADMIN);
263     }
264 
265     @Deprecated
266     public static boolean hasPermission(Map<Integer, Set<PermissionType>> permissionsMap, int permissionNeeded) {
267         return hasPermission(permissionsMap, PermissionType.valueOf(permissionNeeded));
268     }
269 
270     /**
271      * Returns true if the user has the required permission in any project.
272      *
273      * @param permissionsMap   a Map of the user's permissions by project ID
274      * @param permissionNeeded the permission to check for
275      */
276     @Deprecated
277     public static boolean hasPermission(Map<Integer, Set<PermissionType>> permissionsMap, PermissionType permissionNeeded) {
278         if (permissionsMap == null) {
279             return false;
280         }
281 
282         if (isSuperUser(permissionsMap)) {
283             return true;
284         }
285 
286         // Set of project Ids for which the user has permissions. 
287         Set<Integer> keySet = permissionsMap.keySet();
288 
289         for (Iterator<Integer> iterator = keySet.iterator(); iterator.hasNext(); ) {
290             Integer projectId = iterator.next();
291             if (hasPermission(permissionsMap, projectId, permissionNeeded)) {
292                 return true;
293             }
294         }
295         return false;
296     }
297 
298     /**
299      * Returns true if the user has any of required permissions in any project.
300      *
301      * @param permissionsMap    a HashMap of the user's permissions
302      * @param permissionsNeeded a list of permissions that can fulfill the permission check
303      */
304     @Deprecated
305     public static boolean hasPermission(Map<Integer, Set<PermissionType>> permissionsMap, PermissionType[] permissionsNeeded) {
306         if (permissionsMap == null) {
307             return false;
308         }
309 
310         if (isSuperUser(permissionsMap)) {
311             return true;
312         }
313 
314         Set<Integer> keySet = permissionsMap.keySet();
315 
316         for (Iterator<Integer> iterator = keySet.iterator(); iterator.hasNext(); ) {
317             Integer projectId = iterator.next();
318 
319             if (hasPermission(permissionsMap, projectId, permissionsNeeded)) {
320                 return true;
321             }
322         }
323         return false;
324     }
325 
326     @Deprecated
327     public static boolean hasPermission(Map<Integer, Set<PermissionType>> permissionsMap, Integer projectId, int permissionNeeded) {
328         return hasPermission(permissionsMap, projectId, PermissionType.valueOf(permissionNeeded));
329     }
330     /**
331      * Returns true if the user has the required permission for the given project.
332      *
333      * @param permissionsMap   a HashMap of the user's permissions
334      * @param projectId        the project that the permission is required for
335      * @param permissionNeeded the permission to check for
336      */
337     public static boolean hasPermission(Map<Integer, Set<PermissionType>> permissionsMap, Integer projectId, PermissionType permissionNeeded) {
338         if (permissionsMap == null) {
339             return false;
340         }
341 
342         if (isSuperUser(permissionsMap)) {
343             return true;
344         }
345 
346         final Set<PermissionType> permissionTypes = permissionsMap.get(projectId);
347 
348         if ((permissionTypes != null) && permissionTypes.contains(permissionNeeded)) {
349             return true;
350         } else {
351             return false;
352         }
353     }
354 
355     /**
356      * Returns true if the user has any of required permissions for the given project.
357      *
358      * @param permissionsMap    a HashMap of the user's permissions
359      * @param projectId         the project that the permission is required for
360      * @param permissionsNeeded a list of permissions that can fulfill the permission check
361      */
362     public static boolean hasPermission(Map<Integer, Set<PermissionType>> permissionsMap, Integer projectId, PermissionType[] permissionsNeeded) {
363         if (permissionsMap == null) {
364             return false;
365         }
366 
367         if (isSuperUser(permissionsMap)) {
368             return true;
369         }
370 
371         final Set<PermissionType> permissionTypes = permissionsMap.get(projectId);
372 
373         if (permissionTypes != null) {
374             for (int i = 0; i < permissionsNeeded.length; i++) {
375                 if (permissionTypes.contains(permissionsNeeded[i])) {
376                     return true;
377                 }
378             }
379         }
380         return false;
381     }
382 
383     public static String getInitial(String name) {
384         return (name != null && name.length() > 0 ? name.substring(0, 1).toUpperCase() + "." : "");
385     }
386 
387     public static Permission[] createPermissionArray(User user, Project project, int[] permissions) {
388         Permissionn">Permission[] permissionsArray = new Permission[0];
389 
390         List<Permission> permissionsList = new ArrayList<Permission>();
391 
392         if (user.isSuperUser()) {
393             permissionsList.add(new Permission(PermissionType.valueOf(-1), user, (Project) null));
394         }
395 
396         for (int i = 0; i < permissions.length; i++) {
397             permissionsList.add(new Permission(PermissionType.valueOf(permissions[i]), user, project));
398         }
399         permissionsArray = new Permission[permissionsList.size()];
400         permissionsArray = permissionsList.toArray(new Permission[]{});
401 
402         return permissionsArray;
403     }
404 
405     /**
406      * Maps sets of permission types by project ID.
407      */
408     public static Map<Integer, Set<PermissionType>> mapPermissionTypesByProjectId(
409             List<Permission> permissionsList) {
410 
411         final Map<Integer, Set<PermissionType>> permissionsByProjectId =
412                 new HashMap<Integer, Set<PermissionType>>();
413 
414         for (int i = 0; i < permissionsList.size(); i++) {
415             Permission permission = permissionsList.get(i);
416 
417             // Super user has access to all projects, which is indicated by the "null" project. 
418             final Integer projectId = (permission.getProject() == null)
419                     ? null : permission.getProject().getId();
420 
421             Set<PermissionType> projectPermissions = permissionsByProjectId.get(projectId);
422 
423             if (projectPermissions == null) {
424                 // First permission for the project. 
425                 projectPermissions = new HashSet<PermissionType>();
426                 permissionsByProjectId.put(projectId, projectPermissions);
427             } //else { // Add the permission to the existing set of permissions for the project. }
428 
429             PermissionType permissionType = permission.getPermissionType();
430             projectPermissions.add(permissionType);
431         }
432         return permissionsByProjectId;
433     }
434 
435     /**
436      * Returns whether the user is currently hiding a particular section on the myItracker page.
437      *
438      * @param section  the section to check if it is hidden
439      * @param sections an integer of all sections the user is hiding
440      * @return true if the current section is hidden
441      */
442     public static boolean hideIndexSection(int section, int sections) {
443         return ((section & sections) == section);
444     }
445 
446     public static Integer[] getHiddenIndexSections(int sections) {
447         List<Integer> sectionsList = new ArrayList<Integer>();
448         if (hideIndexSection(PREF_HIDE_ASSIGNED, sections)) {
449             sectionsList.add(Integer.valueOf(PREF_HIDE_ASSIGNED));
450         }
451         if (hideIndexSection(PREF_HIDE_UNASSIGNED, sections)) {
452             sectionsList.add(Integer.valueOf(PREF_HIDE_UNASSIGNED));
453         }
454         if (hideIndexSection(PREF_HIDE_CREATED, sections)) {
455             sectionsList.add(Integer.valueOf(PREF_HIDE_CREATED));
456         }
457         if (hideIndexSection(PREF_HIDE_WATCHED, sections)) {
458             sectionsList.add(Integer.valueOf(PREF_HIDE_WATCHED));
459         }
460         Integer[] sectionsArray = new Integer[sectionsList.size()];
461         sectionsList.toArray(sectionsArray);
462 
463         return sectionsArray;
464     }
465 
466 }