]> source.dussan.org Git - gitblit.git/commitdiff
Extract services manager into a top-level injectable manager
authorJames Moger <james.moger@gitblit.com>
Wed, 2 Jul 2014 20:21:16 +0000 (16:21 -0400)
committerJames Moger <james.moger@gitblit.com>
Thu, 3 Jul 2014 21:00:40 +0000 (17:00 -0400)
18 files changed:
src/main/java/com/gitblit/GitBlit.java
src/main/java/com/gitblit/guice/CoreModule.java
src/main/java/com/gitblit/guice/WorkQueueProvider.java [new file with mode: 0644]
src/main/java/com/gitblit/manager/GitblitManager.java
src/main/java/com/gitblit/manager/IGitblit.java
src/main/java/com/gitblit/manager/IRuntimeManager.java
src/main/java/com/gitblit/manager/IServicesManager.java [new file with mode: 0644]
src/main/java/com/gitblit/manager/RepositoryManager.java
src/main/java/com/gitblit/manager/RuntimeManager.java
src/main/java/com/gitblit/manager/ServicesManager.java
src/main/java/com/gitblit/servlet/GitblitContext.java
src/main/java/com/gitblit/wicket/GitBlitWebApp.java
src/main/java/com/gitblit/wicket/GitblitWicketApp.java
src/main/java/com/gitblit/wicket/pages/EmptyRepositoryPage.java
src/main/java/com/gitblit/wicket/pages/TicketPage.java
src/main/java/com/gitblit/wicket/pages/UserPage.java
src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.java
src/test/java/com/gitblit/tests/mock/MockRuntimeManager.java

index a39b0fcd507ed9104bd928a8a641972e3d4b6f39..edad32eff37cc4977773177e039358af505d99a4 100644 (file)
@@ -25,10 +25,7 @@ import java.util.List;
 import java.util.Set;
 
 import com.google.inject.Inject;
-import javax.servlet.http.HttpServletRequest;
 
-import com.gitblit.Constants.AccessPermission;
-import com.gitblit.Constants.Transport;
 import com.gitblit.manager.GitblitManager;
 import com.gitblit.manager.IAuthenticationManager;
 import com.gitblit.manager.IFederationManager;
@@ -39,9 +36,7 @@ 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.RepositoryModel;
-import com.gitblit.models.RepositoryUrl;
 import com.gitblit.models.UserModel;
 import com.gitblit.tickets.ITicketService;
 import com.gitblit.tickets.NullTicketService;
@@ -62,8 +57,6 @@ public class GitBlit extends GitblitManager {
 
        private final Injector injector;
 
-       private final ServicesManager servicesManager;
-
        private ITicketService ticketService;
 
        @Inject
@@ -89,15 +82,11 @@ public class GitBlit extends GitblitManager {
                                federationManager);
 
                this.injector = Guice.createInjector(getModules());
-
-               this.servicesManager = new ServicesManager(this);
        }
 
        @Override
        public GitBlit start() {
                super.start();
-               logger.info("Starting services manager...");
-               servicesManager.start();
                configureTicketService();
                return this;
        }
