From 17820f3a1153250a325fed23dfc2da59ce6ba777 Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Mon, 31 Oct 2011 22:47:21 -0400 Subject: [PATCH] More feeds work in Manager --- src/com/gitblit/FileUserService.java | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 150 insertions(+), 12 deletions(-) diff --git a/src/com/gitblit/FileUserService.java b/src/com/gitblit/FileUserService.java index 01a50be..3c8914d 100644 --- a/src/com/gitblit/FileUserService.java +++ b/src/com/gitblit/FileUserService.java @@ -33,6 +33,15 @@ import com.gitblit.models.UserModel; import com.gitblit.utils.StringUtils; +/** + * FileUserService is Gitblit's default user service implementation. + * + * Users and their repository memberships are stored in a simple properties file + * which is cached and dynamically reloaded when modified. + * + * @author James Moger + * + */ public class FileUserService extends FileSettings implements IUserService { private final Logger logger = LoggerFactory.getLogger(FileUserService.class); @@ -43,11 +52,32 @@ super(realmFile.getAbsolutePath()); } + /** + * Setup the user service. + * + * @param settings + * @since 0.6.1 + */ + @Override + public void setup(IStoredSettings settings) { + } + + /** + * Does the user service support cookie authentication? + * + * @return true or false + */ @Override public boolean supportsCookies() { return true; } + /** + * Returns the cookie value for the specified user. + * + * @param model + * @return cookie value + */ @Override public char[] getCookie(UserModel model) { Properties allUsers = super.read(); @@ -58,6 +88,12 @@ return cookie.toCharArray(); } + /** + * Authenticate a user based on their cookie. + * + * @param cookie + * @return a user object or null + */ @Override public UserModel authenticate(char[] cookie) { String hash = new String(cookie); @@ -73,6 +109,13 @@ return model; } + /** + * Authenticate a user based on a username and password. + * + * @param username + * @param password + * @return a user object or null + */ @Override public UserModel authenticate(String username, char[] password) { Properties allUsers = read(); @@ -83,16 +126,31 @@ UserModel returnedUser = null; UserModel user = getUserModel(username); if (user.password.startsWith(StringUtils.MD5_TYPE)) { + // password digest String md5 = StringUtils.MD5_TYPE + StringUtils.getMD5(new String(password)); if (user.password.equalsIgnoreCase(md5)) { returnedUser = user; } + } else if (user.password.startsWith(StringUtils.COMBINED_MD5_TYPE)) { + // username+password digest + String md5 = StringUtils.COMBINED_MD5_TYPE + + StringUtils.getMD5(username.toLowerCase() + new String(password)); + if (user.password.equalsIgnoreCase(md5)) { + returnedUser = user; + } } else if (user.password.equals(new String(password))) { + // plain-text password returnedUser = user; } return returnedUser; } + /** + * Retrieve the user object for the specified username. + * + * @param username + * @return a user object or null + */ @Override public UserModel getUserModel(String username) { Properties allUsers = read(); @@ -110,6 +168,8 @@ // Permissions if (role.equalsIgnoreCase(Constants.ADMIN_ROLE)) { model.canAdmin = true; + } else if (role.equalsIgnoreCase(Constants.NOT_FEDERATED_ROLE)) { + model.excludeFromFederation = true; } break; default: @@ -119,11 +179,27 @@ return model; } + /** + * Updates/writes a complete user object. + * + * @param model + * @return true if update is successful + */ @Override public boolean updateUserModel(UserModel model) { return updateUserModel(model.username, model); } + /** + * Updates/writes and replaces a complete user object keyed by username. + * This method allows for renaming a user. + * + * @param username + * the old username + * @param model + * the user object to use for username + * @return true if update is successful + */ @Override public boolean updateUserModel(String username, UserModel model) { try { @@ -133,6 +209,9 @@ // Permissions if (model.canAdmin) { roles.add(Constants.ADMIN_ROLE); + } + if (model.excludeFromFederation) { + roles.add(Constants.NOT_FEDERATED_ROLE); } StringBuilder sb = new StringBuilder(); @@ -156,11 +235,23 @@ return false; } + /** + * Deletes the user object from the user service. + * + * @param model + * @return true if successful + */ @Override public boolean deleteUserModel(UserModel model) { return deleteUser(model.username); } + /** + * Delete the user object with the specified username + * + * @param username + * @return true if successful + */ @Override public boolean deleteUser(String username) { try { @@ -175,6 +266,11 @@ return false; } + /** + * Returns the list of all users available to the login service. + * + * @return list of all usernames + */ @Override public List<String> getAllUsernames() { Properties allUsers = read(); @@ -182,8 +278,16 @@ return list; } + /** + * Returns the list of all users who are allowed to bypass the access + * restriction placed on the specified repository. + * + * @param role + * the repository name + * @return list of all usernames that can bypass the access restriction + */ @Override - public List<String> getUsernamesForRepository(String role) { + public List<String> getUsernamesForRepositoryRole(String role) { List<String> list = new ArrayList<String>(); try { Properties allUsers = read(); @@ -205,8 +309,17 @@ return list; } + /** + * Sets the list of all uses who are allowed to bypass the access + * restriction placed on the specified repository. + * + * @param role + * the repository name + * @param usernames + * @return true if successful + */ @Override - public boolean setUsernamesForRepository(String role, List<String> usernames) { + public boolean setUsernamesForRepositoryRole(String role, List<String> usernames) { try { Set<String> specifiedUsers = new HashSet<String>(usernames); Set<String> needsAddRole = new HashSet<String>(specifiedUsers); @@ -272,6 +385,13 @@ return false; } + /** + * Renames a repository role. + * + * @param oldRole + * @param newRole + * @return true if successful + */ @Override public boolean renameRepositoryRole(String oldRole, String newRole) { try { @@ -327,6 +447,12 @@ return false; } + /** + * Removes a repository role from all users. + * + * @param role + * @return true if successful + */ @Override public boolean deleteRepositoryRole(String role) { try { @@ -380,23 +506,32 @@ return false; } + /** + * Writes the properties file. + * + * @param properties + * @throws IOException + */ private void write(Properties properties) throws IOException { - // Update realm file + // Write a temporary copy of the users file File realmFileCopy = new File(propertiesFile.getAbsolutePath() + ".tmp"); FileWriter writer = new FileWriter(realmFileCopy); properties .store(writer, "# Gitblit realm file format: username=password,\\#permission,repository1,repository2..."); writer.close(); + // If the write is successful, delete the current file and rename + // the temporary copy to the original filename. if (realmFileCopy.exists() && realmFileCopy.length() > 0) { - if (propertiesFile.delete()) { - if (!realmFileCopy.renameTo(propertiesFile)) { - throw new IOException(MessageFormat.format("Failed to rename {0} to {1}!", - realmFileCopy.getAbsolutePath(), propertiesFile.getAbsolutePath())); + if (propertiesFile.exists()) { + if (!propertiesFile.delete()) { + throw new IOException(MessageFormat.format("Failed to delete {0}!", + propertiesFile.getAbsolutePath())); } - } else { - throw new IOException(MessageFormat.format("Failed to delete (0)!", - propertiesFile.getAbsolutePath())); + } + if (!realmFileCopy.renameTo(propertiesFile)) { + throw new IOException(MessageFormat.format("Failed to rename {0} to {1}!", + realmFileCopy.getAbsolutePath(), propertiesFile.getAbsolutePath())); } } else { throw new IOException(MessageFormat.format("Failed to save {0}!", @@ -404,11 +539,14 @@ } } + /** + * Reads the properties file and rebuilds the in-memory cookie lookup table. + */ @Override protected synchronized Properties read() { - long lastRead = lastRead(); + long lastRead = lastModified(); Properties allUsers = super.read(); - if (lastRead != lastRead()) { + if (lastRead != lastModified()) { // reload hash cache cookies.clear(); for (String username : allUsers.stringPropertyNames()) { -- Gitblit v1.9.1