From 27ae9095639bb228a1b7ff86a3ebe4264abf05be Mon Sep 17 00:00:00 2001
From: mschaefers <mschaefers@scoop-gmbh.de>
Date: Thu, 29 Nov 2012 12:33:09 -0500
Subject: [PATCH] feature: when using LdapUserService one can configure Gitblit to fetch all users from ldap that can possibly login. This allows to see newly generated LDAP users instantly in Gitblit. By now an LDAP user had to log in once to appear in GitBlit.
---
src/com/gitblit/models/UserModel.java | 170 ++++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 144 insertions(+), 26 deletions(-)
diff --git a/src/com/gitblit/models/UserModel.java b/src/com/gitblit/models/UserModel.java
index 7733704..bd40985 100644
--- a/src/com/gitblit/models/UserModel.java
+++ b/src/com/gitblit/models/UserModel.java
@@ -19,15 +19,18 @@
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.TreeSet;
import com.gitblit.Constants.AccessPermission;
import com.gitblit.Constants.AccessRestrictionType;
import com.gitblit.Constants.AuthorizationControl;
+import com.gitblit.Constants.PermissionType;
import com.gitblit.Constants.RegistrantType;
import com.gitblit.Constants.Unused;
import com.gitblit.utils.ArrayUtils;
@@ -53,6 +56,11 @@
public String cookie;
public String displayName;
public String emailAddress;
+ public String organizationalUnit;
+ public String organization;
+ public String locality;
+ public String stateProvince;
+ public String countryCode;
public boolean canAdmin;
public boolean canFork;
public boolean canCreate;
@@ -60,8 +68,8 @@
// retained for backwards-compatibility with RPC clients
@Deprecated
public final Set<String> repositories = new HashSet<String>();
- public final Map<String, AccessPermission> permissions = new HashMap<String, AccessPermission>();
- public final Set<TeamModel> teams = new HashSet<TeamModel>();
+ public final Map<String, AccessPermission> permissions = new LinkedHashMap<String, AccessPermission>();
+ public final Set<TeamModel> teams = new TreeSet<TeamModel>();
// non-persisted fields
public boolean isAuthenticated;
@@ -136,11 +144,42 @@
*/
public List<RegistrantAccessPermission> getRepositoryPermissions() {
List<RegistrantAccessPermission> list = new ArrayList<RegistrantAccessPermission>();
+ if (canAdmin()) {
+ // user has REWIND access to all repositories
+ return list;
+ }
for (Map.Entry<String, AccessPermission> entry : permissions.entrySet()) {
- list.add(new RegistrantAccessPermission(entry.getKey(), entry.getValue(), RegistrantType.REPOSITORY));
+ String registrant = entry.getKey();
+ AccessPermission ap = entry.getValue();
+ String source = null;
+ boolean mutable = true;
+ PermissionType pType = PermissionType.EXPLICIT;
+ if (isMyPersonalRepository(registrant)) {
+ pType = PermissionType.OWNER;
+ ap = AccessPermission.REWIND;
+ mutable = false;
+ } else if (StringUtils.findInvalidCharacter(registrant) != null) {
+ // a regex will have at least 1 invalid character
+ pType = PermissionType.REGEX;
+ source = registrant;
+ }
+ list.add(new RegistrantAccessPermission(registrant, ap, pType, RegistrantType.REPOSITORY, source, mutable));
}
Collections.sort(list);
- return list;
+
+ // include immutable team permissions, being careful to preserve order
+ Set<RegistrantAccessPermission> set = new LinkedHashSet<RegistrantAccessPermission>(list);
+ for (TeamModel team : teams) {
+ for (RegistrantAccessPermission teamPermission : team.getRepositoryPermissions()) {
+ // we can not change an inherited team permission, though we can override
+ teamPermission.registrantType = RegistrantType.REPOSITORY;
+ teamPermission.permissionType = PermissionType.TEAM;
+ teamPermission.source = team.name;
+ teamPermission.mutable = false;
+ set.add(teamPermission);
+ }
+ }
+ return new ArrayList<RegistrantAccessPermission>(set);
}
/**
@@ -163,6 +202,36 @@
if (p != null) {
return true;
}
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if the user has an explicitly specified access permission for
+ * this repository.
+ *
+ * @param name
+ * @return if the user has an explicitly specified access permission
+ */
+ public boolean hasExplicitRepositoryPermission(String name) {
+ String repository = AccessPermission.repositoryFromRole(name).toLowerCase();
+ return permissions.containsKey(repository);
+ }
+
+ /**
+ * Returns true if the user's team memberships specify an access permission for
+ * this repository.
+ *
+ * @param name
+ * @return if the user's team memberships specifi an access permission
+ */
+ public boolean hasTeamRepositoryPermission(String name) {
+ if (teams != null) {
+ for (TeamModel team : teams) {
+ if (team.hasRepositoryPermission(name)) {
+ return true;
}
}
}
@@ -196,50 +265,94 @@
permissions.put(repository.toLowerCase(), permission);
}
- public AccessPermission getRepositoryPermission(RepositoryModel repository) {
- if (canAdmin() || repository.isOwner(username) || repository.isUsersPersonalRepository(username)) {
- return AccessPermission.REWIND;
+ public RegistrantAccessPermission getRepositoryPermission(RepositoryModel repository) {
+ RegistrantAccessPermission ap = new RegistrantAccessPermission();
+ ap.registrant = username;
+ ap.registrantType = RegistrantType.USER;
+ ap.permission = AccessPermission.NONE;
+ ap.mutable = false;
+
+ if (AccessRestrictionType.NONE.equals(repository.accessRestriction)) {
+ // anonymous rewind
+ ap.permissionType = PermissionType.ADMINISTRATOR;
+ ap.permission = AccessPermission.REWIND;
+ return ap;
}
- if (AuthorizationControl.AUTHENTICATED.equals(repository.authorizationControl) && isAuthenticated) {
- // AUTHENTICATED is a shortcut for authorizing all logged-in users RW access
- return AccessPermission.REWIND;
+
+ // administrator
+ if (canAdmin()) {
+ ap.permissionType = PermissionType.ADMINISTRATOR;
+ ap.permission = AccessPermission.REWIND;
+ if (!canAdmin) {
+ // administator permission from team membership
+ for (TeamModel team : teams) {
+ if (team.canAdmin) {
+ ap.source = team.name;
+ break;
+ }
+ }
+ }
+ return ap;
}
- // determine best permission available based on user's personal permissions
- // and the permissions of teams of which the user belongs
- AccessPermission permission = AccessPermission.NONE;
+ // repository owner - either specified owner or personal repository
+ if (repository.isOwner(username) || repository.isUsersPersonalRepository(username)) {
+ ap.permissionType = PermissionType.OWNER;
+ ap.permission = AccessPermission.REWIND;
+ return ap;
+ }
+
+ if (AuthorizationControl.AUTHENTICATED.equals(repository.authorizationControl) && isAuthenticated) {
+ // AUTHENTICATED is a shortcut for authorizing all logged-in users RW+ access
+ ap.permission = AccessPermission.REWIND;
+ return ap;
+ }
+
+ // explicit user permission OR user regex match is used
+ // if that fails, then the best team permission is used
if (permissions.containsKey(repository.name.toLowerCase())) {
// exact repository permission specified, use it
AccessPermission p = permissions.get(repository.name.toLowerCase());
if (p != null) {
- return p;
+ ap.permissionType = PermissionType.EXPLICIT;
+ ap.permission = p;
+ ap.mutable = true;
+ return ap;
}
} else {
- // search for regex permission match
+ // search for case-insensitive regex permission match
for (String key : permissions.keySet()) {
- if (repository.name.matches(key)) {
+ if (StringUtils.matchesIgnoreCase(repository.name, key)) {
AccessPermission p = permissions.get(key);
if (p != null) {
- permission = p;
+ // take first match
+ ap.permissionType = PermissionType.REGEX;
+ ap.permission = p;
+ ap.source = key;
+ return ap;
}
}
}
}
+ // try to find a team match
for (TeamModel team : teams) {
- AccessPermission p = team.getRepositoryPermission(repository);
- if (permission == null || p.exceeds(permission)) {
- // use team permission
- permission = p;
+ RegistrantAccessPermission p = team.getRepositoryPermission(repository);
+ if (p.permission.exceeds(ap.permission)) {
+ // use highest team permission
+ ap.permission = p.permission;
+ ap.source = team.name;
+ ap.permissionType = PermissionType.TEAM;
}
- }
- return permission;
+ }
+
+ return ap;
}
protected boolean canAccess(RepositoryModel repository, AccessRestrictionType ifRestriction, AccessPermission requirePermission) {
if (repository.accessRestriction.atLeast(ifRestriction)) {
- AccessPermission permission = getRepositoryPermission(repository);
- return permission.atLeast(requirePermission);
+ RegistrantAccessPermission ap = getRepositoryPermission(repository);
+ return ap.permission.atLeast(requirePermission);
}
return true;
}
@@ -478,4 +591,9 @@
// Default UserModel doesn't implement branch-level security. Other Realms (i.e. Gerrit) may override this method.
return hasRepositoryPermission(repositoryName);
}
+
+ public boolean isMyPersonalRepository(String repository) {
+ String projectPath = StringUtils.getFirstPathElement(repository);
+ return !StringUtils.isEmpty(projectPath) && projectPath.equalsIgnoreCase("~" + username);
+ }
}
--
Gitblit v1.9.1