From 23e08cdfd5f61e06f584c7fce4e765dd8b6e6643 Mon Sep 17 00:00:00 2001 From: James Moger Date: Mon, 25 Nov 2013 10:07:46 -0500 Subject: [PATCH] Refactor managers and authentication for federation Change-Id: I5ff18b2768095fb14e7fbece2e756115829abbde --- build.moxie | 4 +- build.xml | 3 +- src/main/java/com/gitblit/DaggerModule.java | 2 - .../java/com/gitblit/FederationClient.java | 48 +- src/main/java/com/gitblit/GitBlit.java | 993 +-------------- src/main/java/com/gitblit/git/GitDaemon.java | 4 +- .../manager/AuthenticationManager.java | 30 +- .../gitblit/manager/FederationManager.java | 43 +- .../com/gitblit/manager/GitblitManager.java | 1096 +++++++++++++++++ .../gitblit/manager/IFederationManager.java | 17 +- .../com/gitblit/manager/IUserManager.java | 7 + .../com/gitblit/manager/ServicesManager.java | 9 +- .../java/com/gitblit/manager/UserManager.java | 14 + .../service/FederationPullService.java | 13 +- .../gitblit/servlet/FederationServlet.java | 6 +- .../java/com/gitblit/servlet/GitFilter.java | 28 +- 16 files changed, 1273 insertions(+), 1044 deletions(-) create mode 100644 src/main/java/com/gitblit/manager/GitblitManager.java diff --git a/build.moxie b/build.moxie index acc1afb1..b09c7a51 100644 --- a/build.moxie +++ b/build.moxie @@ -129,7 +129,7 @@ dependencies: - compile 'log4j:log4j:1.2.17' :war :fedclient :authority - compile 'org.slf4j:slf4j-api:1.6.6' :war :fedclient :authority - compile 'org.slf4j:slf4j-log4j12:1.6.6' :war :fedclient :authority -- compile 'javax.mail:mail:1.4.3' :war :fedclient :authority +- compile 'javax.mail:mail:1.4.3' :war :authority - compile 'javax.servlet:javax.servlet-api:3.0.1' :fedclient - compile 'org.eclipse.jetty.aggregate:jetty-webapp:${jetty.version}' @jar - compile 'org.eclipse.jetty:jetty-ajp:${jetty.version}' @jar @@ -148,7 +148,7 @@ dependencies: - compile 'org.fusesource.wikitext:mediawiki-core:${wikitext.version}' :war - compile 'org.fusesource.wikitext:confluence-core:${wikitext.version}' :war - compile 'org.eclipse.jgit:org.eclipse.jgit:${jgit.version}' :war :fedclient :manager :authority -- compile 'org.eclipse.jgit:org.eclipse.jgit.http.server:${jgit.version}' :war :fedclient :manager :authority +- compile 'org.eclipse.jgit:org.eclipse.jgit.http.server:${jgit.version}' :war :manager :authority - compile 'org.bouncycastle:bcprov-jdk15on:${bouncycastle.version}' :war :authority - compile 'org.bouncycastle:bcmail-jdk15on:${bouncycastle.version}' :war :authority - compile 'org.bouncycastle:bcpkix-jdk15on:${bouncycastle.version}' :war :authority diff --git a/build.xml b/build.xml index ab6699bc..eb97cebc 100644 --- a/build.xml +++ b/build.xml @@ -279,7 +279,8 @@ + destfile="${project.targetDirectory}/fedclient.jar" + excludes="**/.class,**/*.java, **/Thumbs.db, **/*.mkd, com/gitblit/wicket/**"> diff --git a/src/main/java/com/gitblit/DaggerModule.java b/src/main/java/com/gitblit/DaggerModule.java index 135fafbf..857f36a2 100644 --- a/src/main/java/com/gitblit/DaggerModule.java +++ b/src/main/java/com/gitblit/DaggerModule.java @@ -149,13 +149,11 @@ public class DaggerModule { @Provides @Singleton IFederationManager provideFederationManager( IRuntimeManager runtimeManager, INotificationManager notificationManager, - IUserManager userManager, IRepositoryManager repositoryManager) { return new FederationManager( runtimeManager, notificationManager, - userManager, repositoryManager); } diff --git a/src/main/java/com/gitblit/FederationClient.java b/src/main/java/com/gitblit/FederationClient.java index 66b378ab..c2757463 100644 --- a/src/main/java/com/gitblit/FederationClient.java +++ b/src/main/java/com/gitblit/FederationClient.java @@ -17,6 +17,7 @@ package com.gitblit; import java.io.File; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import com.beust.jcommander.JCommander; @@ -24,7 +25,9 @@ import com.beust.jcommander.Parameter; import com.beust.jcommander.ParameterException; import com.beust.jcommander.Parameters; import com.gitblit.manager.FederationManager; -import com.gitblit.manager.NotificationManager; +import com.gitblit.manager.GitblitManager; +import com.gitblit.manager.IGitblit; +import com.gitblit.manager.INotificationManager; import com.gitblit.manager.RepositoryManager; import com.gitblit.manager.RuntimeManager; import com.gitblit.manager.UserManager; @@ -89,14 +92,14 @@ public class FederationClient { } // configure the Gitblit singleton for minimal, non-server operation - RuntimeManager runtime = new RuntimeManager(settings); - runtime.setBaseFolder(baseFolder); - NotificationManager notifications = new NotificationManager(settings).start(); + RuntimeManager runtime = new RuntimeManager(settings, baseFolder).start(); + NoopNotificationManager notifications = new NoopNotificationManager().start(); UserManager users = new UserManager(runtime).start(); RepositoryManager repositories = new RepositoryManager(runtime, users).start(); - FederationManager federation = new FederationManager(runtime, notifications, users, repositories).start(); + FederationManager federation = new FederationManager(runtime, notifications, repositories).start(); + IGitblit gitblit = new GitblitManager(runtime, notifications, users, null, repositories, null, federation); - FederationPullService puller = new FederationPullService(federation.getFederationRegistrations()) { + FederationPullService puller = new FederationPullService(gitblit, federation.getFederationRegistrations()) { @Override public void reschedule(FederationModel registration) { // NOOP @@ -153,4 +156,37 @@ public class FederationClient { public String repositoriesFolder; } + + private static class NoopNotificationManager implements INotificationManager { + + @Override + public NoopNotificationManager start() { + return this; + } + + @Override + public NoopNotificationManager stop() { + return this; + } + + @Override + public void sendMailToAdministrators(String subject, String message) { + } + + @Override + public void sendMail(String subject, String message, Collection toAddresses) { + } + + @Override + public void sendMail(String subject, String message, String... toAddresses) { + } + + @Override + public void sendHtmlMail(String subject, String message, Collection toAddresses) { + } + + @Override + public void sendHtmlMail(String subject, String message, String... toAddresses) { + } + } } diff --git a/src/main/java/com/gitblit/GitBlit.java b/src/main/java/com/gitblit/GitBlit.java index d07ac9a7..da80a746 100644 --- a/src/main/java/com/gitblit/GitBlit.java +++ b/src/main/java/com/gitblit/GitBlit.java @@ -15,98 +15,35 @@ */ package com.gitblit; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.lang.reflect.Type; import java.text.MessageFormat; import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; import java.util.List; -import java.util.Map; -import java.util.TimeZone; import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jgit.lib.Repository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.gitblit.Constants.AccessPermission; -import com.gitblit.Constants.AccessRestrictionType; -import com.gitblit.Constants.FederationRequest; -import com.gitblit.Constants.FederationToken; +import com.gitblit.manager.GitblitManager; import com.gitblit.manager.IAuthenticationManager; import com.gitblit.manager.IFederationManager; -import com.gitblit.manager.IGitblit; import com.gitblit.manager.INotificationManager; import com.gitblit.manager.IProjectManager; import com.gitblit.manager.IRepositoryManager; import com.gitblit.manager.IRuntimeManager; import com.gitblit.manager.IUserManager; import com.gitblit.manager.ServicesManager; -import com.gitblit.models.FederationModel; -import com.gitblit.models.FederationProposal; -import com.gitblit.models.FederationSet; -import com.gitblit.models.ForkModel; -import com.gitblit.models.GitClientApplication; -import com.gitblit.models.Metric; -import com.gitblit.models.ProjectModel; -import com.gitblit.models.RegistrantAccessPermission; import com.gitblit.models.RepositoryModel; import com.gitblit.models.RepositoryUrl; -import com.gitblit.models.SearchResult; -import com.gitblit.models.ServerSettings; -import com.gitblit.models.ServerStatus; -import com.gitblit.models.SettingModel; -import com.gitblit.models.TeamModel; import com.gitblit.models.UserModel; -import com.gitblit.utils.ArrayUtils; -import com.gitblit.utils.HttpUtils; -import com.gitblit.utils.JGitUtils; -import com.gitblit.utils.JsonUtils; -import com.gitblit.utils.ObjectCache; import com.gitblit.utils.StringUtils; -import com.google.gson.Gson; -import com.google.gson.JsonIOException; -import com.google.gson.JsonSyntaxException; -import com.google.gson.reflect.TypeToken; /** - * GitBlit is an aggregate interface delegate. It implements all the manager - * interfaces and delegates all methods calls to the actual manager implementations. - * It's primary purpose is to provide complete management control to the git - * upload and receive pack functions. + * GitBlit is the aggregate manager for the Gitblit webapp. It provides all + * management functions and also manages some long-running services. * * @author James Moger * */ -public class GitBlit implements IGitblit { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - - private final ObjectCache> clientApplications = new ObjectCache>(); - - private final IStoredSettings settings; - - private final IRuntimeManager runtimeManager; - - private final INotificationManager notificationManager; - - private final IUserManager userManager; - - private final IAuthenticationManager authenticationManager; - - private final IRepositoryManager repositoryManager; - - private final IProjectManager projectManager; - - private final IFederationManager federationManager; +public class GitBlit extends GitblitManager { private final ServicesManager servicesManager; @@ -119,21 +56,20 @@ public class GitBlit implements IGitblit { IProjectManager projectManager, IFederationManager federationManager) { - this.settings = runtimeManager.getSettings(); - this.runtimeManager = runtimeManager; - this.notificationManager = notificationManager; - this.userManager = userManager; - this.authenticationManager = authenticationManager; - this.repositoryManager = repositoryManager; - this.projectManager = projectManager; - this.federationManager = federationManager; + super(runtimeManager, + notificationManager, + userManager, + authenticationManager, + repositoryManager, + projectManager, + federationManager); this.servicesManager = new ServicesManager(this); } @Override public GitBlit start() { - loadSettingModels(runtimeManager.getSettingsModel()); + super.start(); logger.info("Starting services manager..."); servicesManager.start(); return this; @@ -141,169 +77,11 @@ public class GitBlit implements IGitblit { @Override public GitBlit stop() { + super.stop(); servicesManager.stop(); return this; } - /* - * IGITBLIT - */ - - /** - * Creates a personal fork of the specified repository. The clone is view - * restricted by default and the owner of the source repository is given - * access to the clone. - * - * @param repository - * @param user - * @return the repository model of the fork, if successful - * @throws GitBlitException - */ - @Override - public RepositoryModel fork(RepositoryModel repository, UserModel user) throws GitBlitException { - String cloneName = MessageFormat.format("{0}/{1}.git", user.getPersonalPath(), StringUtils.stripDotGit(StringUtils.getLastPathElement(repository.name))); - String fromUrl = MessageFormat.format("file://{0}/{1}", repositoryManager.getRepositoriesFolder().getAbsolutePath(), repository.name); - - // clone the repository - try { - JGitUtils.cloneRepository(repositoryManager.getRepositoriesFolder(), cloneName, fromUrl, true, null); - } catch (Exception e) { - throw new GitBlitException(e); - } - - // create a Gitblit repository model for the clone - RepositoryModel cloneModel = repository.cloneAs(cloneName); - // owner has REWIND/RW+ permissions - cloneModel.addOwner(user.username); - repositoryManager.updateRepositoryModel(cloneName, cloneModel, false); - - // add the owner of the source repository to the clone's access list - if (!ArrayUtils.isEmpty(repository.owners)) { - for (String owner : repository.owners) { - UserModel originOwner = userManager.getUserModel(owner); - if (originOwner != null) { - originOwner.setRepositoryPermission(cloneName, AccessPermission.CLONE); - reviseUser(originOwner.username, originOwner); - } - } - } - - // grant origin's user list clone permission to fork - List users = repositoryManager.getRepositoryUsers(repository); - List cloneUsers = new ArrayList(); - for (String name : users) { - if (!name.equalsIgnoreCase(user.username)) { - UserModel cloneUser = userManager.getUserModel(name); - if (cloneUser.canClone(repository)) { - // origin user can clone origin, grant clone access to fork - cloneUser.setRepositoryPermission(cloneName, AccessPermission.CLONE); - } - cloneUsers.add(cloneUser); - } - } - userManager.updateUserModels(cloneUsers); - - // grant origin's team list clone permission to fork - List teams = repositoryManager.getRepositoryTeams(repository); - List cloneTeams = new ArrayList(); - for (String name : teams) { - TeamModel cloneTeam = userManager.getTeamModel(name); - if (cloneTeam.canClone(repository)) { - // origin team can clone origin, grant clone access to fork - cloneTeam.setRepositoryPermission(cloneName, AccessPermission.CLONE); - } - cloneTeams.add(cloneTeam); - } - userManager.updateTeamModels(cloneTeams); - - // add this clone to the cached model - repositoryManager.addToCachedRepositoryList(cloneModel); - return cloneModel; - } - - /** - * Adds a TeamModel object. - * - * @param team - */ - @Override - public void addTeam(TeamModel team) throws GitBlitException { - if (!userManager.updateTeamModel(team)) { - throw new GitBlitException("Failed to add team!"); - } - } - - /** - * Updates the TeamModel object for the specified name. - * - * @param teamname - * @param team - */ - @Override - public void reviseTeam(String teamname, TeamModel team) throws GitBlitException { - if (!teamname.equalsIgnoreCase(team.name)) { - if (userManager.getTeamModel(team.name) != null) { - throw new GitBlitException(MessageFormat.format( - "Failed to rename ''{0}'' because ''{1}'' already exists.", teamname, - team.name)); - } - } - if (!userManager.updateTeamModel(teamname, team)) { - throw new GitBlitException("Failed to update team!"); - } - } - - /** - * Adds a user object. - * - * @param user - * @throws GitBlitException - */ - @Override - public void addUser(UserModel user) throws GitBlitException { - if (!userManager.updateUserModel(user)) { - throw new GitBlitException("Failed to add user!"); - } - } - - /** - * Updates a user object keyed by username. This method allows - * for renaming a user. - * - * @param username - * @param user - * @throws GitBlitException - */ - @Override - public void reviseUser(String username, UserModel user) throws GitBlitException { - if (!username.equalsIgnoreCase(user.username)) { - if (userManager.getUserModel(user.username) != null) { - throw new GitBlitException(MessageFormat.format( - "Failed to rename ''{0}'' because ''{1}'' already exists.", username, - user.username)); - } - - // rename repositories and owner fields for all repositories - for (RepositoryModel model : repositoryManager.getRepositoryModels(user)) { - if (model.isUsersPersonalRepository(username)) { - // personal repository - model.addOwner(user.username); - String oldRepositoryName = model.name; - model.name = user.getPersonalPath() + model.name.substring(model.projectPath.length()); - model.projectPath = user.getPersonalPath(); - repositoryManager.updateRepositoryModel(oldRepositoryName, model, false); - } else if (model.isOwner(username)) { - // common/shared repo - model.addOwner(user.username); - repositoryManager.updateRepositoryModel(model.name, model, false); - } - } - } - if (!userManager.updateUserModel(username, user)) { - throw new GitBlitException("Failed to update user!"); - } - } - /** * Returns a list of repository URLs and the user access permission. * @@ -353,749 +131,4 @@ public class GitBlit implements IGitblit { } return list; } - - protected String getRepositoryUrl(HttpServletRequest request, String username, RepositoryModel repository) { - StringBuilder sb = new StringBuilder(); - sb.append(HttpUtils.getGitblitURL(request)); - sb.append(Constants.R_PATH); - sb.append(repository.name); - - // inject username into repository url if authentication is required - if (repository.accessRestriction.exceeds(AccessRestrictionType.NONE) - && !StringUtils.isEmpty(username)) { - sb.insert(sb.indexOf("://") + 3, username + "@"); - } - return sb.toString(); - } - - - /** - * Returns the list of custom client applications to be used for the - * repository url panel; - * - * @return a collection of client applications - */ - @Override - public Collection getClientApplications() { - // prefer user definitions, if they exist - File userDefs = new File(runtimeManager.getBaseFolder(), "clientapps.json"); - if (userDefs.exists()) { - Date lastModified = new Date(userDefs.lastModified()); - if (clientApplications.hasCurrent("user", lastModified)) { - return clientApplications.getObject("user"); - } else { - // (re)load user definitions - try { - InputStream is = new FileInputStream(userDefs); - Collection clients = readClientApplications(is); - is.close(); - if (clients != null) { - clientApplications.updateObject("user", lastModified, clients); - return clients; - } - } catch (IOException e) { - logger.error("Failed to deserialize " + userDefs.getAbsolutePath(), e); - } - } - } - - // no user definitions, use system definitions - if (!clientApplications.hasCurrent("system", new Date(0))) { - try { - InputStream is = getClass().getResourceAsStream("/clientapps.json"); - Collection clients = readClientApplications(is); - is.close(); - if (clients != null) { - clientApplications.updateObject("system", new Date(0), clients); - } - } catch (IOException e) { - logger.error("Failed to deserialize clientapps.json resource!", e); - } - } - - return clientApplications.getObject("system"); - } - - private Collection readClientApplications(InputStream is) { - try { - Type type = new TypeToken>() { - }.getType(); - InputStreamReader reader = new InputStreamReader(is); - Gson gson = JsonUtils.gson(); - Collection links = gson.fromJson(reader, type); - return links; - } catch (JsonIOException e) { - logger.error("Error deserializing client applications!", e); - } catch (JsonSyntaxException e) { - logger.error("Error deserializing client applications!", e); - } - return null; - } - - /** - * Parse the properties file and aggregate all the comments by the setting - * key. A setting model tracks the current value, the default value, the - * description of the setting and and directives about the setting. - * - * @return Map - */ - private void loadSettingModels(ServerSettings settingsModel) { - try { - // Read bundled Gitblit properties to extract setting descriptions. - // This copy is pristine and only used for populating the setting - // models map. - InputStream is = getClass().getResourceAsStream("/reference.properties"); - BufferedReader propertiesReader = new BufferedReader(new InputStreamReader(is)); - StringBuilder description = new StringBuilder(); - SettingModel setting = new SettingModel(); - String line = null; - while ((line = propertiesReader.readLine()) != null) { - if (line.length() == 0) { - description.setLength(0); - setting = new SettingModel(); - } else { - if (line.charAt(0) == '#') { - if (line.length() > 1) { - String text = line.substring(1).trim(); - if (SettingModel.CASE_SENSITIVE.equals(text)) { - setting.caseSensitive = true; - } else if (SettingModel.RESTART_REQUIRED.equals(text)) { - setting.restartRequired = true; - } else if (SettingModel.SPACE_DELIMITED.equals(text)) { - setting.spaceDelimited = true; - } else if (text.startsWith(SettingModel.SINCE)) { - try { - setting.since = text.split(" ")[1]; - } catch (Exception e) { - setting.since = text; - } - } else { - description.append(text); - description.append('\n'); - } - } - } else { - String[] kvp = line.split("=", 2); - String key = kvp[0].trim(); - setting.name = key; - setting.defaultValue = kvp[1].trim(); - setting.currentValue = setting.defaultValue; - setting.description = description.toString().trim(); - settingsModel.add(setting); - description.setLength(0); - setting = new SettingModel(); - } - } - } - propertiesReader.close(); - } catch (NullPointerException e) { - logger.error("Failed to find resource copy of gitblit.properties"); - } catch (IOException e) { - logger.error("Failed to load resource copy of gitblit.properties"); - } - } - - /* - * ISTOREDSETTINGS - * - * these methods are necessary for (nearly) seamless Groovy hook operation - * after the massive refactor. - */ - - public boolean getBoolean(String key, boolean defaultValue) { - return runtimeManager.getSettings().getBoolean(key, defaultValue); - } - - public String getString(String key, String defaultValue) { - return runtimeManager.getSettings().getString(key, defaultValue); - } - - public int getInteger(String key, int defaultValue) { - return runtimeManager.getSettings().getInteger(key, defaultValue); - } - - public List getStrings(String key) { - return runtimeManager.getSettings().getStrings(key); - } - - /* - * RUNTIME MANAGER - */ - - @Override - public File getBaseFolder() { - return runtimeManager.getBaseFolder(); - } - - @Override - public void setBaseFolder(File folder) { - runtimeManager.setBaseFolder(folder); - } - - @Override - public Date getBootDate() { - return runtimeManager.getBootDate(); - } - - @Override - public ServerSettings getSettingsModel() { - return runtimeManager.getSettingsModel(); - } - - @Override - public boolean isServingRepositories() { - return runtimeManager.isServingRepositories(); - } - - @Override - public TimeZone getTimezone() { - return runtimeManager.getTimezone(); - } - - @Override - public boolean isDebugMode() { - return runtimeManager.isDebugMode(); - } - - @Override - public File getFileOrFolder(String key, String defaultFileOrFolder) { - return runtimeManager.getFileOrFolder(key, defaultFileOrFolder); - } - - @Override - public File getFileOrFolder(String fileOrFolder) { - return runtimeManager.getFileOrFolder(fileOrFolder); - } - - @Override - public IStoredSettings getSettings() { - return runtimeManager.getSettings(); - } - - @Override - public boolean updateSettings(Map updatedSettings) { - return runtimeManager.updateSettings(updatedSettings); - } - - @Override - public ServerStatus getStatus() { - return runtimeManager.getStatus(); - } - - /* - * NOTIFICATION MANAGER - */ - - @Override - public void sendMailToAdministrators(String subject, String message) { - notificationManager.sendMailToAdministrators(subject, message); - } - - @Override - public void sendMail(String subject, String message, Collection toAddresses) { - notificationManager.sendMail(subject, message, toAddresses); - } - - @Override - public void sendMail(String subject, String message, String... toAddresses) { - notificationManager.sendMail(subject, message, toAddresses); - } - - @Override - public void sendHtmlMail(String subject, String message, Collection toAddresses) { - notificationManager.sendHtmlMail(subject, message, toAddresses); - } - - @Override - public void sendHtmlMail(String subject, String message, String... toAddresses) { - notificationManager.sendHtmlMail(subject, message, toAddresses); - } - - /* - * SESSION MANAGER - */ - - @Override - public UserModel authenticate(String username, char[] password) { - return authenticationManager.authenticate(username, password); - } - - @Override - public UserModel authenticate(HttpServletRequest httpRequest) { - return authenticationManager.authenticate(httpRequest, false); - } - @Override - public UserModel authenticate(HttpServletRequest httpRequest, boolean requiresCertificate) { - return authenticationManager.authenticate(httpRequest, requiresCertificate); - } - - @Override - public void setCookie(HttpServletResponse response, UserModel user) { - authenticationManager.setCookie(response, user); - } - - @Override - public void logout(HttpServletResponse response, UserModel user) { - authenticationManager.logout(response, user); - } - - @Override - public boolean supportsCredentialChanges(UserModel user) { - return authenticationManager.supportsCredentialChanges(user); - } - - @Override - public boolean supportsDisplayNameChanges(UserModel user) { - return authenticationManager.supportsDisplayNameChanges(user); - } - - @Override - public boolean supportsEmailAddressChanges(UserModel user) { - return authenticationManager.supportsEmailAddressChanges(user); - } - - @Override - public boolean supportsTeamMembershipChanges(UserModel user) { - return authenticationManager.supportsTeamMembershipChanges(user); - } - - @Override - public boolean supportsTeamMembershipChanges(TeamModel team) { - return authenticationManager.supportsTeamMembershipChanges(team); - } - - /* - * USER MANAGER - */ - - @Override - public void setup(IRuntimeManager runtimeManager) { - } - - @Override - public List getAllUsernames() { - return userManager.getAllUsernames(); - } - - @Override - public List getAllUsers() { - return userManager.getAllUsers(); - } - - @Override - public boolean deleteUser(String username) { - return userManager.deleteUser(username); - } - - @Override - public UserModel getUserModel(String username) { - return userManager.getUserModel(username); - } - - @Override - public List getAllTeams() { - return userManager.getAllTeams(); - } - - @Override - public TeamModel getTeamModel(String teamname) { - return userManager.getTeamModel(teamname); - } - - @Override - public String getCookie(UserModel model) { - return userManager.getCookie(model); - } - - @Override - public UserModel getUserModel(char[] cookie) { - return userManager.getUserModel(cookie); - } - - @Override - public boolean updateUserModel(UserModel model) { - return userManager.updateUserModel(model); - } - - @Override - public boolean updateUserModels(Collection models) { - return userManager.updateUserModels(models); - } - - @Override - public boolean updateUserModel(String username, UserModel model) { - return userManager.updateUserModel(username, model); - } - - @Override - public boolean deleteUserModel(UserModel model) { - return userManager.deleteUserModel(model); - } - - @Override - public List getAllTeamNames() { - return userManager.getAllTeamNames(); - } - - @Override - public List getTeamNamesForRepositoryRole(String role) { - return userManager.getTeamNamesForRepositoryRole(role); - } - - @Override - public boolean updateTeamModel(TeamModel model) { - return userManager.updateTeamModel(model); - } - - @Override - public boolean updateTeamModels(Collection models) { - return userManager.updateTeamModels(models); - } - - @Override - public boolean updateTeamModel(String teamname, TeamModel model) { - return userManager.updateTeamModel(teamname, model); - } - - @Override - public boolean deleteTeamModel(TeamModel model) { - return userManager.deleteTeamModel(model); - } - - @Override - public List getUsernamesForRepositoryRole(String role) { - return userManager.getUsernamesForRepositoryRole(role); - } - - @Override - public boolean renameRepositoryRole(String oldRole, String newRole) { - return userManager.renameRepositoryRole(oldRole, newRole); - } - - @Override - public boolean deleteRepositoryRole(String role) { - return userManager.deleteRepositoryRole(role); - } - - @Override - public boolean deleteTeam(String teamname) { - return userManager.deleteTeam(teamname); - } - - /* - * REPOSITORY MANAGER - */ - - @Override - public Date getLastActivityDate() { - return repositoryManager.getLastActivityDate(); - } - - @Override - public File getRepositoriesFolder() { - return repositoryManager.getRepositoriesFolder(); - } - - @Override - public File getHooksFolder() { - return repositoryManager.getHooksFolder(); - } - - @Override - public File getGrapesFolder() { - return repositoryManager.getGrapesFolder(); - } - - @Override - public List getUserAccessPermissions(UserModel user) { - return repositoryManager.getUserAccessPermissions(user); - } - - @Override - public List getUserAccessPermissions(RepositoryModel repository) { - return repositoryManager.getUserAccessPermissions(repository); - } - - @Override - public boolean setUserAccessPermissions(RepositoryModel repository, Collection permissions) { - return repositoryManager.setUserAccessPermissions(repository, permissions); - } - - @Override - public List getRepositoryUsers(RepositoryModel repository) { - return repositoryManager.getRepositoryUsers(repository); - } - - @Override - public List getTeamAccessPermissions(RepositoryModel repository) { - return repositoryManager.getTeamAccessPermissions(repository); - } - - @Override - public boolean setTeamAccessPermissions(RepositoryModel repository, Collection permissions) { - return repositoryManager.setTeamAccessPermissions(repository, permissions); - } - - @Override - public List getRepositoryTeams(RepositoryModel repository) { - return repositoryManager.getRepositoryTeams(repository); - } - @Override - public void addToCachedRepositoryList(RepositoryModel model) { - repositoryManager.addToCachedRepositoryList(model); - } - - @Override - public void resetRepositoryListCache() { - repositoryManager.resetRepositoryListCache(); - } - - @Override - public List getRepositoryList() { - return repositoryManager.getRepositoryList(); - } - - @Override - public Repository getRepository(String repositoryName) { - return repositoryManager.getRepository(repositoryName); - } - - @Override - public Repository getRepository(String repositoryName, boolean logError) { - return repositoryManager.getRepository(repositoryName, logError); - } - - @Override - public List getRepositoryModels(UserModel user) { - return repositoryManager.getRepositoryModels(user); - } - - @Override - public RepositoryModel getRepositoryModel(UserModel user, String repositoryName) { - return repositoryManager.getRepositoryModel(repositoryName); - } - - @Override - public RepositoryModel getRepositoryModel(String repositoryName) { - return repositoryManager.getRepositoryModel(repositoryName); - } - - @Override - public long getStarCount(RepositoryModel repository) { - return repositoryManager.getStarCount(repository); - } - - @Override - public boolean hasRepository(String repositoryName) { - return repositoryManager.hasRepository(repositoryName); - } - - @Override - public boolean hasRepository(String repositoryName, boolean caseSensitiveCheck) { - return repositoryManager.hasRepository(repositoryName, caseSensitiveCheck); - } - - @Override - public boolean hasFork(String username, String origin) { - return repositoryManager.hasFork(username, origin); - } - - @Override - public String getFork(String username, String origin) { - return repositoryManager.getFork(username, origin); - } - - @Override - public ForkModel getForkNetwork(String repository) { - return repositoryManager.getForkNetwork(repository); - } - - @Override - public long updateLastChangeFields(Repository r, RepositoryModel model) { - return repositoryManager.updateLastChangeFields(r, model); - } - - @Override - public List getRepositoryDefaultMetrics(RepositoryModel model, Repository repository) { - return repositoryManager.getRepositoryDefaultMetrics(model, repository); - } - - @Override - public void updateRepositoryModel(String repositoryName, RepositoryModel repository, - boolean isCreate) throws GitBlitException { - repositoryManager.updateRepositoryModel(repositoryName, repository, isCreate); - } - - @Override - public void updateConfiguration(Repository r, RepositoryModel repository) { - repositoryManager.updateConfiguration(r, repository); - } - - @Override - public boolean deleteRepositoryModel(RepositoryModel model) { - return repositoryManager.deleteRepositoryModel(model); - } - - @Override - public boolean deleteRepository(String repositoryName) { - return repositoryManager.deleteRepository(repositoryName); - } - - @Override - public List getAllScripts() { - return repositoryManager.getAllScripts(); - } - - @Override - public List getPreReceiveScriptsInherited(RepositoryModel repository) { - return repositoryManager.getPreReceiveScriptsInherited(repository); - } - - @Override - public List getPreReceiveScriptsUnused(RepositoryModel repository) { - return repositoryManager.getPreReceiveScriptsUnused(repository); - } - - @Override - public List getPostReceiveScriptsInherited(RepositoryModel repository) { - return repositoryManager.getPostReceiveScriptsInherited(repository); - } - - @Override - public List getPostReceiveScriptsUnused(RepositoryModel repository) { - return repositoryManager.getPostReceiveScriptsUnused(repository); - } - - @Override - public List search(String query, int page, int pageSize, List repositories) { - return repositoryManager.search(query, page, pageSize, repositories); - } - - @Override - public boolean isCollectingGarbage() { - return repositoryManager.isCollectingGarbage(); - } - - @Override - public boolean isCollectingGarbage(String repositoryName) { - return repositoryManager.isCollectingGarbage(repositoryName); - } - - /* - * PROJECT MANAGER - */ - - @Override - public List getProjectModels(UserModel user, boolean includeUsers) { - return projectManager.getProjectModels(user, includeUsers); - } - - @Override - public ProjectModel getProjectModel(String name, UserModel user) { - return projectManager.getProjectModel(name, user); - } - - @Override - public ProjectModel getProjectModel(String name) { - return projectManager.getProjectModel(name); - } - - @Override - public List getProjectModels(List repositoryModels, boolean includeUsers) { - return projectManager.getProjectModels(repositoryModels, includeUsers); - } - - /* - * FEDERATION MANAGER - */ - - @Override - public File getProposalsFolder() { - return federationManager.getProposalsFolder(); - } - - @Override - public UserModel getFederationUser() { - return federationManager.getFederationUser(); - } - - @Override - public boolean canFederate() { - return federationManager.canFederate(); - } - - @Override - public List getFederationRegistrations() { - return federationManager.getFederationRegistrations(); - } - - @Override - public FederationModel getFederationRegistration(String url, String name) { - return federationManager.getFederationRegistration(url, name); - } - - @Override - public List getFederationSets(String gitblitUrl) { - return federationManager.getFederationSets(gitblitUrl); - } - - @Override - public List getFederationTokens() { - return federationManager.getFederationTokens(); - } - - @Override - public String getFederationToken(FederationToken type) { - return federationManager.getFederationToken(type); - } - - @Override - public String getFederationToken(String value) { - return federationManager.getFederationToken(value); - } - - @Override - public boolean validateFederationRequest(FederationRequest req, String token) { - return federationManager.validateFederationRequest(req, token); - } - - @Override - public boolean acknowledgeFederationStatus(String identification, FederationModel registration) { - return federationManager.acknowledgeFederationStatus(identification, registration); - } - - @Override - public List getFederationResultRegistrations() { - return federationManager.getFederationResultRegistrations(); - } - - @Override - public boolean submitFederationProposal(FederationProposal proposal, String gitblitUrl) { - return federationManager.submitFederationProposal(proposal, gitblitUrl); - } - - @Override - public List getPendingFederationProposals() { - return federationManager.getPendingFederationProposals(); - } - - @Override - public Map getRepositories(String gitblitUrl, String token) { - return federationManager.getRepositories(gitblitUrl, token); - } - - @Override - public FederationProposal createFederationProposal(String gitblitUrl, String token) { - return federationManager.createFederationProposal(gitblitUrl, token); - } - - @Override - public FederationProposal getPendingFederationProposal(String token) { - return federationManager.getPendingFederationProposal(token); - } - - @Override - public boolean deletePendingFederationProposal(FederationProposal proposal) { - return federationManager.deletePendingFederationProposal(proposal); - } } diff --git a/src/main/java/com/gitblit/git/GitDaemon.java b/src/main/java/com/gitblit/git/GitDaemon.java index 7273f387..d026b5ed 100644 --- a/src/main/java/com/gitblit/git/GitDaemon.java +++ b/src/main/java/com/gitblit/git/GitDaemon.java @@ -67,9 +67,9 @@ import org.eclipse.jgit.transport.resolver.UploadPackFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.gitblit.GitBlit; import com.gitblit.IStoredSettings; import com.gitblit.Keys; +import com.gitblit.manager.IGitblit; import com.gitblit.utils.StringUtils; /** @@ -108,7 +108,7 @@ public class GitDaemon { private ReceivePackFactory receivePackFactory; - public GitDaemon(GitBlit gitblit) { + public GitDaemon(IGitblit gitblit) { IStoredSettings settings = gitblit.getSettings(); int port = settings.getInteger(Keys.git.daemonPort, 0); diff --git a/src/main/java/com/gitblit/manager/AuthenticationManager.java b/src/main/java/com/gitblit/manager/AuthenticationManager.java index 6e541c45..8c66ce59 100644 --- a/src/main/java/com/gitblit/manager/AuthenticationManager.java +++ b/src/main/java/com/gitblit/manager/AuthenticationManager.java @@ -183,7 +183,7 @@ public class AuthenticationManager implements IAuthenticationManager { if (principal != null) { String username = principal.getName(); if (!StringUtils.isEmpty(username)) { - boolean internalAccount = isInternalAccount(username); + boolean internalAccount = userManager.isInternalAccount(username); UserModel user = userManager.getUserModel(username); if (user != null) { // existing user @@ -322,15 +322,6 @@ public class AuthenticationManager implements IAuthenticationManager { // can not authenticate empty password return null; } - // check to see if this is the federation user -// if (canFederate()) { -// if (usernameDecoded.equalsIgnoreCase(Constants.FEDERATION_USER)) { -// List tokens = getFederationTokens(); -// if (tokens.contains(pw)) { -// return getFederationUser(); -// } -// } -// } // try local authentication UserModel user = userManager.getUserModel(usernameDecoded); @@ -489,23 +480,4 @@ public class AuthenticationManager implements IAuthenticationManager { } return AuthenticationProvider.NULL_PROVIDER; } - - /** - * Returns true if the username represents an internal account - * - * @param username - * @return true if the specified username represents an internal account - */ - protected boolean isInternalAccount(String username) { - return !StringUtils.isEmpty(username) - && (username.equalsIgnoreCase(Constants.FEDERATION_USER) - || username.equalsIgnoreCase(UserModel.ANONYMOUS.username)); - } - -// protected UserModel getFederationUser() { -// // the federation user is an administrator -// UserModel federationUser = new UserModel(Constants.FEDERATION_USER); -// federationUser.canAdmin = true; -// return federationUser; -// } } diff --git a/src/main/java/com/gitblit/manager/FederationManager.java b/src/main/java/com/gitblit/manager/FederationManager.java index 568e87fc..95d38af1 100644 --- a/src/main/java/com/gitblit/manager/FederationManager.java +++ b/src/main/java/com/gitblit/manager/FederationManager.java @@ -17,6 +17,7 @@ package com.gitblit.manager; import java.io.File; import java.io.FileFilter; +import java.nio.charset.Charset; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; @@ -25,6 +26,8 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import javax.servlet.http.HttpServletRequest; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,6 +41,7 @@ import com.gitblit.models.FederationProposal; import com.gitblit.models.FederationSet; import com.gitblit.models.RepositoryModel; import com.gitblit.models.UserModel; +import com.gitblit.utils.Base64; import com.gitblit.utils.FederationUtils; import com.gitblit.utils.JsonUtils; import com.gitblit.utils.StringUtils; @@ -69,7 +73,6 @@ public class FederationManager implements IFederationManager { public FederationManager( IRuntimeManager runtimeManager, INotificationManager notificationManager, - IUserManager userManager, IRepositoryManager repositoryManager) { this.settings = runtimeManager.getSettings(); @@ -99,6 +102,17 @@ public class FederationManager implements IFederationManager { return runtimeManager.getFileOrFolder(Keys.federation.proposalsFolder, "${baseFolder}/proposals"); } + @Override + public boolean canFederate() { + String passphrase = settings.getString(Keys.federation.passphrase, ""); + return !StringUtils.isEmpty(passphrase); + } + + /** + * Returns the federation user account. + * + * @return the federation user account + */ @Override public UserModel getFederationUser() { // the federation user is an administrator @@ -108,9 +122,30 @@ public class FederationManager implements IFederationManager { } @Override - public boolean canFederate() { - String passphrase = settings.getString(Keys.federation.passphrase, ""); - return !StringUtils.isEmpty(passphrase); + public UserModel authenticate(HttpServletRequest httpRequest) { + if (canFederate()) { + // try to authenticate federation user for cloning + final String authorization = httpRequest.getHeader("Authorization"); + if (authorization != null && authorization.startsWith("Basic")) { + // Authorization: Basic base64credentials + String base64Credentials = authorization.substring("Basic".length()).trim(); + String credentials = new String(Base64.decode(base64Credentials), + Charset.forName("UTF-8")); + // credentials = username:password + final String[] values = credentials.split(":", 2); + if (values.length == 2) { + String username = StringUtils.decodeUsername(values[0]); + String password = values[1]; + if (username.equalsIgnoreCase(Constants.FEDERATION_USER)) { + List tokens = getFederationTokens(); + if (tokens.contains(password)) { + return getFederationUser(); + } + } + } + } + } + return null; } /** diff --git a/src/main/java/com/gitblit/manager/GitblitManager.java b/src/main/java/com/gitblit/manager/GitblitManager.java new file mode 100644 index 00000000..b3911814 --- /dev/null +++ b/src/main/java/com/gitblit/manager/GitblitManager.java @@ -0,0 +1,1096 @@ +/* + * Copyright 2013 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.manager; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Type; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jgit.lib.Repository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.gitblit.Constants; +import com.gitblit.Constants.AccessPermission; +import com.gitblit.Constants.AccessRestrictionType; +import com.gitblit.Constants.FederationRequest; +import com.gitblit.Constants.FederationToken; +import com.gitblit.GitBlitException; +import com.gitblit.IStoredSettings; +import com.gitblit.Keys; +import com.gitblit.models.FederationModel; +import com.gitblit.models.FederationProposal; +import com.gitblit.models.FederationSet; +import com.gitblit.models.ForkModel; +import com.gitblit.models.GitClientApplication; +import com.gitblit.models.Metric; +import com.gitblit.models.ProjectModel; +import com.gitblit.models.RegistrantAccessPermission; +import com.gitblit.models.RepositoryModel; +import com.gitblit.models.RepositoryUrl; +import com.gitblit.models.SearchResult; +import com.gitblit.models.ServerSettings; +import com.gitblit.models.ServerStatus; +import com.gitblit.models.SettingModel; +import com.gitblit.models.TeamModel; +import com.gitblit.models.UserModel; +import com.gitblit.utils.ArrayUtils; +import com.gitblit.utils.HttpUtils; +import com.gitblit.utils.JGitUtils; +import com.gitblit.utils.JsonUtils; +import com.gitblit.utils.ObjectCache; +import com.gitblit.utils.StringUtils; +import com.google.gson.Gson; +import com.google.gson.JsonIOException; +import com.google.gson.JsonSyntaxException; +import com.google.gson.reflect.TypeToken; + +/** + * GitblitManager is an aggregate interface delegate. It implements all the manager + * interfaces and delegates most methods calls to the proper manager implementation. + * It's primary purpose is to provide complete management control to the git + * upload and receive pack functions. + * + * GitblitManager also implements several integration methods when it is required + * to manipulate several manages for one operation. + * + * @author James Moger + * + */ +public class GitblitManager implements IGitblit { + + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + protected final ObjectCache> clientApplications = new ObjectCache>(); + + protected final IStoredSettings settings; + + protected final IRuntimeManager runtimeManager; + + protected final INotificationManager notificationManager; + + protected final IUserManager userManager; + + protected final IAuthenticationManager authenticationManager; + + protected final IRepositoryManager repositoryManager; + + protected final IProjectManager projectManager; + + protected final IFederationManager federationManager; + + public GitblitManager( + IRuntimeManager runtimeManager, + INotificationManager notificationManager, + IUserManager userManager, + IAuthenticationManager authenticationManager, + IRepositoryManager repositoryManager, + IProjectManager projectManager, + IFederationManager federationManager) { + + this.settings = runtimeManager.getSettings(); + this.runtimeManager = runtimeManager; + this.notificationManager = notificationManager; + this.userManager = userManager; + this.authenticationManager = authenticationManager; + this.repositoryManager = repositoryManager; + this.projectManager = projectManager; + this.federationManager = federationManager; + } + + @Override + public GitblitManager start() { + loadSettingModels(runtimeManager.getSettingsModel()); + return this; + } + + @Override + public GitblitManager stop() { + return this; + } + + /* + * IGITBLIT + */ + + /** + * Creates a personal fork of the specified repository. The clone is view + * restricted by default and the owner of the source repository is given + * access to the clone. + * + * @param repository + * @param user + * @return the repository model of the fork, if successful + * @throws GitBlitException + */ + @Override + public RepositoryModel fork(RepositoryModel repository, UserModel user) throws GitBlitException { + String cloneName = MessageFormat.format("{0}/{1}.git", user.getPersonalPath(), StringUtils.stripDotGit(StringUtils.getLastPathElement(repository.name))); + String fromUrl = MessageFormat.format("file://{0}/{1}", repositoryManager.getRepositoriesFolder().getAbsolutePath(), repository.name); + + // clone the repository + try { + JGitUtils.cloneRepository(repositoryManager.getRepositoriesFolder(), cloneName, fromUrl, true, null); + } catch (Exception e) { + throw new GitBlitException(e); + } + + // create a Gitblit repository model for the clone + RepositoryModel cloneModel = repository.cloneAs(cloneName); + // owner has REWIND/RW+ permissions + cloneModel.addOwner(user.username); + repositoryManager.updateRepositoryModel(cloneName, cloneModel, false); + + // add the owner of the source repository to the clone's access list + if (!ArrayUtils.isEmpty(repository.owners)) { + for (String owner : repository.owners) { + UserModel originOwner = userManager.getUserModel(owner); + if (originOwner != null) { + originOwner.setRepositoryPermission(cloneName, AccessPermission.CLONE); + reviseUser(originOwner.username, originOwner); + } + } + } + + // grant origin's user list clone permission to fork + List users = repositoryManager.getRepositoryUsers(repository); + List cloneUsers = new ArrayList(); + for (String name : users) { + if (!name.equalsIgnoreCase(user.username)) { + UserModel cloneUser = userManager.getUserModel(name); + if (cloneUser.canClone(repository)) { + // origin user can clone origin, grant clone access to fork + cloneUser.setRepositoryPermission(cloneName, AccessPermission.CLONE); + } + cloneUsers.add(cloneUser); + } + } + userManager.updateUserModels(cloneUsers); + + // grant origin's team list clone permission to fork + List teams = repositoryManager.getRepositoryTeams(repository); + List cloneTeams = new ArrayList(); + for (String name : teams) { + TeamModel cloneTeam = userManager.getTeamModel(name); + if (cloneTeam.canClone(repository)) { + // origin team can clone origin, grant clone access to fork + cloneTeam.setRepositoryPermission(cloneName, AccessPermission.CLONE); + } + cloneTeams.add(cloneTeam); + } + userManager.updateTeamModels(cloneTeams); + + // add this clone to the cached model + repositoryManager.addToCachedRepositoryList(cloneModel); + return cloneModel; + } + + /** + * Adds a TeamModel object. + * + * @param team + */ + @Override + public void addTeam(TeamModel team) throws GitBlitException { + if (!userManager.updateTeamModel(team)) { + throw new GitBlitException("Failed to add team!"); + } + } + + /** + * Updates the TeamModel object for the specified name. + * + * @param teamname + * @param team + */ + @Override + public void reviseTeam(String teamname, TeamModel team) throws GitBlitException { + if (!teamname.equalsIgnoreCase(team.name)) { + if (userManager.getTeamModel(team.name) != null) { + throw new GitBlitException(MessageFormat.format( + "Failed to rename ''{0}'' because ''{1}'' already exists.", teamname, + team.name)); + } + } + if (!userManager.updateTeamModel(teamname, team)) { + throw new GitBlitException("Failed to update team!"); + } + } + + /** + * Adds a user object. + * + * @param user + * @throws GitBlitException + */ + @Override + public void addUser(UserModel user) throws GitBlitException { + if (!userManager.updateUserModel(user)) { + throw new GitBlitException("Failed to add user!"); + } + } + + /** + * Updates a user object keyed by username. This method allows + * for renaming a user. + * + * @param username + * @param user + * @throws GitBlitException + */ + @Override + public void reviseUser(String username, UserModel user) throws GitBlitException { + if (!username.equalsIgnoreCase(user.username)) { + if (userManager.getUserModel(user.username) != null) { + throw new GitBlitException(MessageFormat.format( + "Failed to rename ''{0}'' because ''{1}'' already exists.", username, + user.username)); + } + + // rename repositories and owner fields for all repositories + for (RepositoryModel model : repositoryManager.getRepositoryModels(user)) { + if (model.isUsersPersonalRepository(username)) { + // personal repository + model.addOwner(user.username); + String oldRepositoryName = model.name; + model.name = user.getPersonalPath() + model.name.substring(model.projectPath.length()); + model.projectPath = user.getPersonalPath(); + repositoryManager.updateRepositoryModel(oldRepositoryName, model, false); + } else if (model.isOwner(username)) { + // common/shared repo + model.addOwner(user.username); + repositoryManager.updateRepositoryModel(model.name, model, false); + } + } + } + if (!userManager.updateUserModel(username, user)) { + throw new GitBlitException("Failed to update user!"); + } + } + + /** + * Returns a list of repository URLs and the user access permission. + * + * @param request + * @param user + * @param repository + * @return a list of repository urls + */ + @Override + public List getRepositoryUrls(HttpServletRequest request, UserModel user, RepositoryModel repository) { + if (user == null) { + user = UserModel.ANONYMOUS; + } + String username = StringUtils.encodeUsername(UserModel.ANONYMOUS.equals(user) ? "" : user.username); + + List list = new ArrayList(); + // http/https url + if (settings.getBoolean(Keys.git.enableGitServlet, true)) { + AccessPermission permission = user.getRepositoryPermission(repository).permission; + if (permission.exceeds(AccessPermission.NONE)) { + list.add(new RepositoryUrl(getRepositoryUrl(request, username, repository), permission)); + } + } + + // add all other urls + // {0} = repository + // {1} = username + for (String url : settings.getStrings(Keys.web.otherUrls)) { + if (url.contains("{1}")) { + // external url requires username, only add url IF we have one + if (!StringUtils.isEmpty(username)) { + list.add(new RepositoryUrl(MessageFormat.format(url, repository.name, username), null)); + } + } else { + // external url does not require username + list.add(new RepositoryUrl(MessageFormat.format(url, repository.name), null)); + } + } + return list; + } + + protected String getRepositoryUrl(HttpServletRequest request, String username, RepositoryModel repository) { + StringBuilder sb = new StringBuilder(); + sb.append(HttpUtils.getGitblitURL(request)); + sb.append(Constants.R_PATH); + sb.append(repository.name); + + // inject username into repository url if authentication is required + if (repository.accessRestriction.exceeds(AccessRestrictionType.NONE) + && !StringUtils.isEmpty(username)) { + sb.insert(sb.indexOf("://") + 3, username + "@"); + } + return sb.toString(); + } + + + /** + * Returns the list of custom client applications to be used for the + * repository url panel; + * + * @return a collection of client applications + */ + @Override + public Collection getClientApplications() { + // prefer user definitions, if they exist + File userDefs = new File(runtimeManager.getBaseFolder(), "clientapps.json"); + if (userDefs.exists()) { + Date lastModified = new Date(userDefs.lastModified()); + if (clientApplications.hasCurrent("user", lastModified)) { + return clientApplications.getObject("user"); + } else { + // (re)load user definitions + try { + InputStream is = new FileInputStream(userDefs); + Collection clients = readClientApplications(is); + is.close(); + if (clients != null) { + clientApplications.updateObject("user", lastModified, clients); + return clients; + } + } catch (IOException e) { + logger.error("Failed to deserialize " + userDefs.getAbsolutePath(), e); + } + } + } + + // no user definitions, use system definitions + if (!clientApplications.hasCurrent("system", new Date(0))) { + try { + InputStream is = getClass().getResourceAsStream("/clientapps.json"); + Collection clients = readClientApplications(is); + is.close(); + if (clients != null) { + clientApplications.updateObject("system", new Date(0), clients); + } + } catch (IOException e) { + logger.error("Failed to deserialize clientapps.json resource!", e); + } + } + + return clientApplications.getObject("system"); + } + + private Collection readClientApplications(InputStream is) { + try { + Type type = new TypeToken>() { + }.getType(); + InputStreamReader reader = new InputStreamReader(is); + Gson gson = JsonUtils.gson(); + Collection links = gson.fromJson(reader, type); + return links; + } catch (JsonIOException e) { + logger.error("Error deserializing client applications!", e); + } catch (JsonSyntaxException e) { + logger.error("Error deserializing client applications!", e); + } + return null; + } + + /** + * Parse the properties file and aggregate all the comments by the setting + * key. A setting model tracks the current value, the default value, the + * description of the setting and and directives about the setting. + * + * @return Map + */ + private void loadSettingModels(ServerSettings settingsModel) { + try { + // Read bundled Gitblit properties to extract setting descriptions. + // This copy is pristine and only used for populating the setting + // models map. + InputStream is = getClass().getResourceAsStream("/reference.properties"); + BufferedReader propertiesReader = new BufferedReader(new InputStreamReader(is)); + StringBuilder description = new StringBuilder(); + SettingModel setting = new SettingModel(); + String line = null; + while ((line = propertiesReader.readLine()) != null) { + if (line.length() == 0) { + description.setLength(0); + setting = new SettingModel(); + } else { + if (line.charAt(0) == '#') { + if (line.length() > 1) { + String text = line.substring(1).trim(); + if (SettingModel.CASE_SENSITIVE.equals(text)) { + setting.caseSensitive = true; + } else if (SettingModel.RESTART_REQUIRED.equals(text)) { + setting.restartRequired = true; + } else if (SettingModel.SPACE_DELIMITED.equals(text)) { + setting.spaceDelimited = true; + } else if (text.startsWith(SettingModel.SINCE)) { + try { + setting.since = text.split(" ")[1]; + } catch (Exception e) { + setting.since = text; + } + } else { + description.append(text); + description.append('\n'); + } + } + } else { + String[] kvp = line.split("=", 2); + String key = kvp[0].trim(); + setting.name = key; + setting.defaultValue = kvp[1].trim(); + setting.currentValue = setting.defaultValue; + setting.description = description.toString().trim(); + settingsModel.add(setting); + description.setLength(0); + setting = new SettingModel(); + } + } + } + propertiesReader.close(); + } catch (NullPointerException e) { + logger.error("Failed to find resource copy of gitblit.properties"); + } catch (IOException e) { + logger.error("Failed to load resource copy of gitblit.properties"); + } + } + + /* + * ISTOREDSETTINGS + * + * these methods are necessary for (nearly) seamless Groovy hook operation + * after the massive refactor. + */ + + public boolean getBoolean(String key, boolean defaultValue) { + return runtimeManager.getSettings().getBoolean(key, defaultValue); + } + + public String getString(String key, String defaultValue) { + return runtimeManager.getSettings().getString(key, defaultValue); + } + + public int getInteger(String key, int defaultValue) { + return runtimeManager.getSettings().getInteger(key, defaultValue); + } + + public List getStrings(String key) { + return runtimeManager.getSettings().getStrings(key); + } + + /* + * RUNTIME MANAGER + */ + + @Override + public File getBaseFolder() { + return runtimeManager.getBaseFolder(); + } + + @Override + public void setBaseFolder(File folder) { + runtimeManager.setBaseFolder(folder); + } + + @Override + public Date getBootDate() { + return runtimeManager.getBootDate(); + } + + @Override + public ServerSettings getSettingsModel() { + return runtimeManager.getSettingsModel(); + } + + @Override + public boolean isServingRepositories() { + return runtimeManager.isServingRepositories(); + } + + @Override + public TimeZone getTimezone() { + return runtimeManager.getTimezone(); + } + + @Override + public boolean isDebugMode() { + return runtimeManager.isDebugMode(); + } + + @Override + public File getFileOrFolder(String key, String defaultFileOrFolder) { + return runtimeManager.getFileOrFolder(key, defaultFileOrFolder); + } + + @Override + public File getFileOrFolder(String fileOrFolder) { + return runtimeManager.getFileOrFolder(fileOrFolder); + } + + @Override + public IStoredSettings getSettings() { + return runtimeManager.getSettings(); + } + + @Override + public boolean updateSettings(Map updatedSettings) { + return runtimeManager.updateSettings(updatedSettings); + } + + @Override + public ServerStatus getStatus() { + return runtimeManager.getStatus(); + } + + /* + * NOTIFICATION MANAGER + */ + + @Override + public void sendMailToAdministrators(String subject, String message) { + notificationManager.sendMailToAdministrators(subject, message); + } + + @Override + public void sendMail(String subject, String message, Collection toAddresses) { + notificationManager.sendMail(subject, message, toAddresses); + } + + @Override + public void sendMail(String subject, String message, String... toAddresses) { + notificationManager.sendMail(subject, message, toAddresses); + } + + @Override + public void sendHtmlMail(String subject, String message, Collection toAddresses) { + notificationManager.sendHtmlMail(subject, message, toAddresses); + } + + @Override + public void sendHtmlMail(String subject, String message, String... toAddresses) { + notificationManager.sendHtmlMail(subject, message, toAddresses); + } + + /* + * SESSION MANAGER + */ + + @Override + public UserModel authenticate(String username, char[] password) { + return authenticationManager.authenticate(username, password); + } + + @Override + public UserModel authenticate(HttpServletRequest httpRequest) { + UserModel user = authenticationManager.authenticate(httpRequest, false); + if (user == null) { + user = federationManager.authenticate(httpRequest); + } + return user; + } + @Override + public UserModel authenticate(HttpServletRequest httpRequest, boolean requiresCertificate) { + UserModel user = authenticationManager.authenticate(httpRequest, requiresCertificate); + if (user == null) { + user = federationManager.authenticate(httpRequest); + } + return user; + } + + @Override + public void setCookie(HttpServletResponse response, UserModel user) { + authenticationManager.setCookie(response, user); + } + + @Override + public void logout(HttpServletResponse response, UserModel user) { + authenticationManager.logout(response, user); + } + + @Override + public boolean supportsCredentialChanges(UserModel user) { + return authenticationManager.supportsCredentialChanges(user); + } + + @Override + public boolean supportsDisplayNameChanges(UserModel user) { + return authenticationManager.supportsDisplayNameChanges(user); + } + + @Override + public boolean supportsEmailAddressChanges(UserModel user) { + return authenticationManager.supportsEmailAddressChanges(user); + } + + @Override + public boolean supportsTeamMembershipChanges(UserModel user) { + return authenticationManager.supportsTeamMembershipChanges(user); + } + + @Override + public boolean supportsTeamMembershipChanges(TeamModel team) { + return authenticationManager.supportsTeamMembershipChanges(team); + } + + /* + * USER MANAGER + */ + + @Override + public void setup(IRuntimeManager runtimeManager) { + } + + @Override + public boolean isInternalAccount(String username) { + return userManager.isInternalAccount(username); + } + + @Override + public List getAllUsernames() { + return userManager.getAllUsernames(); + } + + @Override + public List getAllUsers() { + return userManager.getAllUsers(); + } + + @Override + public boolean deleteUser(String username) { + return userManager.deleteUser(username); + } + + @Override + public UserModel getUserModel(String username) { + return userManager.getUserModel(username); + } + + @Override + public List getAllTeams() { + return userManager.getAllTeams(); + } + + @Override + public TeamModel getTeamModel(String teamname) { + return userManager.getTeamModel(teamname); + } + + @Override + public String getCookie(UserModel model) { + return userManager.getCookie(model); + } + + @Override + public UserModel getUserModel(char[] cookie) { + return userManager.getUserModel(cookie); + } + + @Override + public boolean updateUserModel(UserModel model) { + return userManager.updateUserModel(model); + } + + @Override + public boolean updateUserModels(Collection models) { + return userManager.updateUserModels(models); + } + + @Override + public boolean updateUserModel(String username, UserModel model) { + return userManager.updateUserModel(username, model); + } + + @Override + public boolean deleteUserModel(UserModel model) { + return userManager.deleteUserModel(model); + } + + @Override + public List getAllTeamNames() { + return userManager.getAllTeamNames(); + } + + @Override + public List getTeamNamesForRepositoryRole(String role) { + return userManager.getTeamNamesForRepositoryRole(role); + } + + @Override + public boolean updateTeamModel(TeamModel model) { + return userManager.updateTeamModel(model); + } + + @Override + public boolean updateTeamModels(Collection models) { + return userManager.updateTeamModels(models); + } + + @Override + public boolean updateTeamModel(String teamname, TeamModel model) { + return userManager.updateTeamModel(teamname, model); + } + + @Override + public boolean deleteTeamModel(TeamModel model) { + return userManager.deleteTeamModel(model); + } + + @Override + public List getUsernamesForRepositoryRole(String role) { + return userManager.getUsernamesForRepositoryRole(role); + } + + @Override + public boolean renameRepositoryRole(String oldRole, String newRole) { + return userManager.renameRepositoryRole(oldRole, newRole); + } + + @Override + public boolean deleteRepositoryRole(String role) { + return userManager.deleteRepositoryRole(role); + } + + @Override + public boolean deleteTeam(String teamname) { + return userManager.deleteTeam(teamname); + } + + /* + * REPOSITORY MANAGER + */ + + @Override + public Date getLastActivityDate() { + return repositoryManager.getLastActivityDate(); + } + + @Override + public File getRepositoriesFolder() { + return repositoryManager.getRepositoriesFolder(); + } + + @Override + public File getHooksFolder() { + return repositoryManager.getHooksFolder(); + } + + @Override + public File getGrapesFolder() { + return repositoryManager.getGrapesFolder(); + } + + @Override + public List getUserAccessPermissions(UserModel user) { + return repositoryManager.getUserAccessPermissions(user); + } + + @Override + public List getUserAccessPermissions(RepositoryModel repository) { + return repositoryManager.getUserAccessPermissions(repository); + } + + @Override + public boolean setUserAccessPermissions(RepositoryModel repository, Collection permissions) { + return repositoryManager.setUserAccessPermissions(repository, permissions); + } + + @Override + public List getRepositoryUsers(RepositoryModel repository) { + return repositoryManager.getRepositoryUsers(repository); + } + + @Override + public List getTeamAccessPermissions(RepositoryModel repository) { + return repositoryManager.getTeamAccessPermissions(repository); + } + + @Override + public boolean setTeamAccessPermissions(RepositoryModel repository, Collection permissions) { + return repositoryManager.setTeamAccessPermissions(repository, permissions); + } + + @Override + public List getRepositoryTeams(RepositoryModel repository) { + return repositoryManager.getRepositoryTeams(repository); + } + @Override + public void addToCachedRepositoryList(RepositoryModel model) { + repositoryManager.addToCachedRepositoryList(model); + } + + @Override + public void resetRepositoryListCache() { + repositoryManager.resetRepositoryListCache(); + } + + @Override + public List getRepositoryList() { + return repositoryManager.getRepositoryList(); + } + + @Override + public Repository getRepository(String repositoryName) { + return repositoryManager.getRepository(repositoryName); + } + + @Override + public Repository getRepository(String repositoryName, boolean logError) { + return repositoryManager.getRepository(repositoryName, logError); + } + + @Override + public List getRepositoryModels(UserModel user) { + return repositoryManager.getRepositoryModels(user); + } + + @Override + public RepositoryModel getRepositoryModel(UserModel user, String repositoryName) { + return repositoryManager.getRepositoryModel(repositoryName); + } + + @Override + public RepositoryModel getRepositoryModel(String repositoryName) { + return repositoryManager.getRepositoryModel(repositoryName); + } + + @Override + public long getStarCount(RepositoryModel repository) { + return repositoryManager.getStarCount(repository); + } + + @Override + public boolean hasRepository(String repositoryName) { + return repositoryManager.hasRepository(repositoryName); + } + + @Override + public boolean hasRepository(String repositoryName, boolean caseSensitiveCheck) { + return repositoryManager.hasRepository(repositoryName, caseSensitiveCheck); + } + + @Override + public boolean hasFork(String username, String origin) { + return repositoryManager.hasFork(username, origin); + } + + @Override + public String getFork(String username, String origin) { + return repositoryManager.getFork(username, origin); + } + + @Override + public ForkModel getForkNetwork(String repository) { + return repositoryManager.getForkNetwork(repository); + } + + @Override + public long updateLastChangeFields(Repository r, RepositoryModel model) { + return repositoryManager.updateLastChangeFields(r, model); + } + + @Override + public List getRepositoryDefaultMetrics(RepositoryModel model, Repository repository) { + return repositoryManager.getRepositoryDefaultMetrics(model, repository); + } + + @Override + public void updateRepositoryModel(String repositoryName, RepositoryModel repository, + boolean isCreate) throws GitBlitException { + repositoryManager.updateRepositoryModel(repositoryName, repository, isCreate); + } + + @Override + public void updateConfiguration(Repository r, RepositoryModel repository) { + repositoryManager.updateConfiguration(r, repository); + } + + @Override + public boolean deleteRepositoryModel(RepositoryModel model) { + return repositoryManager.deleteRepositoryModel(model); + } + + @Override + public boolean deleteRepository(String repositoryName) { + return repositoryManager.deleteRepository(repositoryName); + } + + @Override + public List getAllScripts() { + return repositoryManager.getAllScripts(); + } + + @Override + public List getPreReceiveScriptsInherited(RepositoryModel repository) { + return repositoryManager.getPreReceiveScriptsInherited(repository); + } + + @Override + public List getPreReceiveScriptsUnused(RepositoryModel repository) { + return repositoryManager.getPreReceiveScriptsUnused(repository); + } + + @Override + public List getPostReceiveScriptsInherited(RepositoryModel repository) { + return repositoryManager.getPostReceiveScriptsInherited(repository); + } + + @Override + public List getPostReceiveScriptsUnused(RepositoryModel repository) { + return repositoryManager.getPostReceiveScriptsUnused(repository); + } + + @Override + public List search(String query, int page, int pageSize, List repositories) { + return repositoryManager.search(query, page, pageSize, repositories); + } + + @Override + public boolean isCollectingGarbage() { + return repositoryManager.isCollectingGarbage(); + } + + @Override + public boolean isCollectingGarbage(String repositoryName) { + return repositoryManager.isCollectingGarbage(repositoryName); + } + + /* + * PROJECT MANAGER + */ + + @Override + public List getProjectModels(UserModel user, boolean includeUsers) { + return projectManager.getProjectModels(user, includeUsers); + } + + @Override + public ProjectModel getProjectModel(String name, UserModel user) { + return projectManager.getProjectModel(name, user); + } + + @Override + public ProjectModel getProjectModel(String name) { + return projectManager.getProjectModel(name); + } + + @Override + public List getProjectModels(List repositoryModels, boolean includeUsers) { + return projectManager.getProjectModels(repositoryModels, includeUsers); + } + + /* + * FEDERATION MANAGER + */ + + @Override + public File getProposalsFolder() { + return federationManager.getProposalsFolder(); + } + + @Override + public boolean canFederate() { + return federationManager.canFederate(); + } + + @Override + public UserModel getFederationUser() { + return federationManager.getFederationUser(); + } + + @Override + public List getFederationRegistrations() { + return federationManager.getFederationRegistrations(); + } + + @Override + public FederationModel getFederationRegistration(String url, String name) { + return federationManager.getFederationRegistration(url, name); + } + + @Override + public List getFederationSets(String gitblitUrl) { + return federationManager.getFederationSets(gitblitUrl); + } + + @Override + public List getFederationTokens() { + return federationManager.getFederationTokens(); + } + + @Override + public String getFederationToken(FederationToken type) { + return federationManager.getFederationToken(type); + } + + @Override + public String getFederationToken(String value) { + return federationManager.getFederationToken(value); + } + + @Override + public boolean validateFederationRequest(FederationRequest req, String token) { + return federationManager.validateFederationRequest(req, token); + } + + @Override + public boolean acknowledgeFederationStatus(String identification, FederationModel registration) { + return federationManager.acknowledgeFederationStatus(identification, registration); + } + + @Override + public List getFederationResultRegistrations() { + return federationManager.getFederationResultRegistrations(); + } + + @Override + public boolean submitFederationProposal(FederationProposal proposal, String gitblitUrl) { + return federationManager.submitFederationProposal(proposal, gitblitUrl); + } + + @Override + public List getPendingFederationProposals() { + return federationManager.getPendingFederationProposals(); + } + + @Override + public Map getRepositories(String gitblitUrl, String token) { + return federationManager.getRepositories(gitblitUrl, token); + } + + @Override + public FederationProposal createFederationProposal(String gitblitUrl, String token) { + return federationManager.createFederationProposal(gitblitUrl, token); + } + + @Override + public FederationProposal getPendingFederationProposal(String token) { + return federationManager.getPendingFederationProposal(token); + } + + @Override + public boolean deletePendingFederationProposal(FederationProposal proposal) { + return federationManager.deletePendingFederationProposal(proposal); + } +} diff --git a/src/main/java/com/gitblit/manager/IFederationManager.java b/src/main/java/com/gitblit/manager/IFederationManager.java index 5afdeea1..d5880c00 100644 --- a/src/main/java/com/gitblit/manager/IFederationManager.java +++ b/src/main/java/com/gitblit/manager/IFederationManager.java @@ -19,6 +19,8 @@ import java.io.File; import java.util.List; import java.util.Map; +import javax.servlet.http.HttpServletRequest; + import com.gitblit.Constants.FederationRequest; import com.gitblit.Constants.FederationToken; import com.gitblit.models.FederationModel; @@ -37,9 +39,22 @@ public interface IFederationManager extends IManager { */ File getProposalsFolder(); + boolean canFederate(); + + /** + * Returns the federation user account. + * + * @return the federation user account + */ UserModel getFederationUser(); - boolean canFederate(); + /** + * Try to authenticate request as the Federation user. + * + * @param httpRequest + * @return the federation user, if authenticated + */ + UserModel authenticate(HttpServletRequest httpRequest); /** * Returns the list of federated gitblit instances that this instance will diff --git a/src/main/java/com/gitblit/manager/IUserManager.java b/src/main/java/com/gitblit/manager/IUserManager.java index 5815bcaf..945d6a85 100644 --- a/src/main/java/com/gitblit/manager/IUserManager.java +++ b/src/main/java/com/gitblit/manager/IUserManager.java @@ -19,5 +19,12 @@ import com.gitblit.IUserService; public interface IUserManager extends IManager, IUserService { + /** + * Returns true if the username represents an internal account + * + * @param username + * @return true if the specified username represents an internal account + */ + boolean isInternalAccount(String username); } \ No newline at end of file diff --git a/src/main/java/com/gitblit/manager/ServicesManager.java b/src/main/java/com/gitblit/manager/ServicesManager.java index 6cc94562..8107a7d8 100644 --- a/src/main/java/com/gitblit/manager/ServicesManager.java +++ b/src/main/java/com/gitblit/manager/ServicesManager.java @@ -32,7 +32,6 @@ import org.slf4j.LoggerFactory; import com.gitblit.Constants.AccessPermission; import com.gitblit.Constants.AccessRestrictionType; import com.gitblit.Constants.FederationToken; -import com.gitblit.GitBlit; import com.gitblit.IStoredSettings; import com.gitblit.Keys; import com.gitblit.fanout.FanoutNioService; @@ -62,13 +61,13 @@ public class ServicesManager implements IManager { private final IStoredSettings settings; - private final GitBlit gitblit; + private final IGitblit gitblit; private FanoutService fanoutService; private GitDaemon gitDaemon; - public ServicesManager(GitBlit gitblit) { + public ServicesManager(IGitblit gitblit) { this.settings = gitblit.getSettings(); this.gitblit = gitblit; } @@ -209,11 +208,11 @@ public class ServicesManager implements IManager { private class FederationPuller extends FederationPullService { public FederationPuller(FederationModel registration) { - super(Arrays.asList(registration)); + super(gitblit, Arrays.asList(registration)); } public FederationPuller(List registrations) { - super(registrations); + super(gitblit, registrations); } @Override diff --git a/src/main/java/com/gitblit/manager/UserManager.java b/src/main/java/com/gitblit/manager/UserManager.java index 3ca62e23..19943d71 100644 --- a/src/main/java/com/gitblit/manager/UserManager.java +++ b/src/main/java/com/gitblit/manager/UserManager.java @@ -28,6 +28,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.gitblit.ConfigUserService; +import com.gitblit.Constants; import com.gitblit.IStoredSettings; import com.gitblit.IUserService; import com.gitblit.Keys; @@ -148,6 +149,19 @@ public class UserManager implements IUserManager { return this; } + /** + * Returns true if the username represents an internal account + * + * @param username + * @return true if the specified username represents an internal account + */ + @Override + public boolean isInternalAccount(String username) { + return !StringUtils.isEmpty(username) + && (username.equalsIgnoreCase(Constants.FEDERATION_USER) + || username.equalsIgnoreCase(UserModel.ANONYMOUS.username)); + } + /** * Returns the cookie value for the specified user. * diff --git a/src/main/java/com/gitblit/service/FederationPullService.java b/src/main/java/com/gitblit/service/FederationPullService.java index e2a50f29..629cbf94 100644 --- a/src/main/java/com/gitblit/service/FederationPullService.java +++ b/src/main/java/com/gitblit/service/FederationPullService.java @@ -31,10 +31,10 @@ import com.gitblit.Constants; import com.gitblit.Constants.AccessPermission; import com.gitblit.Constants.FederationPullStatus; import com.gitblit.Constants.FederationStrategy; -import com.gitblit.GitBlit; import com.gitblit.GitBlitException.ForbiddenException; import com.gitblit.IUserService; import com.gitblit.Keys; +import com.gitblit.manager.IGitblit; import com.gitblit.models.FederationModel; import com.gitblit.models.RefModel; import com.gitblit.models.RepositoryModel; @@ -49,9 +49,9 @@ import com.gitblit.utils.StringUtils; public abstract class FederationPullService implements Runnable { - Logger logger = LoggerFactory.getLogger(getClass()); + final Logger logger = LoggerFactory.getLogger(getClass()); - GitBlit gitblit; + final IGitblit gitblit; private final List registrations; @@ -62,8 +62,8 @@ public abstract class FederationPullService implements Runnable { * @param provider * @param registration */ - public FederationPullService(FederationModel registration) { - this(Arrays.asList(registration)); + public FederationPullService(IGitblit gitblit, FederationModel registration) { + this(gitblit, Arrays.asList(registration)); } /** @@ -77,7 +77,8 @@ public abstract class FederationPullService implements Runnable { * if true, registrations are rescheduled in perpetuity. if * false, the federation pull operation is executed once. */ - public FederationPullService(List registrations) { + public FederationPullService(IGitblit gitblit, List registrations) { + this.gitblit = gitblit; this.registrations = registrations; } diff --git a/src/main/java/com/gitblit/servlet/FederationServlet.java b/src/main/java/com/gitblit/servlet/FederationServlet.java index e86e5d66..4d3cbbe2 100644 --- a/src/main/java/com/gitblit/servlet/FederationServlet.java +++ b/src/main/java/com/gitblit/servlet/FederationServlet.java @@ -29,13 +29,9 @@ import javax.inject.Inject; import javax.inject.Singleton; import javax.servlet.http.HttpServletResponse; -import com.gitblit.Constants; +import com.gitblit.Constants.FederationRequest; import com.gitblit.IStoredSettings; import com.gitblit.Keys; -import com.gitblit.Constants.FederationRequest; -import com.gitblit.Keys.federation; -import com.gitblit.Keys.git; -import com.gitblit.Keys.groovy; import com.gitblit.manager.IFederationManager; import com.gitblit.manager.IRepositoryManager; import com.gitblit.manager.IRuntimeManager; diff --git a/src/main/java/com/gitblit/servlet/GitFilter.java b/src/main/java/com/gitblit/servlet/GitFilter.java index 402636ed..15facbe8 100644 --- a/src/main/java/com/gitblit/servlet/GitFilter.java +++ b/src/main/java/com/gitblit/servlet/GitFilter.java @@ -18,6 +18,7 @@ package com.gitblit.servlet; import java.text.MessageFormat; import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; import com.gitblit.Constants.AccessRestrictionType; import com.gitblit.Constants.AuthorizationControl; @@ -25,8 +26,10 @@ import com.gitblit.GitBlitException; import com.gitblit.IStoredSettings; import com.gitblit.Keys; import com.gitblit.manager.IAuthenticationManager; +import com.gitblit.manager.IFederationManager; import com.gitblit.manager.IRepositoryManager; import com.gitblit.manager.IRuntimeManager; +import com.gitblit.manager.IUserManager; import com.gitblit.models.RepositoryModel; import com.gitblit.models.UserModel; import com.gitblit.utils.StringUtils; @@ -50,14 +53,22 @@ public class GitFilter extends AccessRestrictionFilter { private final IStoredSettings settings; + private final IUserManager userManager; + + private final IFederationManager federationManager; + @Inject public GitFilter( IRuntimeManager runtimeManager, + IUserManager userManager, IAuthenticationManager authenticationManager, - IRepositoryManager repositoryManager) { + IRepositoryManager repositoryManager, + IFederationManager federationManager) { super(runtimeManager, authenticationManager, repositoryManager); this.settings = runtimeManager.getSettings(); + this.userManager = userManager; + this.federationManager = federationManager; } /** @@ -113,6 +124,21 @@ public class GitFilter extends AccessRestrictionFilter { return null; } + /** + * Returns the user making the request, if the user has authenticated. + * + * @param httpRequest + * @return user + */ + @Override + protected UserModel getUser(HttpServletRequest httpRequest) { + UserModel user = authenticationManager.authenticate(httpRequest, requiresClientCertificate()); + if (user == null) { + user = federationManager.authenticate(httpRequest); + } + return user; + } + /** * Determine if a non-existing repository can be created using this filter. * -- 2.39.5