]> source.dussan.org Git - gitblit.git/commitdiff
Refactor managers and authentication for federation
authorJames Moger <james.moger@gitblit.com>
Mon, 25 Nov 2013 15:07:46 +0000 (10:07 -0500)
committerJames Moger <james.moger@gitblit.com>
Fri, 29 Nov 2013 16:05:51 +0000 (11:05 -0500)
Change-Id: I5ff18b2768095fb14e7fbece2e756115829abbde

16 files changed:
build.moxie
build.xml
src/main/java/com/gitblit/DaggerModule.java
src/main/java/com/gitblit/FederationClient.java
src/main/java/com/gitblit/GitBlit.java
src/main/java/com/gitblit/git/GitDaemon.java
src/main/java/com/gitblit/manager/AuthenticationManager.java
src/main/java/com/gitblit/manager/FederationManager.java
src/main/java/com/gitblit/manager/GitblitManager.java [new file with mode: 0644]
src/main/java/com/gitblit/manager/IFederationManager.java
src/main/java/com/gitblit/manager/IUserManager.java
src/main/java/com/gitblit/manager/ServicesManager.java
src/main/java/com/gitblit/manager/UserManager.java
src/main/java/com/gitblit/service/FederationPullService.java
src/main/java/com/gitblit/servlet/FederationServlet.java
src/main/java/com/gitblit/servlet/GitFilter.java

index acc1afb11d92ef7c3fd0227eaa7d35334b512bb3..b09c7a51633d723fe601e468bb4bfae54ca32648 100644 (file)
@@ -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
index ab6699bc1dafd8805a16e263faeaf937fccbd3d1..eb97cebcc06727f116d46fe19decbe0501b8190b 100644 (file)
--- a/build.xml
+++ b/build.xml
                <!-- generate jar by traversing the class hierarchy of the specified\r
                         classes, exclude any classes in classpath jars -->\r
                <mx:genjar tag="" includeresources="false" excludeClasspathJars="true"\r
-                       destfile="${project.targetDirectory}/fedclient.jar">\r
+                       destfile="${project.targetDirectory}/fedclient.jar"\r
+                       excludes="**/.class,**/*.java, **/Thumbs.db, **/*.mkd, com/gitblit/wicket/**">\r
                        <mainclass name="com.gitblit.FederationClient" />\r
                        <class name="com.gitblit.Keys" />\r
                        <launcher paths="ext" />\r
index 135fafbf277f8fca1e395be8c64774573ee5f7aa..857f36a22792aeee40bbeb1122754db7610c6da8 100644 (file)
@@ -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);
        }
 
index 66b378ab696389b196eecf9170c612d7fb4e618f..c275746386751bbbe1229118cba0168ec5ed5c96 100644 (file)
@@ -17,6 +17,7 @@ package com.gitblit;
 \r
 import java.io.File;\r
 import java.util.ArrayList;\r
+import java.util.Collection;\r
 import java.util.List;\r
 \r
 import com.beust.jcommander.JCommander;\r
@@ -24,7 +25,9 @@ import com.beust.jcommander.Parameter;
 import com.beust.jcommander.ParameterException;\r
 import com.beust.jcommander.Parameters;\r
 import com.gitblit.manager.FederationManager;\r
-import com.gitblit.manager.NotificationManager;\r
+import com.gitblit.manager.GitblitManager;\r
+import com.gitblit.manager.IGitblit;\r
+import com.gitblit.manager.INotificationManager;\r
 import com.gitblit.manager.RepositoryManager;\r
 import com.gitblit.manager.RuntimeManager;\r
 import com.gitblit.manager.UserManager;\r
@@ -89,14 +92,14 @@ public class FederationClient {
                }\r
 \r
                // configure the Gitblit singleton for minimal, non-server operation\r
-               RuntimeManager runtime = new RuntimeManager(settings);\r
-               runtime.setBaseFolder(baseFolder);\r
-               NotificationManager notifications = new NotificationManager(settings).start();\r
+               RuntimeManager runtime = new RuntimeManager(settings, baseFolder).start();\r
+               NoopNotificationManager notifications = new NoopNotificationManager().start();\r
                UserManager users = new UserManager(runtime).start();\r
                RepositoryManager repositories = new RepositoryManager(runtime, users).start();\r