@@ -105,184 +94,14 @@ public class GitBlit extends GitblitManager {
        @Override
        public GitBlit stop() {
                super.stop();
-               servicesManager.stop();
                ticketService.stop();
                return this;
        }
 
-       @Override
-       public boolean isServingRepositories() {
-               return servicesManager.isServingRepositories();
-       }
-
-       @Override
-       public boolean isServingHTTP() {
-               return servicesManager.isServingHTTP();
-       }
-
-       @Override
-       public boolean isServingGIT() {
-               return servicesManager.isServingGIT();
-       }
-
-       @Override
-       public boolean isServingSSH() {
-               return servicesManager.isServingSSH();
-       }
-
        protected AbstractModule [] getModules() {
                return new AbstractModule [] { new GitBlitModule()};
        }
 
-       protected boolean acceptPush(Transport byTransport) {
-               if (byTransport == null) {
-                       logger.info("Unknown transport, push rejected!");
-                       return false;
-               }
-
-               Set<Transport> transports = new HashSet<Transport>();
-               for (String value : getSettings().getStrings(Keys.git.acceptedPushTransports)) {
-                       Transport transport = Transport.fromString(value);
-                       if (transport == null) {
-                               logger.info(String.format("Ignoring unknown registered transport %s", value));
-                               continue;
-                       }
-
-                       transports.add(transport);
-               }
-
-               if (transports.isEmpty()) {
-                       // no transports are explicitly specified, all are acceptable
-                       return true;
-               }
-
-               // verify that the transport is permitted
-               return transports.contains(byTransport);
-       }
-
-       /**
-        * 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)) {
-                               Transport transport = Transport.fromString(request.getScheme());
-                               if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(transport)) {
-                                       // downgrade the repo permission for this transport
-                                       // because it is not an acceptable PUSH transport
-                                       permission = AccessPermission.CLONE;
-                               }
-                               list.add(new RepositoryUrl(getRepositoryUrl(request, username, repository), permission));
-                       }
-               }
-
-               // ssh daemon url
-               String sshDaemonUrl = servicesManager.getSshDaemonUrl(request, user, repository);
-               if (!StringUtils.isEmpty(sshDaemonUrl)) {
-                       AccessPermission permission = user.getRepositoryPermission(repository).permission;
-                       if (permission.exceeds(AccessPermission.NONE)) {
-                               if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(Transport.SSH)) {
-                                       // downgrade the repo permission for this transport
-                                       // because it is not an acceptable PUSH transport
-                                       permission = AccessPermission.CLONE;
-                               }
-
-                               list.add(new RepositoryUrl(sshDaemonUrl, permission));
-                       }
-               }
-
-               // git daemon url
-               String gitDaemonUrl = servicesManager.getGitDaemonUrl(request, user, repository);
-               if (!StringUtils.isEmpty(gitDaemonUrl)) {
-                       AccessPermission permission = servicesManager.getGitDaemonAccessPermission(user, repository);
-                       if (permission.exceeds(AccessPermission.NONE)) {
-                               if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(Transport.GIT)) {
-                                       // downgrade the repo permission for this transport
-                                       // because it is not an acceptable PUSH transport
-                                       permission = AccessPermission.CLONE;
-                               }
-                               list.add(new RepositoryUrl(gitDaemonUrl, 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));
-                       }
-               }
-
-               // sort transports by highest permission and then by transport security
-               Collections.sort(list, new Comparator<RepositoryUrl>() {
-
-                       @Override
-                       public int compare(RepositoryUrl o1, RepositoryUrl o2) {
-                               if (!o1.isExternal() && o2.isExternal()) {
-                                       // prefer Gitblit over external
-                                       return -1;
-                               } else if (o1.isExternal() && !o2.isExternal()) {
-                                       // prefer Gitblit over external
-                                       return 1;
-                               } else if (o1.isExternal() && o2.isExternal()) {
-                                       // sort by Transport ordinal
-                                       return o1.transport.compareTo(o2.transport);
-                               } else if (o1.permission.exceeds(o2.permission)) {
-                                       // prefer highest permission
-                                       return -1;
-                               } else if (o2.permission.exceeds(o1.permission)) {
-                                       // prefer highest permission
-                                       return 1;
-                               }
-
-                               // prefer more secure transports
-                               return o1.transport.compareTo(o2.transport);
-                       }
-               });
-
-               // consider the user's transport preference
-               RepositoryUrl preferredUrl = null;
-               Transport preferredTransport = user.getPreferences().getTransport();
-               if (preferredTransport != null) {
-                       Iterator<RepositoryUrl> itr = list.iterator();
-                       while (itr.hasNext()) {
-                               RepositoryUrl url = itr.next();
-                               if (url.transport.equals(preferredTransport)) {
-                                       itr.remove();
-                                       preferredUrl = url;
-                                       break;
-                               }
-                       }
-               }
-               if (preferredUrl != null) {
-                       list.add(0, preferredUrl);
-               }
-
-               return list;
-       }
-
        /**
         * Detect renames and reindex as appropriate.
         */
index 89be94f779faeceff2038590f6a436de17f585e2..03cdbf227c346f942e171887fa887b1431f3c6da 100644 (file)
@@ -31,18 +31,21 @@ import com.gitblit.manager.IPluginManager;
 import com.gitblit.manager.IProjectManager;
 import com.gitblit.manager.IRepositoryManager;
 import com.gitblit.manager.IRuntimeManager;
+import com.gitblit.manager.IServicesManager;
 import com.gitblit.manager.IUserManager;
 import com.gitblit.manager.NotificationManager;
 import com.gitblit.manager.PluginManager;
 import com.gitblit.manager.ProjectManager;
 import com.gitblit.manager.RepositoryManager;
 import com.gitblit.manager.RuntimeManager;
+import com.gitblit.manager.ServicesManager;
 import com.gitblit.manager.UserManager;
 import com.gitblit.transport.ssh.FileKeyManager;
 import com.gitblit.transport.ssh.IPublicKeyManager;
 import com.gitblit.transport.ssh.MemoryKeyManager;
 import com.gitblit.transport.ssh.NullKeyManager;
 import com.gitblit.utils.StringUtils;
+import com.gitblit.utils.WorkQueue;
 import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
 
@@ -59,6 +62,9 @@ public class CoreModule extends AbstractModule {
 
                bind(IStoredSettings.class).toInstance(new FileSettings());
 
+               // bind complex providers
+               bind(WorkQueue.class).toProvider(WorkQueueProvider.class);
+               
                // core managers
                bind(IRuntimeManager.class).to(RuntimeManager.class).in(Singleton.class);
                bind(IPluginManager.class).to(PluginManager.class).in(Singleton.class);
@@ -71,6 +77,9 @@ public class CoreModule extends AbstractModule {
 
                // the monolithic manager
                bind(IGitblit.class).to(GitBlit.class).in(Singleton.class);
+
+               // manager for long-running daemons and services
+               bind(IServicesManager.class).to(ServicesManager.class);
        }
 
        @Provides
diff --git a/src/main/java/com/gitblit/guice/WorkQueueProvider.java b/src/main/java/com/gitblit/guice/WorkQueueProvider.java
new file mode 100644 (file)
index 0000000..cde27ea
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2014 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.guice;
+
+import com.gitblit.IStoredSettings;
+import com.gitblit.Keys;
+import com.gitblit.manager.IRuntimeManager;
+import com.gitblit.utils.IdGenerator;
+import com.gitblit.utils.WorkQueue;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+
+/**
+ * Provides a lazily-instantiated WorkQueue configured from IStoredSettings.
+ *
+ * @author James Moger
+ *
+ */
+@Singleton
+public class WorkQueueProvider implements Provider<WorkQueue> {
+
+       private final IRuntimeManager runtimeManager;
+
+       private volatile WorkQueue workQueue;
+
+       @Inject
+       public WorkQueueProvider(IRuntimeManager runtimeManager) {
+               this.runtimeManager = runtimeManager;
+       }
+
+       @Override
+       public synchronized WorkQueue get() {
+               if (workQueue != null) {
+                       return workQueue;
+               }
+
+               IStoredSettings settings = runtimeManager.getSettings();
+               int defaultThreadPoolSize = settings.getInteger(Keys.execution.defaultThreadPoolSize, 1);
+               IdGenerator idGenerator = new IdGenerator();
+               workQueue = new WorkQueue(idGenerator, defaultThreadPoolSize);
+               return workQueue;
+       }
+}
\ No newline at end of file
index a0718f779213dfc5ebff3f1022a38722e0ea7357..2c88e40562b848ea955ea83a78d67b352045286e 100644 (file)
@@ -49,12 +49,10 @@ import ro.fortsoft.pf4j.Version;
 
 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;
@@ -68,7 +66,6 @@ import com.gitblit.models.PluginRegistry.PluginRelease;
 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;
@@ -79,7 +76,6 @@ import com.gitblit.tickets.ITicketService;
 import com.gitblit.transport.ssh.IPublicKeyManager;
 import com.gitblit.transport.ssh.SshKey;
 import com.gitblit.utils.ArrayUtils;
-import com.gitblit.utils.HttpUtils;
 import com.gitblit.utils.JsonUtils;
 import com.gitblit.utils.ObjectCache;
 import com.gitblit.utils.StringUtils;
@@ -350,66 +346,6 @@ public class GitblitManager implements IGitblit {
                }
        }
 
-       /**
-        * 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) {
-               String gitblitUrl = settings.getString(Keys.web.canonicalUrl, null);
-               if (StringUtils.isEmpty(gitblitUrl)) {
-                       gitblitUrl = HttpUtils.getGitblitURL(request);
-               }
-               StringBuilder sb = new StringBuilder();
-               sb.append(gitblitUrl);
-               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;
@@ -597,26 +533,6 @@ public class GitblitManager implements IGitblit {
                return runtimeManager.getSettingsModel();
        }
 
-       @Override
-       public boolean isServingRepositories() {
-               return runtimeManager.isServingRepositories();
-       }
-
-       @Override
-       public boolean isServingHTTP() {
-               return runtimeManager.isServingHTTP();
-       }
-
-       @Override
-       public boolean isServingGIT() {
-               return runtimeManager.isServingGIT();
-       }
-
-       @Override
-       public boolean isServingSSH() {
-               return runtimeManager.isServingSSH();
-       }
-
        @Override
        public TimeZone getTimezone() {
                return runtimeManager.getTimezone();
index 50ec8b1f56b7fb45ae9a89d2861c12d54366cc72..6c5b374cd8f481eb74e4430159a3f76e6b9c3671 100644 (file)
 package com.gitblit.manager;
 
 import java.util.Collection;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
 
 import com.gitblit.GitBlitException;
 import com.gitblit.models.GitClientApplication;
 import com.gitblit.models.RepositoryModel;
-import com.gitblit.models.RepositoryUrl;
 import com.gitblit.models.TeamModel;
 import com.gitblit.models.UserModel;
 import com.gitblit.tickets.ITicketService;
@@ -39,17 +35,6 @@ public interface IGitblit extends IManager,
                                                                        IProjectManager,
                                                                        IFederationManager {
 
-       /**
-        * Returns a list of repository URLs and the user access permission.
-        *
-        * @param request
-        * @param user
-        * @param repository
-        * @return a list of repository urls
-        * @since 1.4.0
-        */
-       List<RepositoryUrl> getRepositoryUrls(HttpServletRequest request, UserModel user, RepositoryModel repository);
-
        /**
         * Creates a complete user object.
         *
index f736a057d9168b6a460f8c8363d54c1898b63e83..8322d34fa7d0dd7b453a3087dd45f999b1839e65 100644 (file)
@@ -50,42 +50,6 @@ public interface IRuntimeManager extends IManager {
         */
        Locale getLocale();
 
-       /**
-        * Determine if this Gitblit instance is actively serving git repositories
-        * or if it is merely a repository viewer.
-        *
-        * @return true if Gitblit is serving repositories
-        * @since 1.4.0
-        */
-       boolean isServingRepositories();
-
-       /**
-        * Determine if this Gitblit instance is actively serving git repositories
-        * over HTTP.
-        *
-        * @return true if Gitblit is serving repositories over HTTP
-        * @since 1.6.0
-        */
-       boolean isServingHTTP();
-
-       /**
-        * Determine if this Gitblit instance is actively serving git repositories
-        * over the GIT Daemon protocol.
-        *
-        * @return true if Gitblit is serving repositories over the GIT Daemon protocol
-        * @since 1.6.0
-        */
-       boolean isServingGIT();
-
-       /**
-        * Determine if this Gitblit instance is actively serving git repositories
-        * over the SSH protocol.
-        *
-        * @return true if Gitblit is serving repositories over the SSH protocol
-        * @since 1.6.0
-        */
-       boolean isServingSSH();
-
        /**
         * Determine if this Gitblit instance is running in debug mode
         *
diff --git a/src/main/java/com/gitblit/manager/IServicesManager.java b/src/main/java/com/gitblit/manager/IServicesManager.java
new file mode 100644 (file)
index 0000000..5bb135d
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2014 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.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.gitblit.models.RepositoryModel;
+import com.gitblit.models.RepositoryUrl;
+import com.gitblit.models.UserModel;
+
+public interface IServicesManager extends IManager {
+
+       /**
+        * Determine if this Gitblit instance is actively serving git repositories
+        * or if it is merely a repository viewer.
+        *
+        * @return true if Gitblit is serving repositories
+        * @since 1.7.0
+        */
+       boolean isServingRepositories();
+
+       /**
+        * Determine if this Gitblit instance is actively serving git repositories
+        * over HTTP.
+        *
+        * @return true if Gitblit is serving repositories over HTTP
+        * @since 1.7.0
+        */
+       boolean isServingHTTP();
+
+       /**
+        * Determine if this Gitblit instance is actively serving git repositories
+        * over the GIT Daemon protocol.
+        *
+        * @return true if Gitblit is serving repositories over the GIT Daemon protocol
+        * @since 1.7.0
+        */
+       boolean isServingGIT();
+
+       /**
+        * Determine if this Gitblit instance is actively serving git repositories
+        * over the SSH protocol.
+        *
+        * @return true if Gitblit is serving repositories over the SSH protocol
+        * @since 1.7.0
+        */
+       boolean isServingSSH();
+
+       /**
+        * Returns a list of repository URLs and the user access permission.
+        *
+        * @param request
+        * @param user
+        * @param repository
+        * @return a list of repository urls
+        * @since 1.7.0
+        */
+       List<RepositoryUrl> getRepositoryUrls(HttpServletRequest request, UserModel user, RepositoryModel repository);
+
+}
\ No newline at end of file
index 9b061e2585e3e7badf9b54d9ce4171b92bf50ee4..a417c02556a9d71dca452626740bbdf5bf418d35 100644 (file)
@@ -1937,21 +1937,19 @@ public class RepositoryManager implements IRepositoryManager {
        }
 
        protected void confirmWriteAccess() {
-               if (runtimeManager.isServingRepositories()) {
-                       try {
-                               if (!getRepositoriesFolder().exists()) {
-                                       getRepositoriesFolder().mkdirs();
-                               }
-                               File file = File.createTempFile(".test-", ".txt", getRepositoriesFolder());
-                               file.delete();
-                       } catch (Exception e) {
-                               logger.error("");
-                               logger.error(Constants.BORDER2);
-                               logger.error("Please check filesystem permissions!");
-                               logger.error("FAILED TO WRITE TO REPOSITORIES FOLDER!!", e);
-                               logger.error(Constants.BORDER2);
-                               logger.error("");
+               try {
+                       if (!getRepositoriesFolder().exists()) {
+                               getRepositoriesFolder().mkdirs();
                        }
+                       File file = File.createTempFile(".test-", ".txt", getRepositoriesFolder());
+                       file.delete();
+               } catch (Exception e) {
+                       logger.error("");
+                       logger.error(Constants.BORDER2);
+                       logger.error("Please check filesystem permissions!");
+                       logger.error("FAILED TO WRITE TO REPOSITORIES FOLDER!!", e);
+                       logger.error(Constants.BORDER2);
+                       logger.error("");
                }
        }
 }
index 383b1dcebb84aca3e1a700f21f50d9279cf792e8..95a363f69a7e16af05b985245c79edc82971fb8a 100644 (file)
@@ -22,8 +22,6 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.TimeZone;
 
-import com.google.inject.Inject;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -34,8 +32,11 @@ import com.gitblit.models.ServerSettings;
 import com.gitblit.models.ServerStatus;
 import com.gitblit.models.SettingModel;
 import com.gitblit.utils.StringUtils;
+import com.google.inject.Inject;
 import com.google.inject.Injector;
+import com.google.inject.Singleton;
 
+@Singleton
 public class RuntimeManager implements IRuntimeManager {
 
        private final Logger logger = LoggerFactory.getLogger(getClass());
@@ -123,52 +124,6 @@ public class RuntimeManager implements IRuntimeManager {
                return settingsModel;
        }
 
-       /**
-        * Determine if this Gitblit instance is actively serving git repositories
-        * or if it is merely a repository viewer.
-        *
-        * @return true if Gitblit is serving repositories
-        */
-       @Override
-       public boolean isServingRepositories() {
-               return isServingHTTP()
-                               || isServingGIT()
-                               || isServingSSH();
-       }
-
-       /**
-        * Determine if this Gitblit instance is actively serving git repositories
-        * over the HTTP protocol.
-        *
-        * @return true if Gitblit is serving repositories over the HTTP protocol
-        */
-       @Override
-       public boolean isServingHTTP() {
-               return settings.getBoolean(Keys.git.enableGitServlet, true);
-       }
-
-       /**
-        * Determine if this Gitblit instance is actively serving git repositories
-        * over the Git Daemon protocol.
-        *
-        * @return true if Gitblit is serving repositories over the Git Daemon protocol
-        */
-       @Override
-       public boolean isServingGIT() {
-               return settings.getInteger(Keys.git.daemonPort, 0) > 0;
-       }
-
-       /**
-        * Determine if this Gitblit instance is actively serving git repositories
-        * over the SSH protocol.
-        *
-        * @return true if Gitblit is serving repositories over the SSH protocol
-        */
-       @Override
-       public boolean isServingSSH() {
-               return settings.getInteger(Keys.git.sshPort, 0) > 0;
-       }
-
        /**
         * Returns the preferred timezone for the Gitblit instance.
         *
index 37215786a91df4ae5b3f5728b89a3dab82abf8f4..2550f66faf2f93392e2a31015403b5c143f3422c 100644 (file)
@@ -18,9 +18,15 @@ package com.gitblit.manager;
 import java.io.IOException;
 import java.net.URI;
 import java.text.MessageFormat;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
@@ -30,9 +36,11 @@ import javax.servlet.http.HttpServletRequest;
 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.FederationToken;
+import com.gitblit.Constants.Transport;
 import com.gitblit.IStoredSettings;
 import com.gitblit.Keys;
 import com.gitblit.fanout.FanoutNioService;
@@ -40,14 +48,18 @@ import com.gitblit.fanout.FanoutService;
 import com.gitblit.fanout.FanoutSocketService;
 import com.gitblit.models.FederationModel;
 import com.gitblit.models.RepositoryModel;
+import com.gitblit.models.RepositoryUrl;
 import com.gitblit.models.UserModel;
 import com.gitblit.service.FederationPullService;
 import com.gitblit.transport.git.GitDaemon;
 import com.gitblit.transport.ssh.SshDaemon;
-import com.gitblit.utils.IdGenerator;
+import com.gitblit.utils.HttpUtils;
 import com.gitblit.utils.StringUtils;
 import com.gitblit.utils.TimeUtils;
 import com.gitblit.utils.WorkQueue;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
 
 /**
  * Services manager manages long-running services/processes that either have no
@@ -57,32 +69,35 @@ import com.gitblit.utils.WorkQueue;
  * @author James Moger
  *
  */
-public class ServicesManager implements IManager {
+@Singleton
+public class ServicesManager implements IServicesManager {
 
        private final Logger logger = LoggerFactory.getLogger(getClass());
 
        private final ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(5);
 
+       private final Provider<WorkQueue> workQueueProvider;
+
        private final IStoredSettings settings;
 
        private final IGitblit gitblit;
 
-       private final IdGenerator idGenerator;
-
-       private final WorkQueue workQueue;
-
        private FanoutService fanoutService;
 
        private GitDaemon gitDaemon;
 
        private SshDaemon sshDaemon;
 
-       public ServicesManager(IGitblit gitblit) {
-               this.settings = gitblit.getSettings();
+       @Inject
+       public ServicesManager(
+                       Provider<WorkQueue> workQueueProvider,
+                       IStoredSettings settings,
+                       IGitblit gitblit) {
+
+               this.workQueueProvider = workQueueProvider;
+
+               this.settings = settings;
                this.gitblit = gitblit;
-               int defaultThreadPoolSize = settings.getInteger(Keys.execution.defaultThreadPoolSize, 1);
-               this.idGenerator = new IdGenerator();
-               this.workQueue = new WorkQueue(idGenerator, defaultThreadPoolSize);
        }
 
        @Override
@@ -107,24 +122,181 @@ public class ServicesManager implements IManager {
                if (sshDaemon != null) {
                        sshDaemon.stop();
                }
-               workQueue.stop();
+               workQueueProvider.get().stop();
                return this;
        }
 
+       protected String getRepositoryUrl(HttpServletRequest request, String username, RepositoryModel repository) {
+               String gitblitUrl = settings.getString(Keys.web.canonicalUrl, null);
+               if (StringUtils.isEmpty(gitblitUrl)) {
+                       gitblitUrl = HttpUtils.getGitblitURL(request);
+               }
+               StringBuilder sb = new StringBuilder();
+               sb.append(gitblitUrl);
+               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 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)) {
+                               Transport transport = Transport.fromString(request.getScheme());
+                               if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(transport)) {
+                                       // downgrade the repo permission for this transport
+                                       // because it is not an acceptable PUSH transport
+                                       permission = AccessPermission.CLONE;
+                               }
+                               list.add(new RepositoryUrl(getRepositoryUrl(request, username, repository), permission));
+                       }
+               }
+
+               // ssh daemon url
+               String sshDaemonUrl = getSshDaemonUrl(request, user, repository);
+               if (!StringUtils.isEmpty(sshDaemonUrl)) {
+                       AccessPermission permission = user.getRepositoryPermission(repository).permission;
+                       if (permission.exceeds(AccessPermission.NONE)) {
+                               if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(Transport.SSH)) {
+                                       // downgrade the repo permission for this transport
+                                       // because it is not an acceptable PUSH transport
+                                       permission = AccessPermission.CLONE;
+                               }
+
+                               list.add(new RepositoryUrl(sshDaemonUrl, permission));
+                       }
+               }
+
+               // git daemon url
+               String gitDaemonUrl = getGitDaemonUrl(request, user, repository);
+               if (!StringUtils.isEmpty(gitDaemonUrl)) {
+                       AccessPermission permission = getGitDaemonAccessPermission(user, repository);
+                       if (permission.exceeds(AccessPermission.NONE)) {
+                               if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(Transport.GIT)) {
+                                       // downgrade the repo permission for this transport
+                                       // because it is not an acceptable PUSH transport
+                                       permission = AccessPermission.CLONE;
+                               }
+                               list.add(new RepositoryUrl(gitDaemonUrl, 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));
+                       }
+               }
+
+               // sort transports by highest permission and then by transport security
+               Collections.sort(list, new Comparator<RepositoryUrl>() {
+
+                       @Override
+                       public int compare(RepositoryUrl o1, RepositoryUrl o2) {
+                               if (!o1.isExternal() && o2.isExternal()) {
+                                       // prefer Gitblit over external
+                                       return -1;
+                               } else if (o1.isExternal() && !o2.isExternal()) {
+                                       // prefer Gitblit over external
+                                       return 1;
+                               } else if (o1.isExternal() && o2.isExternal()) {
+                                       // sort by Transport ordinal
+                                       return o1.transport.compareTo(o2.transport);
+                               } else if (o1.permission.exceeds(o2.permission)) {
+                                       // prefer highest permission
+                                       return -1;
+                               } else if (o2.permission.exceeds(o1.permission)) {
+                                       // prefer highest permission
+                                       return 1;
+                               }
+
+                               // prefer more secure transports
+                               return o1.transport.compareTo(o2.transport);
+                       }
+               });
+
+               // consider the user's transport preference
+               RepositoryUrl preferredUrl = null;
+               Transport preferredTransport = user.getPreferences().getTransport();
+               if (preferredTransport != null) {
+                       Iterator<RepositoryUrl> itr = list.iterator();
+                       while (itr.hasNext()) {
+                               RepositoryUrl url = itr.next();
+                               if (url.transport.equals(preferredTransport)) {
+                                       itr.remove();
+                                       preferredUrl = url;
+                                       break;
+                               }
+                       }
+               }
+               if (preferredUrl != null) {
+                       list.add(0, preferredUrl);
+               }
+
+               return list;
+       }
+
+       /* (non-Javadoc)
+        * @see com.gitblit.manager.IServicesManager#isServingRepositories()
+        */
+       @Override
        public boolean isServingRepositories() {
                return isServingHTTP()
                                || isServingGIT()
                                || isServingSSH();
        }
 
