From c658df9e87d65b08d5482cf04489cb0532ff83dd Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Sat, 13 Oct 2012 10:50:35 -0400
Subject: [PATCH] Merge branch 'master' of https://github.com/Mrbytes/gitblit

---
 src/com/gitblit/FileUserService.java |  172 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 151 insertions(+), 21 deletions(-)

diff --git a/src/com/gitblit/FileUserService.java b/src/com/gitblit/FileUserService.java
index 40bc3f6..d411b68 100644
--- a/src/com/gitblit/FileUserService.java
+++ b/src/com/gitblit/FileUserService.java
@@ -31,6 +31,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.gitblit.Constants.AccessPermission;
 import com.gitblit.models.TeamModel;
 import com.gitblit.models.UserModel;
 import com.gitblit.utils.ArrayUtils;
@@ -236,12 +237,14 @@
 					model.canAdmin = true;
 				} else if (role.equalsIgnoreCase(Constants.FORK_ROLE)) {
 					model.canFork = true;
+				} else if (role.equalsIgnoreCase(Constants.CREATE_ROLE)) {
+					model.canCreate = true;
 				} else if (role.equalsIgnoreCase(Constants.NOT_FEDERATED_ROLE)) {
 					model.excludeFromFederation = true;
 				}
 				break;
 			default:
-				model.addRepository(role);
+				model.addRepositoryPermission(role);
 			}
 		}
 		// set the teams for the user
@@ -265,6 +268,29 @@
 	}
 
 	/**
+	 * Updates/writes all specified user objects.
+	 * 
+	 * @param model a list of user models
+	 * @return true if update is successful
+	 * @since 1.2.0
+	 */
+	@Override
+	public boolean updateUserModels(List<UserModel> models) {
+		try {			
+			Properties allUsers = read();
+			for (UserModel model : models) {
+				updateUserCache(allUsers, model.username, model);
+			}
+			write(allUsers);
+			return true;
+		} catch (Throwable t) {
+			logger.error(MessageFormat.format("Failed to update {0} user models!", models.size()),
+					t);
+		}
+		return false;
+	}
+
+	/**
 	 * Updates/writes and replaces a complete user object keyed by username.
 	 * This method allows for renaming a user.
 	 * 
@@ -278,8 +304,43 @@
 	public boolean updateUserModel(String username, UserModel model) {
 		try {			
 			Properties allUsers = read();
+			updateUserCache(allUsers, username, model);
+			write(allUsers);
+			return true;
+		} catch (Throwable t) {
+			logger.error(MessageFormat.format("Failed to update user model {0}!", model.username),
+					t);
+		}
+		return false;
+	}
+	
+	/**
+	 * 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
+	 */
+	private boolean updateUserCache(Properties allUsers, String username, UserModel model) {
+		try {			
 			UserModel oldUser = getUserModel(username);
-			ArrayList<String> roles = new ArrayList<String>(model.repositories);
+			List<String> roles;
+			if (model.permissions == null) {
+				// legacy, use repository list
+				roles = new ArrayList<String>(model.repositories);
+			} else {
+				// discrete repository permissions
+				roles = new ArrayList<String>();
+				for (Map.Entry<String, AccessPermission> entry : model.permissions.entrySet()) {
+					if (entry.getValue().exceeds(AccessPermission.NONE)) {
+						// code:repository (e.g. RW+:~james/myrepo.git
+						roles.add(entry.getValue().asRole(entry.getKey()));
+					}
+				}
+			}
 
 			// Permissions
 			if (model.canAdmin) {
@@ -287,6 +348,9 @@
 			}
 			if (model.canFork) {
 				roles.add(Constants.FORK_ROLE);
+			}
+			if (model.canCreate) {
+				roles.add(Constants.CREATE_ROLE);
 			}
 			if (model.excludeFromFederation) {
 				roles.add(Constants.NOT_FEDERATED_ROLE);
@@ -331,8 +395,6 @@
 					}
 				}
 			}
