From d63157b22bb8a7294080be29ca0fca8ecda96db9 Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Wed, 05 Dec 2012 17:36:16 -0500 Subject: [PATCH] Checkbox to automatically set the new ssl certificate alias --- src/com/gitblit/models/UserModel.java | 172 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 145 insertions(+), 27 deletions(-) diff --git a/src/com/gitblit/models/UserModel.java b/src/com/gitblit/models/UserModel.java index 7733704..f1bc5ef 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; } @@ -476,6 +589,11 @@ public boolean hasBranchPermission(String repositoryName, String branch) { // Default UserModel doesn't implement branch-level security. Other Realms (i.e. Gerrit) may override this method. - return hasRepositoryPermission(repositoryName); + return hasRepositoryPermission(repositoryName) || hasTeamRepositoryPermission(repositoryName); + } + + public boolean isMyPersonalRepository(String repository) { + String projectPath = StringUtils.getFirstPathElement(repository); + return !StringUtils.isEmpty(projectPath) && projectPath.equalsIgnoreCase("~" + username); } } -- Gitblit v1.9.1