+       /* (non-Javadoc)
+        * @see com.gitblit.manager.IServicesManager#isServingHTTP()
+        */
+       @Override
        public boolean isServingHTTP() {
                return settings.getBoolean(Keys.git.enableGitServlet, true);
        }
 
+       /* (non-Javadoc)
+        * @see com.gitblit.manager.IServicesManager#isServingGIT()
+        */
+       @Override
        public boolean isServingGIT() {
                return gitDaemon != null && gitDaemon.isRunning();
        }
 
+       /* (non-Javadoc)
+        * @see com.gitblit.manager.IServicesManager#isServingSSH()
+        */
+       @Override
        public boolean isServingSSH() {
                return sshDaemon != null && sshDaemon.isRunning();
        }
@@ -158,6 +330,32 @@ public class ServicesManager implements IManager {
                }
        }
 
+       protected boolean acceptPush(Transport byTransport) {
+               if (byTransport == null) {
+                       logger.info("Unknown transport, push rejected!");
+                       return false;
+               }
+
+               Set<Transport> transports = new HashSet<Transport>();
+               for (String value : settings.getStrings(Keys.git.acceptedPushTransports)) {
+                       Transport transport = Transport.fromString(value);
+                       if (transport == null) {
+                               logger.info(String.format("Ignoring unknown registered transport %s", value));
+                               continue;
+                       }
+
+                       transports.add(transport);
+               }
+
+               if (transports.isEmpty()) {
+                       // no transports are explicitly specified, all are acceptable
+                       return true;
+               }
+
+               // verify that the transport is permitted
+               return transports.contains(byTransport);
+       }
+
        protected void configureGitDaemon() {
                int port = settings.getInteger(Keys.git.daemonPort, 0);
                String bindInterface = settings.getString(Keys.git.daemonBindInterface, "localhost");
@@ -179,7 +377,7 @@ public class ServicesManager implements IManager {
                String bindInterface = settings.getString(Keys.git.sshBindInterface, "localhost");
                if (port > 0) {
                        try {
-                               sshDaemon = new SshDaemon(gitblit, workQueue);
+                               sshDaemon = new SshDaemon(gitblit, workQueueProvider.get());
                                sshDaemon.start();
                        } catch (IOException e) {
                                sshDaemon = null;
@@ -285,7 +483,7 @@ public class ServicesManager implements IManager {
         */
        protected String getHostname(HttpServletRequest request) {
                String hostname = request.getServerName();
-               String canonicalUrl = gitblit.getSettings().getString(Keys.web.canonicalUrl, null);
+               String canonicalUrl = settings.getString(Keys.web.canonicalUrl, null);
                if (!StringUtils.isEmpty(canonicalUrl)) {
                        try {
                                URI uri = new URI(canonicalUrl);
index e0f6003c77a935a2492a2e9dabdcb40f2ffdc9ef..44a857ca8d040d4c6e327723a9e9d906dfafc490 100644 (file)
@@ -51,6 +51,7 @@ import com.gitblit.manager.IPluginManager;
 import com.gitblit.manager.IProjectManager;
 import com.gitblit.manager.IRepositoryManager;
 import com.gitblit.manager.IRuntimeManager;
+import com.gitblit.manager.IServicesManager;
 import com.gitblit.manager.IUserManager;
 import com.gitblit.transport.ssh.IPublicKeyManager;
 import com.gitblit.utils.ContainerUtils;
@@ -200,6 +201,7 @@ public class GitblitContext extends GuiceServletContextListener {
                startManager(injector, IProjectManager.class);
                startManager(injector, IFederationManager.class);
                startManager(injector, IGitblit.class);
+               startManager(injector, IServicesManager.class);
 
                // start the plugin manager last so that plugins can depend on
                // deterministic access to all other managers in their start() methods
index a90731103ea0862b67fdbdcf12151daa1d424e33..24468c0b01fb0d5ef35ea8255a4fe8f45a5d94fd 100644 (file)
@@ -21,9 +21,6 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.TimeZone;
 
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-
 import org.apache.wicket.Application;
 import org.apache.wicket.Request;
 import org.apache.wicket.Response;
@@ -46,6 +43,7 @@ import com.gitblit.manager.IPluginManager;
 import com.gitblit.manager.IProjectManager;
 import com.gitblit.manager.IRepositoryManager;
 import com.gitblit.manager.IRuntimeManager;
+import com.gitblit.manager.IServicesManager;
 import com.gitblit.manager.IUserManager;
 import com.gitblit.tickets.ITicketService;
 import com.gitblit.transport.ssh.IPublicKeyManager;
@@ -92,6 +90,8 @@ import com.gitblit.wicket.pages.TicketsPage;
 import com.gitblit.wicket.pages.TreePage;
 import com.gitblit.wicket.pages.UserPage;
 import com.gitblit.wicket.pages.UsersPage;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
 
 @Singleton
 public class GitBlitWebApp extends WebApplication implements GitblitWicketApp {
@@ -124,6 +124,8 @@ public class GitBlitWebApp extends WebApplication implements GitblitWicketApp {
 
        private final IGitblit gitblit;
 
+       private final IServicesManager services;
+
        @Inject
        public GitBlitWebApp(
                        IRuntimeManager runtimeManager,
@@ -135,7 +137,8 @@ public class GitBlitWebApp extends WebApplication implements GitblitWicketApp {
                        IRepositoryManager repositoryManager,
                        IProjectManager projectManager,
                        IFederationManager federationManager,
-                       IGitblit gitblit) {
+                       IGitblit gitblit,
+                       IServicesManager services) {
 
                super();
                this.settings = runtimeManager.getSettings();
@@ -149,6 +152,7 @@ public class GitBlitWebApp extends WebApplication implements GitblitWicketApp {
                this.projectManager = projectManager;
                this.federationManager = federationManager;
                this.gitblit = gitblit;
+               this.services = services;
        }
 
        @Override
@@ -420,6 +424,14 @@ public class GitBlitWebApp extends WebApplication implements GitblitWicketApp {
                return gitblit;
        }
 
+       /* (non-Javadoc)
+        * @see com.gitblit.wicket.Webapp#services()
+        */
+       @Override
+       public IServicesManager services() {
+               return services;
+       }
+
        /* (non-Javadoc)
         * @see com.gitblit.wicket.Webapp#tickets()
         */
index a56e6996fcbc62d060fe44f34ee61e95001ea68c..7013097c78379960151e96ea8236f527e4f9e8f4 100644 (file)
@@ -14,6 +14,7 @@ import com.gitblit.manager.IPluginManager;
 import com.gitblit.manager.IProjectManager;
 import com.gitblit.manager.IRepositoryManager;
 import com.gitblit.manager.IRuntimeManager;
+import com.gitblit.manager.IServicesManager;
 import com.gitblit.manager.IUserManager;
 import com.gitblit.tickets.ITicketService;
 import com.gitblit.transport.ssh.IPublicKeyManager;
@@ -65,6 +66,8 @@ public interface GitblitWicketApp {
 
        public abstract IGitblit gitblit();
 
+       public abstract IServicesManager services();
+
        public abstract ITicketService tickets();
 
        public abstract TimeZone getTimezone();
index b3c524368ed529e301be3601a7d91e20fe4f6b6c..72d1e1a42f13f177f153844152dfef7a5ac093a2 100644 (file)
@@ -55,7 +55,7 @@ public class EmptyRepositoryPage extends RepositoryPage {
                }\r
 \r
                HttpServletRequest req = ((WebRequest) getRequest()).getHttpServletRequest();\r
-               List<RepositoryUrl> repositoryUrls = app().gitblit().getRepositoryUrls(req, user, repository);\r
+               List<RepositoryUrl> repositoryUrls = app().services().getRepositoryUrls(req, user, repository);\r
                RepositoryUrl primaryUrl = repositoryUrls.size() == 0 ? null : repositoryUrls.get(0);\r
                String url = primaryUrl != null ? primaryUrl.url : "";\r
 \r
index f5f63d23027a7af7dcd32d7e1cd38df1686272d3..e1e816286eaf9d1d842c6f837b5d59c0af11e3bd 100644 (file)
@@ -1505,7 +1505,7 @@ public class TicketPage extends RepositoryPage {
         */\r
        protected RepositoryUrl getRepositoryUrl(UserModel user, RepositoryModel repository) {\r
                HttpServletRequest req = ((WebRequest) getRequest()).getHttpServletRequest();\r
-               List<RepositoryUrl> urls = app().gitblit().getRepositoryUrls(req, user, repository);\r
+               List<RepositoryUrl> urls = app().services().getRepositoryUrls(req, user, repository);\r
                if (ArrayUtils.isEmpty(urls)) {\r
                        return null;\r
                }\r
index 8931d5e31f2376e0f367d013562e9a5e1c58e01f..e21431d99882a8215b7feac6174c4a74a771ff5d 100644 (file)
@@ -104,7 +104,7 @@ public class UserPage extends RootPage {
                if (isMyProfile) {\r
                        addPreferences(user);\r
 \r
-                       if (app().gitblit().isServingSSH()) {\r
+                       if (app().services().isServingSSH()) {\r
                                // show the SSH key management tab\r
                                addSshKeys(user);\r
                        } else {\r
@@ -248,14 +248,14 @@ public class UserPage extends RootPage {
                                emailMeOnMyTicketChanges).setVisible(app().notifier().isSendingMail()));\r
 \r
                List<Transport> availableTransports = new ArrayList<>();\r
-               if (app().gitblit().isServingSSH()) {\r
+               if (app().services().isServingSSH()) {\r
                        availableTransports.add(Transport.SSH);\r
                }\r
-               if (app().gitblit().isServingHTTP()) {\r
+               if (app().services().isServingHTTP()) {\r
                        availableTransports.add(Transport.HTTPS);\r
                        availableTransports.add(Transport.HTTP);\r
                }\r
-               if (app().gitblit().isServingGIT()) {\r
+               if (app().services().isServingGIT()) {\r
                        availableTransports.add(Transport.GIT);\r
                }\r
 \r
index 938226a62cdbd6f9704d8e708e431f905b2ef4ad..0666fcd8c6f65950906eb8a25b3acd8cdf25c20f 100644 (file)
@@ -80,7 +80,7 @@ public class RepositoryUrlPanel extends BasePanel {
 \r
                HttpServletRequest req = ((WebRequest) getRequest()).getHttpServletRequest();\r
 \r
-               List<RepositoryUrl> repositoryUrls = app().gitblit().getRepositoryUrls(req, user, repository);\r
+               List<RepositoryUrl> repositoryUrls = app().services().getRepositoryUrls(req, user, repository);\r
                // grab primary url from the top of the list\r
                primaryUrl = repositoryUrls.size() == 0 ? null : repositoryUrls.get(0);\r
 \r
@@ -165,7 +165,7 @@ public class RepositoryUrlPanel extends BasePanel {
                if (repository.isMirror) {\r
                        urlPanel.add(WicketUtils.newImage("accessRestrictionIcon", "mirror_16x16.png",\r
                                        getString("gb.isMirror")));\r
-               } else if (app().gitblit().isServingRepositories()) {\r
+               } else if (app().services().isServingRepositories()) {\r
                        switch (repository.accessRestriction) {\r
                        case NONE:\r
                                urlPanel.add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false));\r
index 36a0218ec7566544d414529218e8e1529c10a958..9a71c884c5831c1d29aafaa1686da69b0d64ef50 100644 (file)
@@ -82,26 +82,6 @@ public class MockRuntimeManager implements IRuntimeManager {
                return Locale.getDefault();
        }
 
-       @Override
-       public boolean isServingRepositories() {
-               return true;
-       }
-
-       @Override
-       public boolean isServingHTTP() {
-               return true;
-       }
-
-       @Override
-       public boolean isServingGIT() {
-               return true;
-       }
-
-       @Override
-       public boolean isServingSSH() {
-               return true;
-       }
-
        @Override
        public boolean isDebugMode() {
                return true;