From dfb88962fdbd29f59abe92178bb042738d57c3e1 Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Wed, 11 May 2011 22:07:18 -0400
Subject: [PATCH] Add user. Implemented repository view and git access restrictions.

---
 src/com/gitblit/JettyLoginService.java |  180 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 172 insertions(+), 8 deletions(-)

diff --git a/src/com/gitblit/JettyLoginService.java b/src/com/gitblit/JettyLoginService.java
index 5173d21..ddd3722 100644
--- a/src/com/gitblit/JettyLoginService.java
+++ b/src/com/gitblit/JettyLoginService.java
@@ -1,14 +1,33 @@
 package com.gitblit;
 
-import org.eclipse.jetty.security.HashLoginService;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.security.auth.Subject;
+
+import org.eclipse.jetty.http.security.Credential;
+import org.eclipse.jetty.security.IdentityService;
+import org.eclipse.jetty.security.MappedLoginService;
 import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.util.log.Log;
 
-import com.gitblit.wicket.User;
+import com.gitblit.utils.StringUtils;
+import com.gitblit.wicket.models.User;
 
-public class JettyLoginService extends HashLoginService implements ILoginService {
+public class JettyLoginService extends MappedLoginService implements ILoginService {
 
-	public JettyLoginService(String realmFile) {
-		super(Constants.NAME, realmFile);
+	private final File realmFile;
+
+	public JettyLoginService(File realmFile) {
+		super();
+		setName(Constants.NAME);
+		this.realmFile = realmFile;
 	}
 
 	@Override
@@ -17,10 +36,19 @@
 		if (identity == null || identity.equals(UserIdentity.UNAUTHENTICATED_IDENTITY)) {
 			return null;
 		}
-		User user = new User(username, password);
+		User user = new User(username);
+		user.setCookie(StringUtils.getSHA1((Constants.NAME + username + new String(password))));
 		user.canAdmin(identity.isUserInRole(Constants.ADMIN_ROLE, null));
-		user.canClone(identity.isUserInRole(Constants.PULL_ROLE, null));
-		user.canPush(identity.isUserInRole(Constants.PUSH_ROLE, null));
+
+		// Add repositories
+		for (Principal principal : identity.getSubject().getPrincipals()) {
+			if (principal instanceof RolePrincipal) {
+				RolePrincipal role = (RolePrincipal) principal;
+				if (role.getName().charAt(0) != '#') {
+					user.addRepository(role.getName().substring(1));
+				}
+			}
+		}
 		return user;
 	}
 
@@ -29,4 +57,140 @@
 		// TODO cookie login
 		return null;
 	}
+
+	@Override
+	public User getUserModel(String username) {
+		User model = new User(username);
+		UserIdentity identity = _users.get(username);
+		Subject subject = identity.getSubject();
+		for (Principal principal : subject.getPrincipals()) {
+			if (principal instanceof RolePrincipal) {
+				RolePrincipal role = (RolePrincipal) principal;
+				String name = role.getName();
+				switch (name.charAt(0)) {
+				case '#':
+					// Permissions
+					if (name.equalsIgnoreCase(Constants.ADMIN_ROLE)) {
+						model.canAdmin(true);
+					}
+					break;
+				default:
+					model.addRepository(name.substring(1));
+				}
+			}
+		}
+		return model;
+	}
+
+	@Override
+	public boolean updateUserModel(User model) {
+		try {
+			Properties properties = new Properties();
+			FileReader reader = new FileReader(realmFile);
+			properties.load(reader);
+			reader.close();
+
+			ArrayList<String> roles = new ArrayList<String>();
+
+			// Repositories
+			roles.addAll(model.getRepositories());
+
+			// Permissions
+			if (model.canAdmin()) {
+				roles.add(Constants.ADMIN_ROLE);
+			}
+
+			StringBuilder sb = new StringBuilder();
+			sb.append(model.getPassword());
+			sb.append(',');
+			for (String role : roles) {
+				sb.append(role);
+				sb.append(',');
+			}
+			// trim trailing comma
+			sb.setLength(sb.length() - 1);
+
+			// Update realm file
+			File realmFileCopy = new File(realmFile.getAbsolutePath() + ".tmp");
+			FileWriter writer = new FileWriter(realmFileCopy);
+			properties.put(model.getUsername(), sb.toString());
+			properties.store(writer, null);
+			writer.close();
+			realmFile.delete();
+			realmFileCopy.renameTo(realmFile);
+
+			// Update login service
+			putUser(model.getUsername(), Credential.getCredential(model.getPassword()), roles.toArray(new String[0]));
+			return true;
+		} catch (Throwable t) {
+			t.printStackTrace();
+		}
+		return false;
+	}
+
+	@Override
+	public boolean deleteUserModel(User model) {
+		try {
+			// Read realm file
+			Properties properties = new Properties();
+			FileReader reader = new FileReader(realmFile);
+			properties.load(reader);
+			reader.close();
+			properties.remove(model.getUsername());
+
+			// Update realm file
+			File realmFileCopy = new File(realmFile.getAbsolutePath() + ".tmp");
+			FileWriter writer = new FileWriter(realmFileCopy);
+			properties.store(writer, null);
+			writer.close();
+			realmFile.delete();
+			realmFileCopy.renameTo(realmFile);
+
+			// Drop user from map
+			_users.remove(model.getUsername());
+			return true;
+		} catch (Throwable t) {
+			t.printStackTrace();
+		}
+		return false;
+	}
+
+	/* ------------------------------------------------------------ */
+	@Override
+	public void loadUsers() throws IOException {
+		if (realmFile == null)
+			return;
+
+		if (Log.isDebugEnabled())
+			Log.debug("Load " + this + " from " + realmFile);
+		Properties properties = new Properties();
+		FileReader reader = new FileReader(realmFile);
+		properties.load(reader);
+		reader.close();
+
+		// Map Users
+		for (Map.Entry<Object, Object> entry : properties.entrySet()) {
+			String username = ((String) entry.getKey()).trim();
+			String credentials = ((String) entry.getValue()).trim();
+			String roles = null;
+			int c = credentials.indexOf(',');
+			if (c > 0) {
+				roles = credentials.substring(c + 1).trim();
+				credentials = credentials.substring(0, c).trim();
+			}
+
+			if (username != null && username.length() > 0 && credentials != null && credentials.length() > 0) {
+				String[] roleArray = IdentityService.NO_ROLES;
+				if (roles != null && roles.length() > 0) {
+					roleArray = roles.split(",");
+				}
+				putUser(username, Credential.getCredential(credentials), roleArray);
+			}
+		}
+	}
+
+	@Override
+	protected UserIdentity loadUser(String username) {
+		return null;
+	}
 }

--
Gitblit v1.9.1