From a2ce62e1f360e9cdb2221cfa3b091c02bda857eb Mon Sep 17 00:00:00 2001 From: Laurens Vrijnsen <laurens.vrijnsen@sioux.eu> Date: Fri, 22 Mar 2013 07:36:52 -0400 Subject: [PATCH] Added enforced HTTP Basic Authentication --- src/com/gitblit/ConfigUserService.java | 127 +++++++++++++++++++++++++++++++----------- 1 files changed, 93 insertions(+), 34 deletions(-) diff --git a/src/com/gitblit/ConfigUserService.java b/src/com/gitblit/ConfigUserService.java index d274009..7aa0998 100644 --- a/src/com/gitblit/ConfigUserService.java +++ b/src/com/gitblit/ConfigUserService.java @@ -20,6 +20,7 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -65,6 +66,16 @@ private static final String DISPLAYNAME = "displayName"; private static final String EMAILADDRESS = "emailAddress"; + + private static final String ORGANIZATIONALUNIT = "organizationalUnit"; + + private static final String ORGANIZATION = "organization"; + + private static final String LOCALITY = "locality"; + + private static final String STATEPROVINCE = "stateProvince"; + + private static final String COUNTRYCODE = "countryCode"; private static final String COOKIE = "cookie"; @@ -276,7 +287,7 @@ * @since 1.2.0 */ @Override - public boolean updateUserModels(List<UserModel> models) { + public boolean updateUserModels(Collection<UserModel> models) { try { read(); for (UserModel model : models) { @@ -399,6 +410,10 @@ // Read realm file read(); UserModel model = users.remove(username.toLowerCase()); + if (model == null) { + // user does not exist + return false; + } // remove user from team for (TeamModel team : model.teams) { TeamModel t = teams.get(team.name); @@ -552,7 +567,7 @@ * @since 1.2.0 */ @Override - public boolean updateTeamModels(List<TeamModel> models) { + public boolean updateTeamModels(Collection<TeamModel> models) { try { read(); for (TeamModel team : models) { @@ -794,7 +809,6 @@ /** * Writes the properties file. * - * @param properties * @throws IOException */ private synchronized void write() throws IOException { @@ -816,6 +830,21 @@ } if (!StringUtils.isEmpty(model.emailAddress)) { config.setString(USER, model.username, EMAILADDRESS, model.emailAddress); + } + if (!StringUtils.isEmpty(model.organizationalUnit)) { + config.setString(USER, model.username, ORGANIZATIONALUNIT, model.organizationalUnit); + } + if (!StringUtils.isEmpty(model.organization)) { + config.setString(USER, model.username, ORGANIZATION, model.organization); + } + if (!StringUtils.isEmpty(model.locality)) { + config.setString(USER, model.username, LOCALITY, model.locality); + } + if (!StringUtils.isEmpty(model.stateProvince)) { + config.setString(USER, model.username, STATEPROVINCE, model.stateProvince); + } + if (!StringUtils.isEmpty(model.countryCode)) { + config.setString(USER, model.username, COUNTRYCODE, model.countryCode); } // user roles @@ -840,16 +869,8 @@ } config.setStringList(USER, model.username, ROLE, roles); - // repository memberships - if (model.permissions == null) { - // null check on "final" repositories because JSON-sourced UserModel - // can have a null repositories object - if (!ArrayUtils.isEmpty(model.repositories)) { - config.setStringList(USER, model.username, REPOSITORY, new ArrayList<String>( - model.repositories)); - } - } else { - // discrete repository permissions + // discrete repository permissions + if (model.permissions != null && !model.canAdmin) { List<String> permissions = new ArrayList<String>(); for (Map.Entry<String, AccessPermission> entry : model.permissions.entrySet()) { if (entry.getValue().exceeds(AccessPermission.NONE)) { @@ -862,23 +883,44 @@ // write teams for (TeamModel model : teams.values()) { - if (model.permissions == null) { - // null check on "final" repositories because JSON-sourced TeamModel - // can have a null repositories object - if (!ArrayUtils.isEmpty(model.repositories)) { - config.setStringList(TEAM, model.name, REPOSITORY, new ArrayList<String>( - model.repositories)); - } - } else { - // discrete repository permissions - List<String> permissions = 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 - permissions.add(entry.getValue().asRole(entry.getKey())); + // team roles + List<String> roles = new ArrayList<String>(); + if (model.canAdmin) { + roles.add(Constants.ADMIN_ROLE); + } + if (model.canFork) { + roles.add(Constants.FORK_ROLE); + } + if (model.canCreate) { + roles.add(Constants.CREATE_ROLE); + } + if (roles.size() == 0) { + // we do this to ensure that team record is written. + // Otherwise, StoredConfig might optimizes that record away. + roles.add(Constants.NO_ROLE); + } + config.setStringList(TEAM, model.name, ROLE, roles); + + if (!model.canAdmin) { + // write team permission for non-admin teams + if (model.permissions == null) { + // null check on "final" repositories because JSON-sourced TeamModel + // can have a null repositories object + if (!ArrayUtils.isEmpty(model.repositories)) { + config.setStringList(TEAM, model.name, REPOSITORY, new ArrayList<String>( + model.repositories)); } + } else { + // discrete repository permissions + List<String> permissions = 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 + permissions.add(entry.getValue().asRole(entry.getKey())); + } + } + config.setStringList(TEAM, model.name, REPOSITORY, permissions); } - config.setStringList(TEAM, model.name, REPOSITORY, permissions); } // null check on "final" users because JSON-sourced TeamModel @@ -951,6 +993,11 @@ user.password = config.getString(USER, username, PASSWORD); user.displayName = config.getString(USER, username, DISPLAYNAME); user.emailAddress = config.getString(USER, username, EMAILADDRESS); + user.organizationalUnit = config.getString(USER, username, ORGANIZATIONALUNIT); + user.organization = config.getString(USER, username, ORGANIZATION); + user.locality = config.getString(USER, username, LOCALITY); + user.stateProvince = config.getString(USER, username, STATEPROVINCE); + user.countryCode = config.getString(USER, username, COUNTRYCODE); user.cookie = config.getString(USER, username, COOKIE); if (StringUtils.isEmpty(user.cookie) && !StringUtils.isEmpty(user.password)) { user.cookie = StringUtils.getSHA1(user.username + user.password); @@ -965,10 +1012,13 @@ user.excludeFromFederation = roles.contains(Constants.NOT_FEDERATED_ROLE); // repository memberships - Set<String> repositories = new HashSet<String>(Arrays.asList(config - .getStringList(USER, username, REPOSITORY))); - for (String repository : repositories) { - user.addRepositoryPermission(repository); + if (!user.canAdmin) { + // non-admin, read permissions + Set<String> repositories = new HashSet<String>(Arrays.asList(config + .getStringList(USER, username, REPOSITORY))); + for (String repository : repositories) { + user.addRepositoryPermission(repository); + } } // update cache @@ -982,8 +1032,17 @@ Set<String> teamnames = config.getSubsections(TEAM); for (String teamname : teamnames) { TeamModel team = new TeamModel(teamname); - team.addRepositoryPermissions(Arrays.asList(config.getStringList(TEAM, teamname, - REPOSITORY))); + Set<String> roles = new HashSet<String>(Arrays.asList(config.getStringList( + TEAM, teamname, ROLE))); + team.canAdmin = roles.contains(Constants.ADMIN_ROLE); + team.canFork = roles.contains(Constants.FORK_ROLE); + team.canCreate = roles.contains(Constants.CREATE_ROLE); + + if (!team.canAdmin) { + // non-admin team, read permissions + team.addRepositoryPermissions(Arrays.asList(config.getStringList(TEAM, teamname, + REPOSITORY))); + } team.addUsers(Arrays.asList(config.getStringList(TEAM, teamname, USER))); team.addMailingLists(Arrays.asList(config.getStringList(TEAM, teamname, MAILINGLIST))); -- Gitblit v1.9.1