-
-			write(allUsers);
 			return true;
 		} catch (Throwable t) {
 			logger.error(MessageFormat.format("Failed to update user model {0}!", model.username),
@@ -547,8 +609,8 @@
 				String[] roles = value.split(",");
 				// skip first value (password)
 				for (int i = 1; i < roles.length; i++) {
-					String r = roles[i];
-					if (r.equalsIgnoreCase(oldRole)) {
+					String repository = AccessPermission.repositoryFromRole(roles[i]);
+					if (repository.equalsIgnoreCase(oldRole)) {
 						needsRenameRole.add(username);
 						break;
 					}
@@ -568,9 +630,13 @@
 
 				// skip first value (password)
 				for (int i = 1; i < values.length; i++) {
-					String value = values[i];
-					if (!value.equalsIgnoreCase(oldRole)) {
-						sb.append(value);
+					String repository = AccessPermission.repositoryFromRole(values[i]);
+					if (repository.equalsIgnoreCase(oldRole)) {
+						AccessPermission permission = AccessPermission.permissionFromRole(values[i]);
+						sb.append(permission.asRole(newRole));
+						sb.append(',');
+					} else {
+						sb.append(values[i]);
 						sb.append(',');
 					}
 				}
@@ -607,9 +673,9 @@
 				String value = allUsers.getProperty(username);
 				String[] roles = value.split(",");
 				// skip first value (password)
-				for (int i = 1; i < roles.length; i++) {
-					String r = roles[i];
-					if (r.equalsIgnoreCase(role)) {
+				for (int i = 1; i < roles.length; i++) {					
+					String repository = AccessPermission.repositoryFromRole(roles[i]);
+					if (repository.equalsIgnoreCase(role)) {
 						needsDeleteRole.add(username);
 						break;
 					}
@@ -625,10 +691,10 @@
 				sb.append(password);
 				sb.append(',');
 				// skip first value (password)
-				for (int i = 1; i < values.length; i++) {
-					String value = values[i];
-					if (!value.equalsIgnoreCase(role)) {
-						sb.append(value);
+				for (int i = 1; i < values.length; i++) {					
+					String repository = AccessPermission.repositoryFromRole(values[i]);
+					if (!repository.equalsIgnoreCase(role)) {
+						sb.append(values[i]);
 						sb.append(',');
 					}
 				}
@@ -714,10 +780,24 @@
 						} else if (role.charAt(0) == '%') {
 							postReceive.add(role.substring(1));
 						} else {
+							switch (role.charAt(0)) {
+							case '#':
+								// Permissions
+								if (role.equalsIgnoreCase(Constants.ADMIN_ROLE)) {
+									team.canAdmin = true;
+								} else if (role.equalsIgnoreCase(Constants.FORK_ROLE)) {
+									team.canFork = true;
+								} else if (role.equalsIgnoreCase(Constants.CREATE_ROLE)) {
+									team.canCreate = true;
+								}
+								break;
+							default:
+								repositories.add(role);
+							}
 							repositories.add(role);
 						}
 					}
-					team.addRepositories(repositories);
+					team.addRepositoryPermissions(repositories);
 					team.addUsers(users);
 					team.addMailingLists(mailingLists);
 					team.preReceiveScripts.addAll(preReceive);
@@ -907,6 +987,27 @@
 	public boolean updateTeamModel(TeamModel model) {
 		return updateTeamModel(model.name, model);
 	}
+	
+	/**
+	 * Updates/writes all specified team objects.
+	 * 
+	 * @param models a list of team models
+	 * @return true if update is successful
+	 * @since 1.2.0
+	 */
+	public boolean updateTeamModels(List<TeamModel> models) {
+		try {
+			Properties allUsers = read();
+			for (TeamModel model : models) {
+				updateTeamCache(allUsers, model.name, model);
+			}
+			write(allUsers);
+			return true;
+		} catch (Throwable t) {
+			logger.error(MessageFormat.format("Failed to update {0} team models!", models.size()), t);
+		}
+		return false;
+	}
 
 	/**
 	 * Updates/writes and replaces a complete team object keyed by teamname.
@@ -934,12 +1035,41 @@
 
 	private void updateTeamCache(Properties allUsers, String teamname, TeamModel model) {
 		StringBuilder sb = new StringBuilder();
-		if (!ArrayUtils.isEmpty(model.repositories)) {
-			for (String repository : model.repositories) {
-				sb.append(repository);
-				sb.append(',');
+		List<String> roles;
+		if (model.permissions == null) {
+			// legacy, use repository list
+			if (model.repositories != null) {
+				roles = new ArrayList<String>(model.repositories);
+			} else {
+				roles = new ArrayList<String>();
+			}
+		} else {
+			// discrete repository permissions
+			roles = new ArrayList<String>();
+			for (Map.Entry<String, AccessPermission> entry : model.permissions.entrySet()) {
+				if (entry.getValue().exceeds(AccessPermission.NONE)) {
+					// code:repository (e.g. RW+:~james/myrepo.git
+					roles.add(entry.getValue().asRole(entry.getKey()));
+				}
 			}
 		}
+		
+		// Permissions
+		if (model.canAdmin) {
+			roles.add(Constants.ADMIN_ROLE);
+		}
+		if (model.canFork) {
+			roles.add(Constants.FORK_ROLE);
+		}
+		if (model.canCreate) {
+			roles.add(Constants.CREATE_ROLE);
+		}
+
+		for (String role : roles) {
+				sb.append(role);
+				sb.append(',');
+		}
+		
 		if (!ArrayUtils.isEmpty(model.users)) {
 			for (String user : model.users) {
 				sb.append('!');

--
Gitblit v1.9.1