build.moxie
@@ -129,7 +129,7 @@ - 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 @@ - 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 build.xml
@@ -279,7 +279,8 @@ <!-- generate jar by traversing the class hierarchy of the specified classes, exclude any classes in classpath jars --> <mx:genjar tag="" includeresources="false" excludeClasspathJars="true" destfile="${project.targetDirectory}/fedclient.jar"> destfile="${project.targetDirectory}/fedclient.jar" excludes="**/.class,**/*.java, **/Thumbs.db, **/*.mkd, com/gitblit/wicket/**"> <mainclass name="com.gitblit.FederationClient" /> <class name="com.gitblit.Keys" /> <launcher paths="ext" /> src/main/java/com/gitblit/DaggerModule.java
@@ -149,13 +149,11 @@ @Provides @Singleton IFederationManager provideFederationManager( IRuntimeManager runtimeManager, INotificationManager notificationManager, IUserManager userManager, IRepositoryManager repositoryManager) { return new FederationManager( runtimeManager, notificationManager, userManager, repositoryManager); } src/main/java/com/gitblit/FederationClient.java
@@ -17,6 +17,7 @@ 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.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 @@ } // 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 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<String> toAddresses) { } @Override public void sendMail(String subject, String message, String... toAddresses) { } @Override public void sendHtmlMail(String subject, String message, Collection<String> toAddresses) { } @Override public void sendHtmlMail(String subject, String message, String... toAddresses) { } } } 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<Collection<GitClientApplication>> clientApplications = new ObjectCache<Collection<GitClientApplication>>(); 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 @@ 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,167 +77,9 @@ @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<String> users = repositoryManager.getRepositoryUsers(repository); List<UserModel> cloneUsers = new ArrayList<UserModel>(); 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<String> teams = repositoryManager.getRepositoryTeams(repository); List<TeamModel> cloneTeams = new ArrayList<TeamModel>(); 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!"); } } /** @@ -352,750 +130,5 @@ } } 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<GitClientApplication> 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<GitClientApplication> 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<GitClientApplication> 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<GitClientApplication> readClientApplications(InputStream is) { try { Type type = new TypeToken<Collection<GitClientApplication>>() { }.getType(); InputStreamReader reader = new InputStreamReader(is); Gson gson = JsonUtils.gson(); Collection<GitClientApplication> 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<String, SettingModel> */ 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<String> 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<String, String> 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<String> 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<String> 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<String> getAllUsernames() { return userManager.getAllUsernames(); } @Override public List<UserModel> 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<TeamModel> 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<UserModel> 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<String> getAllTeamNames() { return userManager.getAllTeamNames(); } @Override public List<String> getTeamNamesForRepositoryRole(String role) { return userManager.getTeamNamesForRepositoryRole(role); } @Override public boolean updateTeamModel(TeamModel model) { return userManager.updateTeamModel(model); } @Override public boolean updateTeamModels(Collection<TeamModel> 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<String> 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<RegistrantAccessPermission> getUserAccessPermissions(UserModel user) { return repositoryManager.getUserAccessPermissions(user); } @Override public List<RegistrantAccessPermission> getUserAccessPermissions(RepositoryModel repository) { return repositoryManager.getUserAccessPermissions(repository); } @Override public boolean setUserAccessPermissions(RepositoryModel repository, Collection<RegistrantAccessPermission> permissions) { return repositoryManager.setUserAccessPermissions(repository, permissions); } @Override public List<String> getRepositoryUsers(RepositoryModel repository) { return repositoryManager.getRepositoryUsers(repository); } @Override public List<RegistrantAccessPermission> getTeamAccessPermissions(RepositoryModel repository) { return repositoryManager.getTeamAccessPermissions(repository); } @Override public boolean setTeamAccessPermissions(RepositoryModel repository, Collection<RegistrantAccessPermission> permissions) { return repositoryManager.setTeamAccessPermissions(repository, permissions); } @Override public List<String> 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<String> 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<RepositoryModel> 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<Metric> 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<String> getAllScripts() { return repositoryManager.getAllScripts(); } @Override public List<String> getPreReceiveScriptsInherited(RepositoryModel repository) { return repositoryManager.getPreReceiveScriptsInherited(repository); } @Override public List<String> getPreReceiveScriptsUnused(RepositoryModel repository) { return repositoryManager.getPreReceiveScriptsUnused(repository); } @Override public List<String> getPostReceiveScriptsInherited(RepositoryModel repository) { return repositoryManager.getPostReceiveScriptsInherited(repository); } @Override public List<String> getPostReceiveScriptsUnused(RepositoryModel repository) { return repositoryManager.getPostReceiveScriptsUnused(repository); } @Override public List<SearchResult> search(String query, int page, int pageSize, List<String> 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<ProjectModel> 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<ProjectModel> getProjectModels(List<RepositoryModel> 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<FederationModel> getFederationRegistrations() { return federationManager.getFederationRegistrations(); } @Override public FederationModel getFederationRegistration(String url, String name) { return federationManager.getFederationRegistration(url, name); } @Override public List<FederationSet> getFederationSets(String gitblitUrl) { return federationManager.getFederationSets(gitblitUrl); } @Override public List<String> 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<FederationModel> getFederationResultRegistrations() { return federationManager.getFederationResultRegistrations(); } @Override public boolean submitFederationProposal(FederationProposal proposal, String gitblitUrl) { return federationManager.submitFederationProposal(proposal, gitblitUrl); } @Override public List<FederationProposal> getPendingFederationProposals() { return federationManager.getPendingFederationProposals(); } @Override public Map<String, RepositoryModel> 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); } } src/main/java/com/gitblit/git/GitDaemon.java
@@ -67,9 +67,9 @@ 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 @@ private ReceivePackFactory<GitDaemonClient> receivePackFactory; public GitDaemon(GitBlit gitblit) { public GitDaemon(IGitblit gitblit) { IStoredSettings settings = gitblit.getSettings(); int port = settings.getInteger(Keys.git.daemonPort, 0); src/main/java/com/gitblit/manager/AuthenticationManager.java
@@ -183,7 +183,7 @@ 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 @@ // 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<String> tokens = getFederationTokens(); // if (tokens.contains(pw)) { // return getFederationUser(); // } // } // } // try local authentication UserModel user = userManager.getUserModel(usernameDecoded); @@ -489,23 +480,4 @@ } 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; // } } src/main/java/com/gitblit/manager/FederationManager.java
@@ -17,6 +17,7 @@ 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; @@ -24,6 +25,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.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 FederationManager( IRuntimeManager runtimeManager, INotificationManager notificationManager, IUserManager userManager, IRepositoryManager repositoryManager) { this.settings = runtimeManager.getSettings(); @@ -100,6 +103,17 @@ } @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 UserModel federationUser = new UserModel(Constants.FEDERATION_USER); @@ -108,9 +122,30 @@ } @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<String> tokens = getFederationTokens(); if (tokens.contains(password)) { return getFederationUser(); } } } } } return null; } /** src/main/java/com/gitblit/manager/GitblitManager.java
New file @@ -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<Collection<GitClientApplication>> clientApplications = new ObjectCache<Collection<GitClientApplication>>(); 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<String> users = repositoryManager.getRepositoryUsers(repository); List<UserModel> cloneUsers = new ArrayList<UserModel>(); 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<String> teams = repositoryManager.getRepositoryTeams(repository); List<TeamModel> cloneTeams = new ArrayList<TeamModel>(); 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<RepositoryUrl> getRepositoryUrls(HttpServletRequest request, UserModel user, RepositoryModel repository) { if (user == null) { user = UserModel.ANONYMOUS; } String username = StringUtils.encodeUsername(UserModel.ANONYMOUS.equals(user) ? "" : user.username); List<RepositoryUrl> list = new ArrayList<RepositoryUrl>(); // 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<GitClientApplication> 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<GitClientApplication> 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<GitClientApplication> 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<GitClientApplication> readClientApplications(InputStream is) { try { Type type = new TypeToken<Collection<GitClientApplication>>() { }.getType(); InputStreamReader reader = new InputStreamReader(is); Gson gson = JsonUtils.gson(); Collection<GitClientApplication> 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<String, SettingModel> */ 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<String> 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<String, String> 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<String> 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<String> 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<String> getAllUsernames() { return userManager.getAllUsernames(); } @Override public List<UserModel> 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<TeamModel> 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<UserModel> 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<String> getAllTeamNames() { return userManager.getAllTeamNames(); } @Override public List<String> getTeamNamesForRepositoryRole(String role) { return userManager.getTeamNamesForRepositoryRole(role); } @Override public boolean updateTeamModel(TeamModel model) { return userManager.updateTeamModel(model); } @Override public boolean updateTeamModels(Collection<TeamModel> 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<String> 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<RegistrantAccessPermission> getUserAccessPermissions(UserModel user) { return repositoryManager.getUserAccessPermissions(user); } @Override public List<RegistrantAccessPermission> getUserAccessPermissions(RepositoryModel repository) { return repositoryManager.getUserAccessPermissions(repository); } @Override public boolean setUserAccessPermissions(RepositoryModel repository, Collection<RegistrantAccessPermission> permissions) { return repositoryManager.setUserAccessPermissions(repository, permissions); } @Override public List<String> getRepositoryUsers(RepositoryModel repository) { return repositoryManager.getRepositoryUsers(repository); } @Override public List<RegistrantAccessPermission> getTeamAccessPermissions(RepositoryModel repository) { return repositoryManager.getTeamAccessPermissions(repository); } @Override public boolean setTeamAccessPermissions(RepositoryModel repository, Collection<RegistrantAccessPermission> permissions) { return repositoryManager.setTeamAccessPermissions(repository, permissions); } @Override public List<String> 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<String> 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<RepositoryModel> 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<Metric> 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<String> getAllScripts() { return repositoryManager.getAllScripts(); } @Override public List<String> getPreReceiveScriptsInherited(RepositoryModel repository) { return repositoryManager.getPreReceiveScriptsInherited(repository); } @Override public List<String> getPreReceiveScriptsUnused(RepositoryModel repository) { return repositoryManager.getPreReceiveScriptsUnused(repository); } @Override public List<String> getPostReceiveScriptsInherited(RepositoryModel repository) { return repositoryManager.getPostReceiveScriptsInherited(repository); } @Override public List<String> getPostReceiveScriptsUnused(RepositoryModel repository) { return repositoryManager.getPostReceiveScriptsUnused(repository); } @Override public List<SearchResult> search(String query, int page, int pageSize, List<String> 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<ProjectModel> 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<ProjectModel> getProjectModels(List<RepositoryModel> 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<FederationModel> getFederationRegistrations() { return federationManager.getFederationRegistrations(); } @Override public FederationModel getFederationRegistration(String url, String name) { return federationManager.getFederationRegistration(url, name); } @Override public List<FederationSet> getFederationSets(String gitblitUrl) { return federationManager.getFederationSets(gitblitUrl); } @Override public List<String> 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<FederationModel> getFederationResultRegistrations() { return federationManager.getFederationResultRegistrations(); } @Override public boolean submitFederationProposal(FederationProposal proposal, String gitblitUrl) { return federationManager.submitFederationProposal(proposal, gitblitUrl); } @Override public List<FederationProposal> getPendingFederationProposals() { return federationManager.getPendingFederationProposals(); } @Override public Map<String, RepositoryModel> 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); } } src/main/java/com/gitblit/manager/IFederationManager.java
@@ -19,6 +19,8 @@ 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 @@ */ 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 src/main/java/com/gitblit/manager/IUserManager.java
@@ -19,5 +19,12 @@ 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); } src/main/java/com/gitblit/manager/ServicesManager.java
@@ -32,7 +32,6 @@ 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 @@ 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 @@ private class FederationPuller extends FederationPullService { public FederationPuller(FederationModel registration) { super(Arrays.asList(registration)); super(gitblit, Arrays.asList(registration)); } public FederationPuller(List<FederationModel> registrations) { super(registrations); super(gitblit, registrations); } @Override src/main/java/com/gitblit/manager/UserManager.java
@@ -28,6 +28,7 @@ import org.slf4j.LoggerFactory; import com.gitblit.ConfigUserService; import com.gitblit.Constants; import com.gitblit.IStoredSettings; import com.gitblit.IUserService; import com.gitblit.Keys; @@ -149,6 +150,19 @@ } /** * 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. * * @param model src/main/java/com/gitblit/service/FederationPullService.java
@@ -31,10 +31,10 @@ 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 @@ 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<FederationModel> registrations; @@ -62,8 +62,8 @@ * @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 @@ * if true, registrations are rescheduled in perpetuity. if * false, the federation pull operation is executed once. */ public FederationPullService(List<FederationModel> registrations) { public FederationPullService(IGitblit gitblit, List<FederationModel> registrations) { this.gitblit = gitblit; this.registrations = registrations; } src/main/java/com/gitblit/servlet/FederationServlet.java
@@ -29,13 +29,9 @@ 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; src/main/java/com/gitblit/servlet/GitFilter.java
@@ -18,6 +18,7 @@ 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.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 @@ 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; } /** @@ -114,6 +125,21 @@ } /** * 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. * * @return true if the server allows repository creation on-push