1 /* 2 * Copyright (C) 2008-2009, Google Inc. 3 * Copyright (C) 2009, Robin Rosenberg <robin.rosenberg@dewire.com> 4 * and other copyright owners as documented in the project's IP log. 5 * 6 * This program and the accompanying materials are made available 7 * under the terms of the Eclipse Distribution License v1.0 which 8 * accompanies this distribution, is reproduced below, and is 9 * available at http://www.eclipse.org/org/documents/edl-v10.php 10 * 11 * All rights reserved. 12 * 13 * Redistribution and use in source and binary forms, with or 14 * without modification, are permitted provided that the following 15 * conditions are met: 16 * 17 * - Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 20 * - Redistributions in binary form must reproduce the above 21 * copyright notice, this list of conditions and the following 22 * disclaimer in the documentation and/or other materials provided 23 * with the distribution. 24 * 25 * - Neither the name of the Eclipse Foundation, Inc. nor the 26 * names of its contributors may be used to endorse or promote 27 * products derived from this software without specific prior 28 * written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 31 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 32 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 33 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 34 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 35 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 36 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 37 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 38 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 39 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 42 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 43 */ 44 45 package org.eclipse.jgit.transport; 46 47 import java.io.IOException; 48 import java.util.Collection; 49 50 import org.eclipse.jgit.annotations.Nullable; 51 import org.eclipse.jgit.lib.Config; 52 import org.eclipse.jgit.lib.Config.SectionParser; 53 import org.eclipse.jgit.lib.Repository; 54 import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; 55 import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; 56 57 /** 58 * A service exposed by {@link org.eclipse.jgit.transport.Daemon} over anonymous 59 * <code>git://</code>. 60 */ 61 public abstract class DaemonService { 62 private final String command; 63 64 private final SectionParser<ServiceConfig> configKey; 65 66 private boolean enabled; 67 68 private boolean overridable; 69 70 DaemonService(String cmdName, String cfgName) { 71 command = cmdName.startsWith("git-") ? cmdName : "git-" + cmdName; //$NON-NLS-1$ //$NON-NLS-2$ 72 configKey = cfg -> new ServiceConfig(DaemonService.this, cfg, cfgName); 73 overridable = true; 74 } 75 76 private static class ServiceConfig { 77 final boolean enabled; 78 79 ServiceConfig(final DaemonService service, final Config cfg, 80 final String name) { 81 enabled = cfg.getBoolean("daemon", name, service.isEnabled()); //$NON-NLS-1$ 82 } 83 } 84 85 /** 86 * Whether this service is enabled for invocation. 87 * 88 * @return whether this service is enabled for invocation. 89 */ 90 public boolean isEnabled() { 91 return enabled; 92 } 93 94 /** 95 * Set if it is allowed to use this service 96 * 97 * @param on 98 * {@code true} to allow this service to be used; {@code false} 99 * to deny it. 100 */ 101 public void setEnabled(boolean on) { 102 enabled = on; 103 } 104 105 /** @return can this service be configured in the repository config file? */ 106 /** 107 * Whether this service can be configured in the repository config file 108 * 109 * @return whether this service can be configured in the repository config 110 * file 111 */ 112 public boolean isOverridable() { 113 return overridable; 114 } 115 116 /** 117 * Whether to permit repositories to override this service's enabled state 118 * with the <code>daemon.servicename</code> config setting. 119 * 120 * @param on 121 * {@code true} to permit repositories to override this service's 122 * enabled state with the <code>daemon.servicename</code> config 123 * setting. 124 */ 125 public void setOverridable(boolean on) { 126 overridable = on; 127 } 128 129 /** 130 * Get name of the command requested by clients. 131 * 132 * @return name of the command requested by clients. 133 */ 134 public String getCommandName() { 135 return command; 136 } 137 138 /** 139 * Determine if this service can handle the requested command. 140 * 141 * @param commandLine 142 * input line from the client. 143 * @return true if this command can accept the given command line. 144 */ 145 public boolean handles(String commandLine) { 146 return command.length() + 1 < commandLine.length() 147 && commandLine.charAt(command.length()) == ' ' 148 && commandLine.startsWith(command); 149 } 150 151 void execute(DaemonClient client, String commandLine, 152 @Nullable Collection<String> extraParameters) 153 throws IOException, ServiceNotEnabledException, 154 ServiceNotAuthorizedException { 155 final String name = commandLine.substring(command.length() + 1); 156 try (Repository db = client.getDaemon().openRepository(client, name)) { 157 if (isEnabledFor(db)) { 158 execute(client, db, extraParameters); 159 } 160 } catch (ServiceMayNotContinueException e) { 161 // An error when opening the repo means the client is expecting a ref 162 // advertisement, so use that style of error. 163 PacketLineOut pktOut = new PacketLineOut(client.getOutputStream()); 164 pktOut.writeString("ERR " + e.getMessage() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ 165 } 166 } 167 168 private boolean isEnabledFor(Repository db) { 169 if (isOverridable()) 170 return db.getConfig().get(configKey).enabled; 171 return isEnabled(); 172 } 173 174 abstract void execute(DaemonClient client, Repository db, 175 @Nullable Collection<String> extraParameters) 176 throws IOException, ServiceNotEnabledException, 177 ServiceNotAuthorizedException; 178 }