mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-05-06 18:36:51 +02:00
Merge pull request #1403 from scm-manager/bugfix/anonymous-ssh-clone
Bugfix/anonymous ssh clone
This commit is contained in:
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Fixed
|
||||
- Internal server error for git sub modules without tree object ([#1397](https://github.com/scm-manager/scm-manager/pull/1397))
|
||||
- Do not expose subversion commit with id 0 ([#1395](https://github.com/scm-manager/scm-manager/pull/1395))
|
||||
- Disable cloning repositories via ssh for anonymous users ([#1403](https://github.com/scm-manager/scm-manager/pull/1403))
|
||||
- SVN diff with property changes ([#1400](https://github.com/scm-manager/scm-manager/pull/1400))
|
||||
- Branches link in repository overview ([#1404](https://github.com/scm-manager/scm-manager/pull/1404))
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryPermissions;
|
||||
import sonia.scm.repository.spi.RepositoryServiceProvider;
|
||||
import sonia.scm.repository.work.WorkdirProvider;
|
||||
import sonia.scm.security.Authentications;
|
||||
import sonia.scm.user.EMail;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@@ -453,7 +454,8 @@ public final class RepositoryService implements Closeable {
|
||||
public Stream<ScmProtocol> getSupportedProtocols() {
|
||||
return protocolProviders.stream()
|
||||
.filter(protocolProvider -> protocolProvider.getType().equals(getRepository().getType()))
|
||||
.map(this::createProviderInstanceForRepository);
|
||||
.map(this::createProviderInstanceForRepository)
|
||||
.filter(protocol -> !Authentications.isAuthenticatedSubjectAnonymous() || protocol.isAnonymousEnabled());
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "java:S3740"})
|
||||
|
||||
@@ -40,4 +40,11 @@ public interface ScmProtocol {
|
||||
* The URL to access the repository providing this protocol.
|
||||
*/
|
||||
String getUrl();
|
||||
|
||||
/**
|
||||
* Whether the protocol can be used as an anonymous user.
|
||||
*/
|
||||
default boolean isAnonymousEnabled() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,15 @@
|
||||
|
||||
package sonia.scm.repository.api;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.apache.shiro.util.ThreadContext;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import sonia.scm.SCMContext;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.spi.HttpScmProtocol;
|
||||
@@ -42,16 +50,32 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
import static org.assertj.core.util.IterableUtil.sizeOf;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class RepositoryServiceTest {
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class RepositoryServiceTest {
|
||||
|
||||
private final RepositoryServiceProvider provider = mock(RepositoryServiceProvider.class);
|
||||
private final Repository repository = new Repository("", "git", "space", "repo");
|
||||
|
||||
private final EMail eMail = new EMail(new ScmConfiguration());
|
||||
|
||||
@Mock
|
||||
private Subject subject;
|
||||
|
||||
@BeforeEach
|
||||
void bindSubject() {
|
||||
ThreadContext.bind(subject);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void unbindSubject() {
|
||||
ThreadContext.unbindSubject();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnMatchingProtocolsFromProvider() {
|
||||
void shouldReturnMatchingProtocolsFromProvider() {
|
||||
when(subject.getPrincipal()).thenReturn("Hitchhiker");
|
||||
RepositoryService repositoryService = new RepositoryService(null, provider, repository, null, Collections.singleton(new DummyScmProtocolProvider()), null, eMail);
|
||||
Stream<ScmProtocol> supportedProtocols = repositoryService.getSupportedProtocols();
|
||||
|
||||
@@ -59,7 +83,17 @@ public class RepositoryServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindKnownProtocol() {
|
||||
void shouldFilterOutNonAnonymousEnabledProtocolsForAnonymousUser() {
|
||||
when(subject.getPrincipal()).thenReturn(SCMContext.USER_ANONYMOUS);
|
||||
RepositoryService repositoryService = new RepositoryService(null, provider, repository, null, Stream.of(new DummyScmProtocolProvider(), new DummyScmProtocolProvider(false)).collect(Collectors.toSet()), null, eMail);
|
||||
Stream<ScmProtocol> supportedProtocols = repositoryService.getSupportedProtocols();
|
||||
|
||||
assertThat(sizeOf(supportedProtocols.collect(Collectors.toList()))).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFindKnownProtocol() {
|
||||
when(subject.getPrincipal()).thenReturn("Hitchhiker");
|
||||
RepositoryService repositoryService = new RepositoryService(null, provider, repository, null, Collections.singleton(new DummyScmProtocolProvider()), null, eMail);
|
||||
|
||||
HttpScmProtocol protocol = repositoryService.getProtocol(HttpScmProtocol.class);
|
||||
@@ -68,23 +102,44 @@ public class RepositoryServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFailForUnknownProtocol() {
|
||||
void shouldFailForUnknownProtocol() {
|
||||
when(subject.getPrincipal()).thenReturn("Hitchhiker");
|
||||
RepositoryService repositoryService = new RepositoryService(null, provider, repository, null, Collections.singleton(new DummyScmProtocolProvider()), null, eMail);
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () -> repositoryService.getProtocol(UnknownScmProtocol.class));
|
||||
}
|
||||
|
||||
private static class DummyHttpProtocol extends HttpScmProtocol {
|
||||
public DummyHttpProtocol(Repository repository) {
|
||||
|
||||
private final boolean anonymousEnabled;
|
||||
|
||||
public DummyHttpProtocol(Repository repository, boolean anonymousEnabled) {
|
||||
super(repository, "");
|
||||
this.anonymousEnabled = anonymousEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serve(HttpServletRequest request, HttpServletResponse response, Repository repository, ServletConfig config) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnonymousEnabled() {
|
||||
return anonymousEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
private static class DummyScmProtocolProvider implements ScmProtocolProvider {
|
||||
|
||||
private final boolean anonymousEnabled;
|
||||
|
||||
public DummyScmProtocolProvider() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
public DummyScmProtocolProvider(boolean anonymousEnabled) {
|
||||
this.anonymousEnabled = anonymousEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "git";
|
||||
@@ -92,9 +147,10 @@ public class RepositoryServiceTest {
|
||||
|
||||
@Override
|
||||
public ScmProtocol get(Repository repository) {
|
||||
return new DummyHttpProtocol(repository);
|
||||
return new DummyHttpProtocol(repository, anonymousEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
private interface UnknownScmProtocol extends ScmProtocol {}
|
||||
private interface UnknownScmProtocol extends ScmProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user