]> source.dussan.org Git - gitblit.git/commitdiff
Remove obsolete and deprecated FileUserService
authorJames Moger <james.moger@gitblit.com>
Fri, 6 Sep 2013 22:14:51 +0000 (18:14 -0400)
committerJames Moger <james.moger@gitblit.com>
Tue, 17 Sep 2013 21:13:54 +0000 (17:13 -0400)
Change-Id: I92d1d742e286643e1e1ab47a410b3fda146d1741

src/main/java/com/gitblit/FileUserService.java [deleted file]
src/main/java/com/gitblit/GitblitUserService.java
src/test/java/com/gitblit/tests/UserServiceTest.java

diff --git a/src/main/java/com/gitblit/FileUserService.java b/src/main/java/com/gitblit/FileUserService.java
deleted file mode 100644 (file)
index 32c24cc..0000000
+++ /dev/null
@@ -1,1146 +0,0 @@
-/*\r
- * Copyright 2011 gitblit.com.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package com.gitblit;\r
-\r
-import java.io.File;\r
-import java.io.FileWriter;\r
-import java.io.IOException;\r
-import java.text.MessageFormat;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Properties;\r
-import java.util.Set;\r
-import java.util.concurrent.ConcurrentHashMap;\r
-\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-import com.gitblit.Constants.AccessPermission;\r
-import com.gitblit.models.TeamModel;\r
-import com.gitblit.models.UserModel;\r
-import com.gitblit.utils.ArrayUtils;\r
-import com.gitblit.utils.DeepCopier;\r
-import com.gitblit.utils.StringUtils;\r
-\r
-/**\r
- * FileUserService is Gitblit's original default user service implementation.\r
- * \r
- * Users and their repository memberships are stored in a simple properties file\r
- * which is cached and dynamically reloaded when modified.\r
- * \r
- * This class was deprecated in Gitblit 0.8.0 in favor of ConfigUserService\r
- * which is still a human-readable, editable, plain-text file but it is more\r
- * flexible for storing additional fields.\r
- * \r
- * @author James Moger\r
- * \r
- */\r
-@Deprecated\r
-public class FileUserService extends FileSettings implements IUserService {\r
-\r
-       private final Logger logger = LoggerFactory.getLogger(FileUserService.class);\r
-\r
-       private final Map<String, String> cookies = new ConcurrentHashMap<String, String>();\r
-\r
-       private final Map<String, TeamModel> teams = new ConcurrentHashMap<String, TeamModel>();\r
-\r
-       public FileUserService(File realmFile) {\r
-               super(realmFile.getAbsolutePath());\r
-       }\r
-\r
-       /**\r
-        * Setup the user service.\r
-        * \r
-        * @param settings\r
-        * @since 0.7.0\r
-        */\r
-       @Override\r
-       public void setup(IStoredSettings settings) {\r
-       }\r
-\r
-       /**\r
-        * Does the user service support changes to credentials?\r
-        * \r
-        * @return true or false\r
-        * @since 1.0.0\r
-        */\r
-       @Override\r
-       public boolean supportsCredentialChanges() {\r
-               return true;\r
-       }\r
-\r
-       /**\r
-        * Does the user service support changes to user display name?\r
-        * \r
-        * @return true or false\r
-        * @since 1.0.0\r
-        */\r
-       @Override\r
-       public boolean supportsDisplayNameChanges() {\r
-               return false;\r
-       }\r
-\r
-       /**\r
-        * Does the user service support changes to user email address?\r
-        * \r
-        * @return true or false\r
-        * @since 1.0.0\r
-        */\r
-       @Override\r
-       public boolean supportsEmailAddressChanges() {\r
-               return false;\r
-       }\r
-\r
-       /**\r
-        * Does the user service support changes to team memberships?\r
-        * \r
-        * @return true or false\r
-        * @since 1.0.0\r
-        */     \r
-       public boolean supportsTeamMembershipChanges() {\r
-               return true;\r
-       }\r
-\r
-       /**\r
-        * Does the user service support cookie authentication?\r
-        * \r
-        * @return true or false\r
-        */\r
-       @Override\r
-       public boolean supportsCookies() {\r
-               return true;\r
-       }\r
-\r
-       /**\r
-        * Returns the cookie value for the specified user.\r
-        * \r
-        * @param model\r
-        * @return cookie value\r
-        */\r
-       @Override\r
-       public String getCookie(UserModel model) {\r
-               if (!StringUtils.isEmpty(model.cookie)) {\r
-                       return model.cookie;\r
-               }\r
-               Properties allUsers = super.read();\r
-               String value = allUsers.getProperty(model.username);\r
-               String[] roles = value.split(",");\r
-               String password = roles[0];\r
-               String cookie = StringUtils.getSHA1(model.username + password);\r
-               return cookie;\r
-       }\r
-\r
-       /**\r
-        * Authenticate a user based on their cookie.\r
-        * \r
-        * @param cookie\r
-        * @return a user object or null\r
-        */\r
-       @Override\r
-       public UserModel authenticate(char[] cookie) {\r
-               String hash = new String(cookie);\r
-               if (StringUtils.isEmpty(hash)) {\r
-                       return null;\r
-               }\r
-               read();\r
-               UserModel model = null;\r
-               if (cookies.containsKey(hash)) {\r
-                       String username = cookies.get(hash);\r
-                       model = getUserModel(username);\r
-               }\r
-               return model;\r
-       }\r
-\r
-       /**\r
-        * Authenticate a user based on a username and password.\r
-        * \r
-        * @param username\r
-        * @param password\r
-        * @return a user object or null\r
-        */\r
-       @Override\r
-       public UserModel authenticate(String username, char[] password) {\r
-               Properties allUsers = read();\r
-               String userInfo = allUsers.getProperty(username);\r
-               if (StringUtils.isEmpty(userInfo)) {\r
-                       return null;\r
-               }\r
-               UserModel returnedUser = null;\r
-               UserModel user = getUserModel(username);\r
-               if (user.password.startsWith(StringUtils.MD5_TYPE)) {\r
-                       // password digest\r
-                       String md5 = StringUtils.MD5_TYPE + StringUtils.getMD5(new String(password));\r
-                       if (user.password.equalsIgnoreCase(md5)) {\r
-                               returnedUser = user;\r
-                       }\r
-               } else if (user.password.startsWith(StringUtils.COMBINED_MD5_TYPE)) {\r
-                       // username+password digest\r
-                       String md5 = StringUtils.COMBINED_MD5_TYPE\r
-                                       + StringUtils.getMD5(username.toLowerCase() + new String(password));\r
-                       if (user.password.equalsIgnoreCase(md5)) {\r
-                               returnedUser = user;\r
-                       }\r
-               } else if (user.password.equals(new String(password))) {\r
-                       // plain-text password\r
-                       returnedUser = user;\r
-               }\r
-               return returnedUser;\r
-       }\r
-\r
-       /**\r
-        * Logout a user.\r
-        * \r
-        * @param user\r
-        */\r
-       @Override\r
-       public void logout(UserModel user) {    \r
-       }\r
-\r
-       /**\r
-        * Retrieve the user object for the specified username.\r
-        * \r
-        * @param username\r
-        * @return a user object or null\r
-        */\r
-       @Override\r
-       public UserModel getUserModel(String username) {\r
-               Properties allUsers = read();\r
-               String userInfo = allUsers.getProperty(username.toLowerCase());\r
-               if (userInfo == null) {\r
-                       return null;\r
-               }\r
-               UserModel model = new UserModel(username.toLowerCase());\r
-               String[] userValues = userInfo.split(",");\r
-               model.password = userValues[0];\r
-               for (int i = 1; i < userValues.length; i++) {\r
-                       String role = userValues[i];\r
-                       switch (role.charAt(0)) {\r
-                       case '#':\r
-                               // Permissions\r
-                               if (role.equalsIgnoreCase(Constants.ADMIN_ROLE)) {\r
-                                       model.canAdmin = true;\r
-                               } else if (role.equalsIgnoreCase(Constants.FORK_ROLE)) {\r
-                                       model.canFork = true;\r
-                               } else if (role.equalsIgnoreCase(Constants.CREATE_ROLE)) {\r
-                                       model.canCreate = true;\r
-                               } else if (role.equalsIgnoreCase(Constants.NOT_FEDERATED_ROLE)) {\r
-                                       model.excludeFromFederation = true;\r
-                               }\r
-                               break;\r
-                       default:\r
-                               model.addRepositoryPermission(role);\r
-                       }\r
-               }\r
-               // set the teams for the user\r
-               for (TeamModel team : teams.values()) {\r
-                       if (team.hasUser(username)) {\r
-                               model.teams.add(DeepCopier.copy(team));\r
-                       }\r
-               }\r
-               return model;\r
-       }\r
-\r
-       /**\r
-        * Updates/writes a complete user object.\r
-        * \r
-        * @param model\r
-        * @return true if update is successful\r
-        */\r
-       @Override\r
-       public boolean updateUserModel(UserModel model) {\r
-               return updateUserModel(model.username, model);\r
-       }\r
-\r
-       /**\r
-        * Updates/writes all specified user objects.\r
-        * \r
-        * @param models a list of user models\r
-        * @return true if update is successful\r
-        * @since 1.2.0\r
-        */\r
-       @Override\r
-       public boolean updateUserModels(Collection<UserModel> models) {\r
-               try {                   \r
-                       Properties allUsers = read();\r
-                       for (UserModel model : models) {\r
-                               updateUserCache(allUsers, model.username, model);\r
-                       }\r
-                       write(allUsers);\r
-                       return true;\r
-               } catch (Throwable t) {\r
-                       logger.error(MessageFormat.format("Failed to update {0} user models!", models.size()),\r
-                                       t);\r
-               }\r
-               return false;\r
-       }\r
-\r
-       /**\r
-        * Updates/writes and replaces a complete user object keyed by username.\r
-        * This method allows for renaming a user.\r
-        * \r
-        * @param username\r
-        *            the old username\r
-        * @param model\r
-        *            the user object to use for username\r
-        * @return true if update is successful\r
-        */\r
-       @Override\r
-       public boolean updateUserModel(String username, UserModel model) {\r
-               try {                   \r
-                       Properties allUsers = read();\r
-                       updateUserCache(allUsers, username, model);\r
-                       write(allUsers);\r
-                       return true;\r
-               } catch (Throwable t) {\r
-                       logger.error(MessageFormat.format("Failed to update user model {0}!", model.username),\r
-                                       t);\r
-               }\r
-               return false;\r
-       }\r
-       \r
-       /**\r
-        * Updates/writes and replaces a complete user object keyed by username.\r
-        * This method allows for renaming a user.\r
-        * \r
-        * @param username\r
-        *            the old username\r
-        * @param model\r
-        *            the user object to use for username\r
-        * @return true if update is successful\r
-        */\r
-       private boolean updateUserCache(Properties allUsers, String username, UserModel model) {\r
-               try {                   \r
-                       UserModel oldUser = getUserModel(username);\r
-                       List<String> roles;\r
-                       if (model.permissions == null) {\r
-                               roles = new ArrayList<String>();\r
-                       } else {\r
-                               // discrete repository permissions\r
-                               roles = new ArrayList<String>();\r
-                               for (Map.Entry<String, AccessPermission> entry : model.permissions.entrySet()) {\r
-                                       if (entry.getValue().exceeds(AccessPermission.NONE)) {\r
-                                               // code:repository (e.g. RW+:~james/myrepo.git\r
-                                               roles.add(entry.getValue().asRole(entry.getKey()));\r
-                                       }\r
-                               }\r
-                       }\r
-\r
-                       // Permissions\r
-                       if (model.canAdmin) {\r
-                               roles.add(Constants.ADMIN_ROLE);\r
-                       }\r
-                       if (model.canFork) {\r
-                               roles.add(Constants.FORK_ROLE);\r
-                       }\r
-                       if (model.canCreate) {\r
-                               roles.add(Constants.CREATE_ROLE);\r
-                       }\r
-                       if (model.excludeFromFederation) {\r
-                               roles.add(Constants.NOT_FEDERATED_ROLE);\r
-                       }\r
-\r
-                       StringBuilder sb = new StringBuilder();\r
-                       if (!StringUtils.isEmpty(model.password)) {\r
-                               sb.append(model.password);\r
-                       }\r
-                       sb.append(',');\r
-                       for (String role : roles) {\r
-                               sb.append(role);\r
-                               sb.append(',');\r
-                       }\r
-                       // trim trailing comma\r
-                       sb.setLength(sb.length() - 1);\r
-                       allUsers.remove(username.toLowerCase());\r
-                       allUsers.put(model.username.toLowerCase(), sb.toString());\r
-\r
-                       // null check on "final" teams because JSON-sourced UserModel\r
-                       // can have a null teams object\r
-                       if (model.teams != null) {\r
-                               // update team cache\r
-                               for (TeamModel team : model.teams) {\r
-                                       TeamModel t = getTeamModel(team.name);\r
-                                       if (t == null) {\r
-                                               // new team\r
-                                               t = team;\r
-                                       }\r
-                                       t.removeUser(username);\r
-                                       t.addUser(model.username);\r
-                                       updateTeamCache(allUsers, t.name, t);\r
-                               }\r
-\r
-                               // check for implicit team removal\r
-                               if (oldUser != null) {\r
-                                       for (TeamModel team : oldUser.teams) {\r
-                                               if (!model.isTeamMember(team.name)) {\r
-                                                       team.removeUser(username);\r
-                                                       updateTeamCache(allUsers, team.name, team);\r
-                                               }\r
-                                       }\r
-                               }\r
-                       }\r
-                       return true;\r
-               } catch (Throwable t) {\r
-                       logger.error(MessageFormat.format("Failed to update user model {0}!", model.username),\r
-                                       t);\r
-               }\r
-               return false;\r
-       }\r
-\r
-       /**\r
-        * Deletes the user object from the user service.\r
-        * \r
-        * @param model\r
-        * @return true if successful\r
-        */\r
-       @Override\r
-       public boolean deleteUserModel(UserModel model) {\r
-               return deleteUser(model.username);\r
-       }\r
-\r
-       /**\r
-        * Delete the user object with the specified username\r
-        * \r
-        * @param username\r
-        * @return true if successful\r
-        */\r
-       @Override\r
-       public boolean deleteUser(String username) {\r
-               try {\r
-                       // Read realm file\r
-                       Properties allUsers = read();\r
-                       UserModel user = getUserModel(username);\r
-                       allUsers.remove(username);\r
-                       for (TeamModel team : user.teams) {\r
-                               TeamModel t = getTeamModel(team.name);\r
-                               if (t == null) {\r
-                                       // new team\r
-                                       t = team;\r
-                               }\r
-                               t.removeUser(username);\r
-                               updateTeamCache(allUsers, t.name, t);\r
-                       }\r
-                       write(allUsers);\r
-                       return true;\r
-               } catch (Throwable t) {\r
-                       logger.error(MessageFormat.format("Failed to delete user {0}!", username), t);\r
-               }\r
-               return false;\r
-       }\r
-\r
-       /**\r
-        * Returns the list of all users available to the login service.\r
-        * \r
-        * @return list of all usernames\r
-        */\r
-       @Override\r
-       public List<String> getAllUsernames() {\r
-               Properties allUsers = read();\r
-               List<String> list = new ArrayList<String>();\r
-               for (String user : allUsers.stringPropertyNames()) {\r
-                       if (user.charAt(0) == '@') {\r
-                               // skip team user definitions\r
-                               continue;\r
-                       }\r
-                       list.add(user);\r
-               }\r
-               Collections.sort(list);\r
-               return list;\r
-       }\r
-\r
-       /**\r
-        * Returns the list of all users available to the login service.\r
-        * \r
-        * @return list of all usernames\r
-        */\r
-       @Override\r
-       public List<UserModel> getAllUsers() {\r
-               read();\r
-               List<UserModel> list = new ArrayList<UserModel>();\r
-               for (String username : getAllUsernames()) {\r
-                       list.add(getUserModel(username));\r
-               }\r
-               Collections.sort(list);\r
-               return list;\r
-       }\r
-\r
-       /**\r
-        * Returns the list of all users who are allowed to bypass the access\r
-        * restriction placed on the specified repository.\r
-        * \r
-        * @param role\r
-        *            the repository name\r
-        * @return list of all usernames that can bypass the access restriction\r
-        */\r
-       @Override\r
-       public List<String> getUsernamesForRepositoryRole(String role) {\r
-               List<String> list = new ArrayList<String>();\r
-               try {\r
-                       Properties allUsers = read();\r
-                       for (String username : allUsers.stringPropertyNames()) {\r
-                               if (username.charAt(0) == '@') {\r
-                                       continue;\r
-                               }\r
-                               String value = allUsers.getProperty(username);\r
-                               String[] values = value.split(",");\r
-                               // skip first value (password)\r
-                               for (int i = 1; i < values.length; i++) {\r
-                                       String r = values[i];\r
-                                       if (r.equalsIgnoreCase(role)) {\r
-                                               list.add(username);\r
-                                               break;\r
-                                       }\r
-                               }\r
-                       }\r
-               } catch (Throwable t) {\r
-                       logger.error(MessageFormat.format("Failed to get usernames for role {0}!", role), t);\r
-               }\r
-               Collections.sort(list);\r
-               return list;\r
-       }\r
-\r
-       /**\r
-        * Sets the list of all users who are allowed to bypass the access\r
-        * restriction placed on the specified repository.\r
-        * \r
-        * @param role\r
-        *            the repository name\r
-        * @param usernames\r
-        * @return true if successful\r
-        */\r
-       @Override\r
-       public boolean setUsernamesForRepositoryRole(String role, List<String> usernames) {\r
-               try {\r
-                       Set<String> specifiedUsers = new HashSet<String>(usernames);\r
-                       Set<String> needsAddRole = new HashSet<String>(specifiedUsers);\r
-                       Set<String> needsRemoveRole = new HashSet<String>();\r
-\r
-                       // identify users which require add and remove role\r
-                       Properties allUsers = read();\r
-                       for (String username : allUsers.stringPropertyNames()) {\r
-                               String value = allUsers.getProperty(username);\r
-                               String[] values = value.split(",");\r
-                               // skip first value (password)\r
-                               for (int i = 1; i < values.length; i++) {\r
-                                       String r = values[i];\r
-                                       if (r.equalsIgnoreCase(role)) {\r
-                                               // user has role, check against revised user list\r
-                                               if (specifiedUsers.contains(username)) {\r
-                                                       needsAddRole.remove(username);\r
-                                               } else {\r
-                                                       // remove role from user\r
-                                                       needsRemoveRole.add(username);\r
-                                               }\r
-                                               break;\r
-                                       }\r
-                               }\r
-                       }\r
-\r
-                       // add roles to users\r
-                       for (String user : needsAddRole) {\r
-                               String userValues = allUsers.getProperty(user);\r
-                               userValues += "," + role;\r
-                               allUsers.put(user, userValues);\r
-                       }\r
-\r
-                       // remove role from user\r
-                       for (String user : needsRemoveRole) {\r
-                               String[] values = allUsers.getProperty(user).split(",");\r
-                               String password = values[0];\r
-                               StringBuilder sb = new StringBuilder();\r
-                               sb.append(password);\r
-                               sb.append(',');\r
-\r
-                               // skip first value (password)\r
-                               for (int i = 1; i < values.length; i++) {\r
-                                       String value = values[i];\r
-                                       if (!value.equalsIgnoreCase(role)) {\r
-                                               sb.append(value);\r
-                                               sb.append(',');\r
-                                       }\r
-                               }\r
-                               sb.setLength(sb.length() - 1);\r
-\r
-                               // update properties\r
-                               allUsers.put(user, sb.toString());\r
-                       }\r
-\r
-                       // persist changes\r
-                       write(allUsers);\r
-                       return true;\r
-               } catch (Throwable t) {\r
-                       logger.error(MessageFormat.format("Failed to set usernames for role {0}!", role), t);\r
-               }\r
-               return false;\r
-       }\r
-\r
-       /**\r
-        * Renames a repository role.\r
-        * \r
-        * @param oldRole\r
-        * @param newRole\r
-        * @return true if successful\r
-        */\r
-       @Override\r
-       public boolean renameRepositoryRole(String oldRole, String newRole) {\r
-               try {\r
-                       Properties allUsers = read();\r
-                       Set<String> needsRenameRole = new HashSet<String>();\r
-\r
-                       // identify users which require role rename\r
-                       for (String username : allUsers.stringPropertyNames()) {\r
-                               String value = allUsers.getProperty(username);\r
-                               String[] roles = value.split(",");\r
-                               // skip first value (password)\r
-                               for (int i = 1; i < roles.length; i++) {\r
-                                       String repository = AccessPermission.repositoryFromRole(roles[i]);\r
-                                       if (repository.equalsIgnoreCase(oldRole)) {\r
-                                               needsRenameRole.add(username);\r
-                                               break;\r
-                                       }\r
-                               }\r
-                       }\r
-\r
-                       // rename role for identified users\r
-                       for (String user : needsRenameRole) {\r
-                               String userValues = allUsers.getProperty(user);\r
-                               String[] values = userValues.split(",");\r
-                               String password = values[0];\r
-                               StringBuilder sb = new StringBuilder();\r
-                               sb.append(password);\r
-                               sb.append(',');\r
-                               sb.append(newRole);\r
-                               sb.append(',');\r
-\r
-                               // skip first value (password)\r
-                               for (int i = 1; i < values.length; i++) {\r
-                                       String repository = AccessPermission.repositoryFromRole(values[i]);\r
-                                       if (repository.equalsIgnoreCase(oldRole)) {\r
-                                               AccessPermission permission = AccessPermission.permissionFromRole(values[i]);\r
-                                               sb.append(permission.asRole(newRole));\r
-                                               sb.append(',');\r
-                                       } else {\r
-                                               sb.append(values[i]);\r
-                                               sb.append(',');\r
-                                       }\r
-                               }\r
-                               sb.setLength(sb.length() - 1);\r
-\r
-                               // update properties\r
-                               allUsers.put(user, sb.toString());\r
-                       }\r
-\r
-                       // persist changes\r
-                       write(allUsers);\r
-                       return true;\r
-               } catch (Throwable t) {\r
-                       logger.error(\r
-                                       MessageFormat.format("Failed to rename role {0} to {1}!", oldRole, newRole), t);\r
-               }\r
-               return false;\r
-       }\r
-\r
-       /**\r
-        * Removes a repository role from all users.\r
-        * \r
-        * @param role\r
-        * @return true if successful\r
-        */\r
-       @Override\r
-       public boolean deleteRepositoryRole(String role) {\r
-               try {\r
-                       Properties allUsers = read();\r
-                       Set<String> needsDeleteRole = new HashSet<String>();\r
-\r
-                       // identify users which require role rename\r
-                       for (String username : allUsers.stringPropertyNames()) {\r
-                               String value = allUsers.getProperty(username);\r
-                               String[] roles = value.split(",");\r
-                               // skip first value (password)\r
-                               for (int i = 1; i < roles.length; i++) {                                        \r
-                                       String repository = AccessPermission.repositoryFromRole(roles[i]);\r
-                                       if (repository.equalsIgnoreCase(role)) {\r
-                                               needsDeleteRole.add(username);\r
-                                               break;\r
-                                       }\r
-                               }\r
-                       }\r
-\r
-                       // delete role for identified users\r
-                       for (String user : needsDeleteRole) {\r
-                               String userValues = allUsers.getProperty(user);\r
-                               String[] values = userValues.split(",");\r
-                               String password = values[0];\r
-                               StringBuilder sb = new StringBuilder();\r
-                               sb.append(password);\r
-                               sb.append(',');\r
-                               // skip first value (password)\r
-                               for (int i = 1; i < values.length; i++) {                                       \r
-                                       String repository = AccessPermission.repositoryFromRole(values[i]);\r
-                                       if (!repository.equalsIgnoreCase(role)) {\r
-                                               sb.append(values[i]);\r
-                                               sb.append(',');\r
-                                       }\r
-                               }\r
-                               sb.setLength(sb.length() - 1);\r
-\r
-                               // update properties\r
-                               allUsers.put(user, sb.toString());\r
-                       }\r
-\r
-                       // persist changes\r
-                       write(allUsers);\r
-                       return true;\r
-               } catch (Throwable t) {\r
-                       logger.error(MessageFormat.format("Failed to delete role {0}!", role), t);\r
-               }\r
-               return false;\r
-       }\r
-\r
-       /**\r
-        * Writes the properties file.\r
-        * \r
-        * @param properties\r
-        * @throws IOException\r
-        */\r
-       private void write(Properties properties) throws IOException {\r
-               // Write a temporary copy of the users file\r
-               File realmFileCopy = new File(propertiesFile.getAbsolutePath() + ".tmp");\r
-               FileWriter writer = new FileWriter(realmFileCopy);\r
-               properties\r
-                               .store(writer,\r
-                                               " Gitblit realm file format:\n   username=password,\\#permission,repository1,repository2...\n   @teamname=!username1,!username2,!username3,repository1,repository2...");\r
-               writer.close();\r
-               // If the write is successful, delete the current file and rename\r
-               // the temporary copy to the original filename.\r
-               if (realmFileCopy.exists() && realmFileCopy.length() > 0) {\r
-                       if (propertiesFile.exists()) {\r
-                               if (!propertiesFile.delete()) {\r
-                                       throw new IOException(MessageFormat.format("Failed to delete {0}!",\r
-                                                       propertiesFile.getAbsolutePath()));\r
-                               }\r
-                       }\r
-                       if (!realmFileCopy.renameTo(propertiesFile)) {\r
-                               throw new IOException(MessageFormat.format("Failed to rename {0} to {1}!",\r
-                                               realmFileCopy.getAbsolutePath(), propertiesFile.getAbsolutePath()));\r
-                       }\r
-               } else {\r
-                       throw new IOException(MessageFormat.format("Failed to save {0}!",\r
-                                       realmFileCopy.getAbsolutePath()));\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Reads the properties file and rebuilds the in-memory cookie lookup table.\r
-        */\r
-       @Override\r
-       protected synchronized Properties read() {\r
-               long lastRead = lastModified();\r
-               boolean reload = forceReload();\r
-               Properties allUsers = super.read();\r
-               if (reload || (lastRead != lastModified())) {\r
-                       // reload hash cache\r
-                       cookies.clear();\r
-                       teams.clear();\r
-\r
-                       for (String username : allUsers.stringPropertyNames()) {\r
-                               String value = allUsers.getProperty(username);\r
-                               String[] roles = value.split(",");\r
-                               if (username.charAt(0) == '@') {\r
-                                       // team definition\r
-                                       TeamModel team = new TeamModel(username.substring(1));\r
-                                       List<String> repositories = new ArrayList<String>();\r
-                                       List<String> users = new ArrayList<String>();\r
-                                       List<String> mailingLists = new ArrayList<String>();\r
-                                       List<String> preReceive = new ArrayList<String>();\r
-                                       List<String> postReceive = new ArrayList<String>();\r
-                                       for (String role : roles) {\r
-                                               if (role.charAt(0) == '!') {\r
-                                                       users.add(role.substring(1));\r
-                                               } else if (role.charAt(0) == '&') {\r
-                                                       mailingLists.add(role.substring(1));\r
-                                               } else if (role.charAt(0) == '^') {\r
-                                                       preReceive.add(role.substring(1));\r
-                                               } else if (role.charAt(0) == '%') {\r
-                                                       postReceive.add(role.substring(1));\r
-                                               } else {\r
-                                                       switch (role.charAt(0)) {\r
-                                                       case '#':\r
-                                                               // Permissions\r
-                                                               if (role.equalsIgnoreCase(Constants.ADMIN_ROLE)) {\r
-                                                                       team.canAdmin = true;\r
-                                                               } else if (role.equalsIgnoreCase(Constants.FORK_ROLE)) {\r
-                                                                       team.canFork = true;\r
-                                                               } else if (role.equalsIgnoreCase(Constants.CREATE_ROLE)) {\r
-                                                                       team.canCreate = true;\r
-                                                               }\r
-                                                               break;\r
-                                                       default:\r
-                                                               repositories.add(role);\r
-                                                       }\r
-                                                       repositories.add(role);\r
-                                               }\r
-                                       }\r
-                                       if (!team.canAdmin) {\r
-                                               // only read permissions for non-admin teams\r
-                                               team.addRepositoryPermissions(repositories);\r
-                                       }\r
-                                       team.addUsers(users);\r
-                                       team.addMailingLists(mailingLists);\r
-                                       team.preReceiveScripts.addAll(preReceive);\r
-                                       team.postReceiveScripts.addAll(postReceive);\r
-                                       teams.put(team.name.toLowerCase(), team);\r
-                               } else {\r
-                                       // user definition\r
-                                       String password = roles[0];\r
-                                       cookies.put(StringUtils.getSHA1(username.toLowerCase() + password), username.toLowerCase());\r
-                               }\r
-                       }\r
-               }\r
-               return allUsers;\r
-       }\r
-\r
-       @Override\r
-       public String toString() {\r
-               return getClass().getSimpleName() + "(" + propertiesFile.getAbsolutePath() + ")";\r
-       }\r
-\r
-       /**\r
-        * Returns the list of all teams available to the login service.\r
-        * \r
-        * @return list of all teams\r
-        * @since 0.8.0\r
-        */\r
-       @Override\r
-       public List<String> getAllTeamNames() {\r
-               List<String> list = new ArrayList<String>(teams.keySet());\r
-               Collections.sort(list);\r
-               return list;\r
-       }\r
-\r
-       /**\r
-        * Returns the list of all teams available to the login service.\r
-        * \r
-        * @return list of all teams\r
-        * @since 0.8.0\r
-        */\r
-       @Override\r
-       public List<TeamModel> getAllTeams() {\r
-               List<TeamModel> list = new ArrayList<TeamModel>(teams.values());\r
-               list = DeepCopier.copy(list);\r
-               Collections.sort(list);\r
-               return list;\r
-       }\r
-\r
-       /**\r
-        * Returns the list of all teams who are allowed to bypass the access\r
-        * restriction placed on the specified repository.\r
-        * \r
-        * @param role\r
-        *            the repository name\r
-        * @return list of all teamnames that can bypass the access restriction\r
-        */\r
-       @Override\r
-       public List<String> getTeamnamesForRepositoryRole(String role) {\r
-               List<String> list = new ArrayList<String>();\r
-               try {\r
-                       Properties allUsers = read();\r
-                       for (String team : allUsers.stringPropertyNames()) {\r
-                               if (team.charAt(0) != '@') {\r
-                                       // skip users\r
-                                       continue;\r
-                               }\r
-                               String value = allUsers.getProperty(team);\r
-                               String[] values = value.split(",");\r
-                               for (int i = 0; i < values.length; i++) {\r
-                                       String r = values[i];\r
-                                       if (r.equalsIgnoreCase(role)) {\r
-                                               // strip leading @\r
-                                               list.add(team.substring(1));\r
-                                               break;\r
-                                       }\r
-                               }\r
-                       }\r
-               } catch (Throwable t) {\r
-                       logger.error(MessageFormat.format("Failed to get teamnames for role {0}!", role), t);\r
-               }\r
-               Collections.sort(list);\r
-               return list;\r
-       }\r
-\r
-       /**\r
-        * Sets the list of all teams who are allowed to bypass the access\r
-        * restriction placed on the specified repository.\r
-        * \r
-        * @param role\r
-        *            the repository name\r
-        * @param teamnames\r
-        * @return true if successful\r
-        */\r
-       @Override\r
-       public boolean setTeamnamesForRepositoryRole(String role, List<String> teamnames) {\r
-               try {\r
-                       Set<String> specifiedTeams = new HashSet<String>(teamnames);\r
-                       Set<String> needsAddRole = new HashSet<String>(specifiedTeams);\r
-                       Set<String> needsRemoveRole = new HashSet<String>();\r
-\r
-                       // identify teams which require add and remove role\r
-                       Properties allUsers = read();\r
-                       for (String team : allUsers.stringPropertyNames()) {\r
-                               if (team.charAt(0) != '@') {\r
-                                       // skip users\r
-                                       continue;\r
-                               }\r
-                               String name = team.substring(1);\r
-                               String value = allUsers.getProperty(team);\r
-                               String[] values = value.split(",");\r
-                               for (int i = 0; i < values.length; i++) {\r
-                                       String r = values[i];\r
-                                       if (r.equalsIgnoreCase(role)) {\r
-                                               // team has role, check against revised team list\r
-                                               if (specifiedTeams.contains(name)) {\r
-                                                       needsAddRole.remove(name);\r
-                                               } else {\r
-                                                       // remove role from team\r
-                                                       needsRemoveRole.add(name);\r
-                                               }\r
-                                               break;\r
-                                       }\r
-                               }\r
-                       }\r
-\r
-                       // add roles to teams\r
-                       for (String name : needsAddRole) {\r
-                               String team = "@" + name;\r
-                               String teamValues = allUsers.getProperty(team);\r
-                               teamValues += "," + role;\r
-                               allUsers.put(team, teamValues);\r
-                       }\r
-\r
-                       // remove role from team\r
-                       for (String name : needsRemoveRole) {\r
-                               String team = "@" + name;\r
-                               String[] values = allUsers.getProperty(team).split(",");\r
-                               StringBuilder sb = new StringBuilder();\r
-                               for (int i = 0; i < values.length; i++) {\r
-                                       String value = values[i];\r
-                                       if (!value.equalsIgnoreCase(role)) {\r
-                                               sb.append(value);\r
-                                               sb.append(',');\r
-                                       }\r
-                               }\r
-                               sb.setLength(sb.length() - 1);\r
-\r
-                               // update properties\r
-                               allUsers.put(team, sb.toString());\r
-                       }\r
-\r
-                       // persist changes\r
-                       write(allUsers);\r
-                       return true;\r
-               } catch (Throwable t) {\r
-                       logger.error(MessageFormat.format("Failed to set teamnames for role {0}!", role), t);\r
-               }\r
-               return false;\r
-       }\r
-\r
-       /**\r
-        * Retrieve the team object for the specified team name.\r
-        * \r
-        * @param teamname\r
-        * @return a team object or null\r
-        * @since 0.8.0\r
-        */\r
-       @Override\r
-       public TeamModel getTeamModel(String teamname) {\r
-               read();\r
-               TeamModel team = teams.get(teamname.toLowerCase());\r
-               if (team != null) {\r
-                       // clone the model, otherwise all changes to this object are\r
-                       // live and unpersisted\r
-                       team = DeepCopier.copy(team);\r
-               }\r
-               return team;\r
-       }\r
-\r
-       /**\r
-        * Updates/writes a complete team object.\r
-        * \r
-        * @param model\r
-        * @return true if update is successful\r
-        * @since 0.8.0\r
-        */\r
-       @Override\r
-       public boolean updateTeamModel(TeamModel model) {\r
-               return updateTeamModel(model.name, model);\r
-       }\r
-       \r
-       /**\r
-        * Updates/writes all specified team objects.\r
-        * \r
-        * @param models a list of team models\r
-        * @return true if update is successful\r
-        * @since 1.2.0\r
-        */\r
-       public boolean updateTeamModels(Collection<TeamModel> models) {\r
-               try {\r
-                       Properties allUsers = read();\r
-                       for (TeamModel model : models) {\r
-                               updateTeamCache(allUsers, model.name, model);\r
-                       }\r
-                       write(allUsers);\r
-                       return true;\r
-               } catch (Throwable t) {\r
-                       logger.error(MessageFormat.format("Failed to update {0} team models!", models.size()), t);\r
-               }\r
-               return false;\r
-       }\r
-\r
-       /**\r
-        * Updates/writes and replaces a complete team object keyed by teamname.\r
-        * This method allows for renaming a team.\r
-        * \r
-        * @param teamname\r
-        *            the old teamname\r
-        * @param model\r
-        *            the team object to use for teamname\r
-        * @return true if update is successful\r
-        * @since 0.8.0\r
-        */\r
-       @Override\r
-       public boolean updateTeamModel(String teamname, TeamModel model) {\r
-               try {\r
-                       Properties allUsers = read();\r
-                       updateTeamCache(allUsers, teamname, model);\r
-                       write(allUsers);\r
-                       return true;\r
-               } catch (Throwable t) {\r
-                       logger.error(MessageFormat.format("Failed to update team model {0}!", model.name), t);\r
-               }\r
-               return false;\r
-       }\r
-\r
-       private void updateTeamCache(Properties allUsers, String teamname, TeamModel model) {\r
-               StringBuilder sb = new StringBuilder();\r
-               List<String> roles;\r
-               if (model.permissions == null) {\r
-                       // legacy, use repository list\r
-                       if (model.repositories != null) {\r
-                               roles = new ArrayList<String>(model.repositories);\r
-                       } else {\r
-                               roles = new ArrayList<String>();\r
-                       }\r
-               } else {\r
-                       // discrete repository permissions\r
-                       roles = new ArrayList<String>();\r
-                       for (Map.Entry<String, AccessPermission> entry : model.permissions.entrySet()) {\r
-                               if (entry.getValue().exceeds(AccessPermission.NONE)) {\r
-                                       // code:repository (e.g. RW+:~james/myrepo.git\r
-                                       roles.add(entry.getValue().asRole(entry.getKey()));\r
-                               }\r
-                       }\r
-               }\r
-               \r
-               // Permissions\r
-               if (model.canAdmin) {\r
-                       roles.add(Constants.ADMIN_ROLE);\r
-               }\r
-               if (model.canFork) {\r
-                       roles.add(Constants.FORK_ROLE);\r
-               }\r
-               if (model.canCreate) {\r
-                       roles.add(Constants.CREATE_ROLE);\r
-               }\r
-\r
-               for (String role : roles) {\r
-                               sb.append(role);\r
-                               sb.append(',');\r
-               }\r
-               \r
-               if (!ArrayUtils.isEmpty(model.users)) {\r
-                       for (String user : model.users) {\r
-                               sb.append('!');\r
-                               sb.append(user);\r
-                               sb.append(',');\r
-                       }\r
-               }\r
-               if (!ArrayUtils.isEmpty(model.mailingLists)) {\r
-                       for (String address : model.mailingLists) {\r
-                               sb.append('&');\r
-                               sb.append(address);\r
-                               sb.append(',');\r
-                       }\r
-               }\r
-               if (!ArrayUtils.isEmpty(model.preReceiveScripts)) {\r
-                       for (String script : model.preReceiveScripts) {\r
-                               sb.append('^');\r
-                               sb.append(script);\r
-                               sb.append(',');\r
-                       }\r
-               }\r
-               if (!ArrayUtils.isEmpty(model.postReceiveScripts)) {\r
-                       for (String script : model.postReceiveScripts) {\r
-                               sb.append('%');\r
-                               sb.append(script);\r
-                               sb.append(',');\r
-                       }\r
-               }\r
-               // trim trailing comma\r
-               sb.setLength(sb.length() - 1);\r
-               allUsers.remove("@" + teamname);\r
-               allUsers.put("@" + model.name, sb.toString());\r
-\r
-               // update team cache\r
-               teams.remove(teamname.toLowerCase());\r
-               teams.put(model.name.toLowerCase(), model);\r
-       }\r
-\r
-       /**\r
-        * Deletes the team object from the user service.\r
-        * \r
-        * @param model\r
-        * @return true if successful\r
-        * @since 0.8.0\r
-        */\r
-       @Override\r
-       public boolean deleteTeamModel(TeamModel model) {\r
-               return deleteTeam(model.name);\r
-       }\r
-\r
-       /**\r
-        * Delete the team object with the specified teamname\r
-        * \r
-        * @param teamname\r
-        * @return true if successful\r
-        * @since 0.8.0\r
-        */\r
-       @Override\r
-       public boolean deleteTeam(String teamname) {\r
-               Properties allUsers = read();\r
-               teams.remove(teamname.toLowerCase());\r
-               allUsers.remove("@" + teamname);\r
-               try {\r
-                       write(allUsers);\r
-                       return true;\r
-               } catch (Throwable t) {\r
-                       logger.error(MessageFormat.format("Failed to delete team {0}!", teamname), t);\r
-               }\r
-               return false;\r
-       }\r
-}\r
index 658404b5e7f883ef4884aa5ac0d02a9f78643dbc..677d63aefd9419692b206bbd98165607b1085062 100644 (file)
@@ -33,25 +33,25 @@ import com.gitblit.utils.StringUtils;
 /**\r
  * This class wraps the default user service and is recommended as the starting\r
  * point for custom user service implementations.\r
- * \r
+ *\r
  * This does seem a little convoluted, but the idea is to allow IUserService to\r
  * evolve with new methods and implementations without breaking custom\r
  * authentication implementations.\r
- * \r
+ *\r
  * The most common implementation of a custom IUserService is to only override\r
  * authentication and then delegate all other functionality to one of Gitblit's\r
  * user services. This class optimizes that use-case.\r
- * \r
+ *\r
  * Extending GitblitUserService allows for authentication customization without\r
  * having to keep-up-with IUSerService API changes.\r
- * \r
+ *\r
  * @author James Moger\r
- * \r
+ *\r
  */\r
 public class GitblitUserService implements IUserService {\r
 \r
        protected IUserService serviceImpl;\r
-       \r
+\r
        private final Logger logger = LoggerFactory.getLogger(GitblitUserService.class);\r
 \r
        public GitblitUserService() {\r
@@ -64,13 +64,9 @@ public class GitblitUserService implements IUserService {
                logger.info("GUS delegating to " + serviceImpl.toString());\r
        }\r
 \r
-       @SuppressWarnings("deprecation")\r
        protected IUserService createUserService(File realmFile) {\r
                IUserService service = null;\r
-               if (realmFile.getName().toLowerCase().endsWith(".properties")) {\r
-                       // v0.5.0 - v0.7.0 properties-based realm file\r
-                       service = new FileUserService(realmFile);\r
-               } else if (realmFile.getName().toLowerCase().endsWith(".conf")) {\r
+               if (realmFile.getName().toLowerCase().endsWith(".conf")) {\r
                        // v0.8.0+ config-based realm file\r
                        service = new ConfigUserService(realmFile);\r
                }\r
@@ -91,25 +87,9 @@ public class GitblitUserService implements IUserService {
                        service.updateUserModel(admin);\r
                }\r
 \r
-               if (service instanceof FileUserService) {\r
-                       // automatically create a users.conf realm file from the original\r
-                       // users.properties file\r
-                       File usersConfig = new File(realmFile.getParentFile(), "users.conf");\r
-                       if (!usersConfig.exists()) {\r
-                               logger.info(MessageFormat.format("Automatically creating {0} based on {1}",\r
-                                               usersConfig.getAbsolutePath(), realmFile.getAbsolutePath()));\r
-                               ConfigUserService configService = new ConfigUserService(usersConfig);\r
-                               for (String username : service.getAllUsernames()) {\r
-                                       UserModel userModel = service.getUserModel(username);\r
-                                       configService.updateUserModel(userModel);\r
-                               }\r
-                       }\r
-                       // issue suggestion about switching to users.conf\r
-                       logger.warn("Please consider using \"users.conf\" instead of the deprecated \"users.properties\" file");\r
-               }\r
                return service;\r
        }\r
-       \r
+\r
        @Override\r
        public String toString() {\r
                return getClass().getSimpleName();\r
@@ -158,7 +138,7 @@ public class GitblitUserService implements IUserService {
                setAccountType(user);\r
                return user;\r
        }\r
-       \r
+\r
        @Override\r
        public void logout(UserModel user) {\r
                serviceImpl.logout(user);\r
@@ -187,7 +167,7 @@ public class GitblitUserService implements IUserService {
                        if (!model.isLocalAccount() && !supportsTeamMembershipChanges()) {\r
                                //  teams are externally controlled - copy from original model\r
                                UserModel existingModel = getUserModel(username);\r
-                               \r
+\r
                                model = DeepCopier.copy(model);\r
                                model.teams.clear();\r
                                model.teams.addAll(existingModel.teams);\r
@@ -200,7 +180,7 @@ public class GitblitUserService implements IUserService {
                        if (!model.isLocalAccount() && !supportsTeamMembershipChanges()) {\r
                                //  teams are externally controlled- copy from original model\r
                                UserModel existingModel = getUserModel(username);\r
-                               \r
+\r
                                model = DeepCopier.copy(model);\r
                                model.teams.clear();\r
                                model.teams.addAll(existingModel.teams);\r
@@ -231,7 +211,7 @@ public class GitblitUserService implements IUserService {
        for (UserModel user : users) {\r
                setAccountType(user);\r
        }\r
-               return users; \r
+               return users;\r
        }\r
 \r
        @Override\r
@@ -275,7 +255,7 @@ public class GitblitUserService implements IUserService {
                if (!supportsTeamMembershipChanges()) {\r
                        // teams are externally controlled - copy from original model\r
                        TeamModel existingModel = getTeamModel(teamname);\r
-                       \r
+\r
                        model = DeepCopier.copy(model);\r
                        model.users.clear();\r
                        model.users.addAll(existingModel.users);\r
@@ -313,12 +293,12 @@ public class GitblitUserService implements IUserService {
        public boolean deleteRepositoryRole(String role) {\r
                return serviceImpl.deleteRepositoryRole(role);\r
        }\r
-       \r
+\r
        protected boolean isLocalAccount(String username) {\r
                UserModel user = getUserModel(username);\r
                return user != null && user.isLocalAccount();\r
        }\r
-       \r
+\r
        protected void setAccountType(UserModel user) {\r
                if (user != null) {\r
                        if (!StringUtils.isEmpty(user.password)\r
@@ -330,7 +310,7 @@ public class GitblitUserService implements IUserService {
                        }\r
                }\r
        }\r
-       \r
+\r
        protected AccountType getAccountType() {\r
                return AccountType.LOCAL;\r
        }\r
index 710d1f35b00b22834e35aa07c53cdd80b194fb3f..f6cdd6a336129418596f7f80bd1df7a0b466c409 100644 (file)
@@ -26,7 +26,6 @@ import org.junit.Test;
 \r
 import com.gitblit.ConfigUserService;\r
 import com.gitblit.Constants.AccessRestrictionType;\r
-import com.gitblit.FileUserService;\r
 import com.gitblit.IUserService;\r
 import com.gitblit.models.RepositoryModel;\r
 import com.gitblit.models.TeamModel;\r
@@ -34,16 +33,6 @@ import com.gitblit.models.UserModel;
 \r
 public class UserServiceTest {\r
 \r
-       @Test\r
-       public void testFileUserService() throws IOException {\r
-               File file = new File("us-test.properties");\r
-               file.delete();\r
-               IUserService service = new FileUserService(file);\r
-               testUsers(service);\r
-               testTeams(service);\r
-               file.delete();\r
-       }\r
-\r
        @Test\r
        public void testConfigUserService() throws IOException {\r
                File file = new File("us-test.conf");\r
@@ -62,13 +51,13 @@ public class UserServiceTest {
                // add admin and admins team\r
                TeamModel admins = new TeamModel("admins");\r
                admins.mailingLists.add("admins@localhost.com");\r
-               \r
+\r
                admin = new UserModel("admin");\r
                admin.password = "password";\r
                admin.canAdmin = true;\r
                admin.excludeFromFederation = true;\r
                admin.teams.add(admins);\r
-               \r
+\r
                service.updateUserModel(admin);\r
                admin = null;\r
                admins = null;\r
@@ -125,7 +114,7 @@ public class UserServiceTest {
                // confirm we have 1 team (admins)\r
                assertEquals(1, service.getAllTeamNames().size());\r
                assertEquals("admins", service.getAllTeamNames().get(0));\r
-               \r
+\r
                RepositoryModel newrepo1 = new RepositoryModel("newrepo1", null, null, null);\r
                newrepo1.accessRestriction = AccessRestrictionType.VIEW;\r
                RepositoryModel NEWREPO1 = new RepositoryModel("NEWREPO1", null, null, null);\r
@@ -168,7 +157,7 @@ public class UserServiceTest {
                newrepo2.accessRestriction = AccessRestrictionType.VIEW;\r
                RepositoryModel NEWREPO2 = new RepositoryModel("NEWREPO2", null, null, null);\r
                NEWREPO2.accessRestriction = AccessRestrictionType.VIEW;\r
-               \r
+\r
                team.addRepositoryPermission(newrepo2.name);\r
                team.name = "testteam2";\r
                service.updateTeamModel("testteam", team);\r
@@ -233,11 +222,11 @@ public class UserServiceTest {
                // delete both teams\r
                service.deleteTeam("testteam");\r
                service.deleteTeam("nextteam");\r
-               \r
+\r
                // assert we still have the admins team\r
                assertEquals(1, service.getAllTeamNames().size());\r
                assertEquals("admins", service.getAllTeamNames().get(0));\r
-               \r
+\r
                team = service.getTeamModel("admins");\r
                assertEquals(1, team.mailingLists.size());\r
                assertTrue(team.mailingLists.contains("admins@localhost.com"));\r