Add repository-specific non-ff disallowed option (#1579)

Co-authored-by: René Pfeuffer <rene.pfeuffer@cloudogu.com>
This commit is contained in:
Florian Scholdei
2021-03-11 10:13:26 +01:00
committed by GitHub
parent 831877564d
commit 0d3339b0cb
18 changed files with 142 additions and 64 deletions

View File

@@ -40,6 +40,8 @@ public class GitRepositoryConfigDto extends HalRepresentation implements UpdateG
private String defaultBranch;
private boolean nonFastForwardDisallowed;
@Override
@SuppressWarnings("squid:S1185") // We want to have this method available in this package
protected HalRepresentation add(Links links) {

View File

@@ -119,7 +119,7 @@ public class GitRepositoryConfigResource {
schema = @Schema(implementation = UpdateGitRepositoryConfigDto.class),
examples = @ExampleObject(
name = "Overwrites current configuration with this one.",
value = "{\n \"defaultBranch\":\"main\"\n}",
value = "{\n \"defaultBranch\":\"main\"\n \"nonFastForwardDisallowed\":false,\n}",
summary = "Simple update configuration"
)
)

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.api.v2.resources;
import sonia.scm.event.ScmEventBus;
@@ -42,7 +42,22 @@ public class GitRepositoryConfigStoreProvider {
}
public ConfigurationStore<GitRepositoryConfig> get(Repository repository) {
return new StoreWrapper(configurationStoreFactory.withType(GitRepositoryConfig.class).withName("gitConfig").forRepository(repository).build(), repository);
return new StoreWrapper(createStore(repository.getId()), repository);
}
public GitRepositoryConfig getGitRepositoryConfig(String repositoryId) {
return getFronStore(createStore(repositoryId));
}
private static GitRepositoryConfig getFronStore(ConfigurationStore<GitRepositoryConfig> store) {
return store.getOptional().orElse(new GitRepositoryConfig());
}
private ConfigurationStore<GitRepositoryConfig> createStore(String id) {
return configurationStoreFactory
.withType(GitRepositoryConfig.class)
.withName("gitConfig")
.forRepository(id).build();
}
private static class StoreWrapper implements ConfigurationStore<GitRepositoryConfig> {
@@ -57,11 +72,7 @@ public class GitRepositoryConfigStoreProvider {
@Override
public GitRepositoryConfig get() {
GitRepositoryConfig config = delegate.get();
if (config == null) {
return new GitRepositoryConfig();
}
return config;
return getFronStore(delegate);
}
@Override

View File

@@ -26,4 +26,5 @@ package sonia.scm.api.v2.resources;
interface UpdateGitRepositoryConfigDto {
String getDefaultBranch();
boolean isNonFastForwardDisallowed();
}

View File

@@ -29,7 +29,9 @@ import org.eclipse.jgit.transport.ReceivePack;
import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
import sonia.scm.api.v2.resources.GitRepositoryConfigStoreProvider;
import sonia.scm.repository.GitChangesetConverterFactory;
import sonia.scm.repository.GitRepositoryConfig;
import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.web.CollectingPackParserListener;
import sonia.scm.web.GitHookEventFacade;
@@ -39,16 +41,21 @@ public abstract class BaseReceivePackFactory<T> implements ReceivePackFactory<T>
private final GitRepositoryHandler handler;
private final GitReceiveHook hook;
private final GitRepositoryConfigStoreProvider storeProvider;
protected BaseReceivePackFactory(GitChangesetConverterFactory converterFactory, GitRepositoryHandler handler, GitHookEventFacade hookEventFacade) {
protected BaseReceivePackFactory(GitChangesetConverterFactory converterFactory,
GitRepositoryHandler handler,
GitHookEventFacade hookEventFacade,
GitRepositoryConfigStoreProvider storeProvider) {
this.handler = handler;
this.storeProvider = storeProvider;
this.hook = new GitReceiveHook(converterFactory, hookEventFacade, handler);
}
@Override
public final ReceivePack create(T connection, Repository repository) throws ServiceNotAuthorizedException, ServiceNotEnabledException {
ReceivePack receivePack = createBasicReceivePack(connection, repository);
receivePack.setAllowNonFastForwards(isNonFastForwardAllowed());
receivePack.setAllowNonFastForwards(isNonFastForwardAllowed(repository));
receivePack.setPreReceiveHook(hook);
receivePack.setPostReceiveHook(hook);
@@ -61,7 +68,9 @@ public abstract class BaseReceivePackFactory<T> implements ReceivePackFactory<T>
protected abstract ReceivePack createBasicReceivePack(T request, Repository repository)
throws ServiceNotEnabledException, ServiceNotAuthorizedException;
private boolean isNonFastForwardAllowed() {
return ! handler.getConfig().isNonFastForwardDisallowed();
private boolean isNonFastForwardAllowed(Repository repository) {
String repositoryId = handler.getRepositoryId(repository.getConfig());
GitRepositoryConfig gitRepositoryConfig = storeProvider.getGitRepositoryConfig(repositoryId);
return !(handler.getConfig().isNonFastForwardDisallowed() || gitRepositoryConfig.isNonFastForwardDisallowed());
}
}

View File

@@ -27,6 +27,7 @@ package sonia.scm.protocolcommand.git;
import com.google.inject.Inject;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.ReceivePack;
import sonia.scm.api.v2.resources.GitRepositoryConfigStoreProvider;
import sonia.scm.protocolcommand.RepositoryContext;
import sonia.scm.repository.GitChangesetConverterFactory;
import sonia.scm.repository.GitRepositoryHandler;
@@ -35,8 +36,11 @@ import sonia.scm.web.GitHookEventFacade;
public class ScmReceivePackFactory extends BaseReceivePackFactory<RepositoryContext> {
@Inject
public ScmReceivePackFactory(GitChangesetConverterFactory converterFactory, GitRepositoryHandler handler, GitHookEventFacade hookEventFacade) {
super(converterFactory, handler, hookEventFacade);
public ScmReceivePackFactory(GitChangesetConverterFactory converterFactory,
GitRepositoryHandler handler,
GitHookEventFacade hookEventFacade,
GitRepositoryConfigStoreProvider gitRepositoryConfigStoreProvider) {
super(converterFactory, handler, hookEventFacade, gitRepositoryConfigStoreProvider);
}
@Override

View File

@@ -40,6 +40,7 @@ public class GitRepositoryConfig {
}
private String defaultBranch;
private boolean nonFastForwardDisallowed;
public String getDefaultBranch() {
return defaultBranch;
@@ -48,4 +49,10 @@ public class GitRepositoryConfig {
public void setDefaultBranch(String defaultBranch) {
this.defaultBranch = defaultBranch;
}
public boolean isNonFastForwardDisallowed() { return nonFastForwardDisallowed; }
public void setNonFastForwardDisallowed(boolean nonFastForwardDisallowed) {
this.nonFastForwardDisallowed = nonFastForwardDisallowed;
}
}

View File

@@ -33,6 +33,7 @@ import org.eclipse.jgit.transport.ReceivePack;
import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
import sonia.scm.api.v2.resources.GitRepositoryConfigStoreProvider;
import sonia.scm.protocolcommand.git.BaseReceivePackFactory;
import sonia.scm.repository.GitChangesetConverterFactory;
import sonia.scm.repository.GitRepositoryHandler;
@@ -53,8 +54,11 @@ public class GitReceivePackFactory extends BaseReceivePackFactory<HttpServletReq
private ReceivePackFactory<HttpServletRequest> wrapped;
@Inject
public GitReceivePackFactory(GitChangesetConverterFactory converterFactory, GitRepositoryHandler handler, GitHookEventFacade hookEventFacade) {
super(converterFactory, handler, hookEventFacade);
public GitReceivePackFactory(GitChangesetConverterFactory converterFactory,
GitRepositoryHandler handler,
GitHookEventFacade hookEventFacade,
GitRepositoryConfigStoreProvider gitRepositoryConfigStoreProvider) {
super(converterFactory, handler, hookEventFacade, gitRepositoryConfigStoreProvider);
this.wrapped = new DefaultReceivePackFactory();
}