-               FederationManager federation = new FederationManager(runtime, notifications, users, repositories).start();\r
+               FederationManager federation = new FederationManager(runtime, notifications, repositories).start();\r
+               IGitblit gitblit = new GitblitManager(runtime, notifications, users, null, repositories, null, federation);\r
 \r
-               FederationPullService puller = new FederationPullService(federation.getFederationRegistrations()) {\r
+               FederationPullService puller = new FederationPullService(gitblit, federation.getFederationRegistrations()) {\r
                        @Override\r
                        public void reschedule(FederationModel registration) {\r
                                // NOOP\r
@@ -153,4 +156,37 @@ public class FederationClient {
                public String repositoriesFolder;\r
 \r
        }\r
+\r
+       private static class NoopNotificationManager implements INotificationManager {\r
+\r
+               @Override\r
+               public NoopNotificationManager start() {\r
+                       return this;\r
+               }\r
+\r
+               @Override\r
+               public NoopNotificationManager stop() {\r
+                       return this;\r
+               }\r
+\r
+               @Override\r
+               public void sendMailToAdministrators(String subject, String message) {\r
+               }\r
+\r
+               @Override\r
+               public void sendMail(String subject, String message, Collection<String> toAddresses) {\r
+               }\r
+\r
+               @Override\r
+               public void sendMail(String subject, String message, String... toAddresses) {\r
+               }\r
+\r
+               @Override\r
+               public void sendHtmlMail(String subject, String message, Collection<String> toAddresses) {\r
+               }\r
+\r
+               @Override\r
+               public void sendHtmlMail(String subject, String message, String... toAddresses) {\r
+               }\r
+       }\r
 }\r
index d07ac9a74cf928174f98db1c6534c6ee987f1756..da80a746b4b90646e2278c4bbf6c15eb0f40a499 100644 (file)
  */
 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 @@ 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<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.
         *
@@ -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<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);
-       }
 }
index 7273f387859f85d0b2e7d1dedd3ad17e86d0668a..d026b5ed38d1a24c23e39beb43baed90692236fa 100644 (file)
@@ -67,9 +67,9 @@ import org.eclipse.jgit.transport.resolver.UploadPackFactory;
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
 \r
-import com.gitblit.GitBlit;\r
 import com.gitblit.IStoredSettings;\r
 import com.gitblit.Keys;\r
+import com.gitblit.manager.IGitblit;\r
 import com.gitblit.utils.StringUtils;\r
 \r
 /**\r
@@ -108,7 +108,7 @@ public class GitDaemon {
 \r
        private ReceivePackFactory<GitDaemonClient> receivePackFactory;\r
 \r
-       public GitDaemon(GitBlit gitblit) {\r
+       public GitDaemon(IGitblit gitblit) {\r
 \r
                IStoredSettings settings = gitblit.getSettings();\r
                int port = settings.getInteger(Keys.git.daemonPort, 0);\r
index 6e541c458d5309d3d90ddc319dfa0564a94a5a14..8c66ce59c8031649211b5678398c9f2c88bc76e2 100644 (file)
@@ -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<String> 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;
-//     }
 }
index 568e87fce1decc4f9e432017949d1717b3b941b1..95d38af10bed735a086b5f283d7b03069900c536 100644 (file)
@@ -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<String> 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 (file)
index 0000000..b391181
--- /dev/null
@@ -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);
+       }
+}
index 5afdeea1a3fee98a547c8030e9f52a757ee8cfc0..d5880c0048e027941387d982b65092a2223b301f 100644 (file)
@@ -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
index 5815bcafce6c065e0c4003137b3e5815cf6d661d..945d6a854536dd56a10b2b77f9c4df6ac1656b52 100644 (file)
@@ -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
index 6cc945621e5984bc2112c960299030224f992fd7..8107a7d8a41c6df55f35c77fc4943179b1502c6c 100644 (file)
@@ -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<FederationModel> registrations) {
-                       super(registrations);
+                       super(gitblit, registrations);
                }
 
                @Override
index 3ca62e232f260bdfa5a84c25ebd4d4c4247c3eae..19943d717e7477bb3bbaf2aec0440196bd719535 100644 (file)
@@ -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.
         *
index e2a50f29f62530e6bcaceb82660e2502d49077e5..629cbf94c0eb552c2b64c29fd91ee3a0c470b688 100644 (file)
@@ -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<FederationModel> 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<FederationModel> registrations) {
+       public FederationPullService(IGitblit gitblit, List<FederationModel> registrations) {
+               this.gitblit = gitblit;
                this.registrations = registrations;
        }
 
index e86e5d6679dc52336b27a0477a0b867c559220a3..4d3cbbe288b80df427df05417f49eaa2f7206c2c 100644 (file)
@@ -29,13 +29,9 @@ import javax.inject.Inject;
 import javax.inject.Singleton;\r
 import javax.servlet.http.HttpServletResponse;\r
 \r
-import com.gitblit.Constants;\r
+import com.gitblit.Constants.FederationRequest;\r
 import com.gitblit.IStoredSettings;\r
 import com.gitblit.Keys;\r
-import com.gitblit.Constants.FederationRequest;\r
-import com.gitblit.Keys.federation;\r
-import com.gitblit.Keys.git;\r
-import com.gitblit.Keys.groovy;\r
 import com.gitblit.manager.IFederationManager;\r
 import com.gitblit.manager.IRepositoryManager;\r
 import com.gitblit.manager.IRuntimeManager;\r
index 402636ed294514e25464c83d9ad1c1e734fc6913..15facbe8d1ad16235d6d5fb7617e2b3efae7300d 100644 (file)
@@ -18,6 +18,7 @@ package com.gitblit.servlet;
 import java.text.MessageFormat;\r
 \r
 import javax.inject.Inject;\r
+import javax.servlet.http.HttpServletRequest;\r
 \r
 import com.gitblit.Constants.AccessRestrictionType;\r
 import com.gitblit.Constants.AuthorizationControl;\r
@@ -25,8 +26,10 @@ import com.gitblit.GitBlitException;
 import com.gitblit.IStoredSettings;\r
 import com.gitblit.Keys;\r
 import com.gitblit.manager.IAuthenticationManager;\r
+import com.gitblit.manager.IFederationManager;\r
 import com.gitblit.manager.IRepositoryManager;\r
 import com.gitblit.manager.IRuntimeManager;\r
+import com.gitblit.manager.IUserManager;\r
 import com.gitblit.models.RepositoryModel;\r
 import com.gitblit.models.UserModel;\r
 import com.gitblit.utils.StringUtils;\r
@@ -50,14 +53,22 @@ public class GitFilter extends AccessRestrictionFilter {
 \r
        private final IStoredSettings settings;\r
 \r
+       private final IUserManager userManager;\r
+\r
+       private final IFederationManager federationManager;\r
+\r
        @Inject\r
        public GitFilter(\r
                        IRuntimeManager runtimeManager,\r
+                       IUserManager userManager,\r
                        IAuthenticationManager authenticationManager,\r
-                       IRepositoryManager repositoryManager) {\r
+                       IRepositoryManager repositoryManager,\r
+                       IFederationManager federationManager) {\r
 \r
                super(runtimeManager, authenticationManager, repositoryManager);\r
                this.settings = runtimeManager.getSettings();\r
+               this.userManager = userManager;\r
+               this.federationManager = federationManager;\r
        }\r
 \r
        /**\r
@@ -113,6 +124,21 @@ public class GitFilter extends AccessRestrictionFilter {
                return null;\r
        }\r
 \r
+       /**\r
+        * Returns the user making the request, if the user has authenticated.\r
+        *\r
+        * @param httpRequest\r
+        * @return user\r
+        */\r
+       @Override\r
+       protected UserModel getUser(HttpServletRequest httpRequest) {\r
+               UserModel user = authenticationManager.authenticate(httpRequest, requiresClientCertificate());\r
+               if (user == null) {\r
+                       user = federationManager.authenticate(httpRequest);\r
+               }\r
+               return user;\r
+       }\r
+\r
        /**\r
         * Determine if a non-existing repository can be created using this filter.\r
         *\r