mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-02-22 06:26:56 +01:00
Merge with upstream
This commit is contained in:
@@ -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 org.junit.jupiter.params.ParameterizedTest;
|
||||
@@ -29,6 +29,7 @@ import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static sonia.scm.repository.Branch.VALID_BRANCH_NAMES;
|
||||
|
||||
class BranchDtoTest {
|
||||
|
||||
@@ -54,10 +55,11 @@ class BranchDtoTest {
|
||||
"val{d",
|
||||
"val{}d",
|
||||
"val|kill",
|
||||
"val}"
|
||||
"val}",
|
||||
"va/li/d"
|
||||
})
|
||||
void shouldAcceptValidBranchName(String branchName) {
|
||||
assertTrue(branchName.matches(BranchDto.VALID_BRANCH_NAMES));
|
||||
assertTrue(branchName.matches(VALID_BRANCH_NAMES));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@@ -70,6 +72,6 @@ class BranchDtoTest {
|
||||
"val id"
|
||||
})
|
||||
void shouldRejectInvalidBranchName(String branchName) {
|
||||
assertFalse(branchName.matches(BranchDto.VALID_BRANCH_NAMES));
|
||||
assertFalse(branchName.matches(VALID_BRANCH_NAMES));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import sonia.scm.security.AnonymousMode;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
@@ -42,9 +43,7 @@ public class ConfigDtoToScmConfigurationMapperTest {
|
||||
@InjectMocks
|
||||
private ConfigDtoToScmConfigurationMapperImpl mapper;
|
||||
|
||||
private String[] expectedUsers = {"trillian", "arthur"};
|
||||
private String[] expectedGroups = {"admin", "plebs"};
|
||||
private String[] expectedExcludes = {"ex", "clude"};
|
||||
private final String[] expectedExcludes = {"ex", "clude"};
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
@@ -73,6 +72,7 @@ public class ConfigDtoToScmConfigurationMapperTest {
|
||||
assertEquals("https://plug.ins", config.getPluginUrl());
|
||||
assertEquals(40, config.getLoginAttemptLimitTimeout());
|
||||
assertTrue(config.isEnabledXsrfProtection());
|
||||
assertFalse(config.isEnabledUserConverter());
|
||||
assertEquals("username", config.getNamespaceStrategy());
|
||||
assertEquals("https://scm-manager.org/login-info", config.getLoginInfoUrl());
|
||||
assertEquals("hitchhiker.mail", config.getMailDomainName());
|
||||
@@ -115,6 +115,7 @@ public class ConfigDtoToScmConfigurationMapperTest {
|
||||
configDto.setNamespaceStrategy("username");
|
||||
configDto.setLoginInfoUrl("https://scm-manager.org/login-info");
|
||||
configDto.setMailDomainName("hitchhiker.mail");
|
||||
configDto.setEnabledUserConverter(false);
|
||||
|
||||
return configDto;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import sonia.scm.ContextEntry;
|
||||
import sonia.scm.group.GroupCollector;
|
||||
import sonia.scm.security.ApiKey;
|
||||
import sonia.scm.security.ApiKeyService;
|
||||
import sonia.scm.user.EMail;
|
||||
import sonia.scm.user.InvalidPasswordException;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.user.UserManager;
|
||||
@@ -96,6 +97,9 @@ public class MeResourceTest {
|
||||
@Mock
|
||||
private ApiKeyService apiKeyService;
|
||||
|
||||
@Mock
|
||||
private EMail eMail;
|
||||
|
||||
@InjectMocks
|
||||
private MeDtoFactory meDtoFactory;
|
||||
@InjectMocks
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.github.sdorra.shiro.ShiroRule;
|
||||
import com.github.sdorra.shiro.SubjectAware;
|
||||
import com.google.common.io.Resources;
|
||||
import com.google.inject.util.Providers;
|
||||
import com.sun.mail.iap.Argument;
|
||||
import org.apache.shiro.authc.credential.PasswordService;
|
||||
import org.jboss.resteasy.mock.MockHttpRequest;
|
||||
import org.jboss.resteasy.mock.MockHttpResponse;
|
||||
@@ -58,10 +59,12 @@ import java.util.Collection;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
@@ -457,6 +460,43 @@ public class UserRootResourceTest {
|
||||
assertEquals("other:*", captor.getValue().iterator().next().getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldConvertUserToInternalAndSetNewPassword() throws URISyntaxException {
|
||||
when(passwordService.encryptPassword(anyString())).thenReturn("abc");
|
||||
ArgumentCaptor<User> userCaptor = ArgumentCaptor.forClass(User.class);
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.put("/" + UserRootResource.USERS_PATH_V2 + "Neo/convert-to-internal")
|
||||
.contentType(VndMediaType.USER)
|
||||
.content("{\"newPassword\":\"trillian\"}".getBytes());
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
verify(passwordService).encryptPassword("trillian");
|
||||
verify(userManager).overwritePassword("Neo", "abc");
|
||||
verify(userManager).modify(userCaptor.capture());
|
||||
|
||||
User user = userCaptor.getValue();
|
||||
assertThat(user.isExternal()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldConvertUserToExternalAndRemoveLocalPassword() throws URISyntaxException {
|
||||
ArgumentCaptor<User> userCaptor = ArgumentCaptor.forClass(User.class);
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.put("/" + UserRootResource.USERS_PATH_V2 + "Neo/convert-to-external")
|
||||
.contentType(VndMediaType.USER);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
verify(userManager).overwritePassword("Neo", null);
|
||||
verify(userManager).modify(userCaptor.capture());
|
||||
|
||||
User user = userCaptor.getValue();
|
||||
assertThat(user.isExternal()).isTrue();
|
||||
}
|
||||
|
||||
private PageResult<User> createSingletonPageResult(int overallCount) {
|
||||
return new PageResult<>(singletonList(createDummyUser("Neo")), overallCount);
|
||||
}
|
||||
|
||||
@@ -90,25 +90,15 @@ public class UserToUserDtoMapperTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetPasswordLinkForAdmin() {
|
||||
public void shouldGetInternalUserLinks() {
|
||||
User user = createDefaultUser();
|
||||
user.setExternal(false);
|
||||
when(subject.isPermitted("user:modify:abc")).thenReturn(true);
|
||||
when(userManager.isTypeDefault(eq(user))).thenReturn(true);
|
||||
|
||||
UserDto userDto = mapper.map(user);
|
||||
|
||||
assertEquals("expected password link with modify permission", expectedBaseUri.resolve("abc/password").toString(), userDto.getLinks().getLinkBy("password").get().getHref());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetPasswordLinkOnlyForDefaultUserType() {
|
||||
User user = createDefaultUser();
|
||||
when(subject.isPermitted("user:modify:abc")).thenReturn(true);
|
||||
when(userManager.isTypeDefault(eq(user))).thenReturn(false);
|
||||
|
||||
UserDto userDto = mapper.map(user);
|
||||
|
||||
assertFalse("expected no password link", userDto.getLinks().getLinkBy("password").isPresent());
|
||||
assertEquals("expected convert to external link with modify permission", expectedBaseUri.resolve("abc/convert-to-external").toString(), userDto.getLinks().getLinkBy("convertToExternal").get().getHref());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -148,12 +148,6 @@ class DefaultRepositoryRoleManagerTest {
|
||||
verify(dao).modify(role);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotModifyRole_whenTypeChanged() {
|
||||
assertThrows(ScmConstraintViolationException.class, () -> manager.modify(new RepositoryRole(CUSTOM_ROLE_NAME, singletonList("changed"), null)));
|
||||
verify(dao, never()).modify(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotModifyRole_whenRoleDoesNotExists() {
|
||||
assertThrows(NotFoundException.class, () -> manager.modify(new RepositoryRole("noSuchRole", singletonList("changed"), null)));
|
||||
|
||||
@@ -102,7 +102,7 @@ class JwtAccessTokenBuilderTest {
|
||||
void testBuild() {
|
||||
JwtAccessToken token = factory.create().subject("dent")
|
||||
.issuer("https://www.scm-manager.org")
|
||||
.expiresIn(5, TimeUnit.SECONDS)
|
||||
.expiresIn(1, TimeUnit.MINUTES)
|
||||
.custom("a", "b")
|
||||
.scope(Scope.valueOf("repo:*"))
|
||||
.build();
|
||||
|
||||
@@ -21,66 +21,52 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.user;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
package sonia.scm.user;
|
||||
|
||||
import com.github.sdorra.shiro.ShiroRule;
|
||||
import com.github.sdorra.shiro.SubjectAware;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.store.JAXBConfigurationStoreFactory;
|
||||
import sonia.scm.user.xml.XmlUserDAO;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.junit.Rule;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@SubjectAware(
|
||||
username = "trillian",
|
||||
password = "secret",
|
||||
configuration = "classpath:sonia/scm/repository/shiro.ini"
|
||||
username = "trillian",
|
||||
password = "secret",
|
||||
configuration = "classpath:sonia/scm/repository/shiro.ini"
|
||||
)
|
||||
public class DefaultUserManagerTest extends UserManagerTestBase
|
||||
{
|
||||
public class DefaultUserManagerTest extends UserManagerTestBase {
|
||||
|
||||
@Rule
|
||||
public ShiroRule shiro = new ShiroRule();
|
||||
|
||||
|
||||
private UserDAO userDAO ;
|
||||
private User trillian;
|
||||
private UserDAO userDAO;
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public UserManager createManager()
|
||||
{
|
||||
public UserManager createManager() {
|
||||
return new DefaultUserManager(createXmlUserDAO());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void initDao() {
|
||||
trillian = UserTestData.createTrillian();
|
||||
User trillian = UserTestData.createTrillian();
|
||||
trillian.setPassword("oldEncrypted");
|
||||
|
||||
userDAO = mock(UserDAO.class);
|
||||
@@ -108,15 +94,6 @@ public class DefaultUserManagerTest extends UserManagerTestBase
|
||||
Assertions.assertThat(userCaptor.getValue().getPassword()).isEqualTo("newEncrypted");
|
||||
}
|
||||
|
||||
@Test(expected = ChangePasswordNotAllowedException.class)
|
||||
public void shouldFailOverwritePasswordForWrongType() {
|
||||
trillian.setType("wrongType");
|
||||
|
||||
UserManager userManager = new DefaultUserManager(userDAO);
|
||||
|
||||
userManager.overwritePassword("trillian", "---");
|
||||
}
|
||||
|
||||
@Test(expected = NotFoundException.class)
|
||||
public void shouldFailOverwritePasswordForMissingUser() {
|
||||
UserManager userManager = new DefaultUserManager(userDAO);
|
||||
@@ -124,6 +101,16 @@ public class DefaultUserManagerTest extends UserManagerTestBase
|
||||
userManager.overwritePassword("notExisting", "---");
|
||||
}
|
||||
|
||||
@Test(expected = ChangePasswordNotAllowedException.class)
|
||||
public void shouldFailOverwritePasswordForExternalUser() {
|
||||
User trillian = new User("trillian");
|
||||
trillian.setExternal(true);
|
||||
when(userDAO.get("trillian")).thenReturn(trillian);
|
||||
UserManager userManager = new DefaultUserManager(userDAO);
|
||||
|
||||
userManager.overwritePassword("trillian", "---");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSucceedOverwritePassword() {
|
||||
ArgumentCaptor<User> userCaptor = ArgumentCaptor.forClass(User.class);
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.user;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class InternalToExternalUserConverterTest {
|
||||
|
||||
@Mock
|
||||
ScmConfiguration scmConfiguration;
|
||||
|
||||
@InjectMocks
|
||||
InternalToExternalUserConverter converter;
|
||||
|
||||
@Test
|
||||
void shouldNotConvertExternalUser() {
|
||||
User external = new User();
|
||||
external.setExternal(true);
|
||||
|
||||
User user = converter.convert(external);
|
||||
|
||||
assertThat(user).isSameAs(external);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotConvertIfConfigDisabled() {
|
||||
when(scmConfiguration.isEnabledUserConverter()).thenReturn(false);
|
||||
User external = new User();
|
||||
external.setExternal(false);
|
||||
|
||||
User user = converter.convert(external);
|
||||
|
||||
assertThat(user).isSameAs(external);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnConvertedUser() {
|
||||
when(scmConfiguration.isEnabledUserConverter()).thenReturn(true);
|
||||
User internal = new User();
|
||||
internal.setExternal(false);
|
||||
|
||||
User external = converter.convert(internal);
|
||||
|
||||
assertThat(external).isInstanceOf(User.class);
|
||||
assertThat(external.isExternal()).isTrue();
|
||||
assertThat(external.getPassword()).isNull();
|
||||
}
|
||||
}
|
||||
@@ -91,15 +91,12 @@ class HttpProtocolServletTest {
|
||||
@BeforeEach
|
||||
void prepareMocks() {
|
||||
when(userAgentParser.parse(request)).thenReturn(userAgent);
|
||||
when(userAgent.isBrowser()).thenReturn(true);
|
||||
when(userAgent.isScmClient()).thenReturn(false);
|
||||
when(request.getRequestURI()).thenReturn("uri");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldDispatchBrowserRequests() throws ServletException, IOException {
|
||||
when(userAgent.isBrowser()).thenReturn(true);
|
||||
when(request.getRequestURI()).thenReturn("uri");
|
||||
|
||||
servlet.service(request, response);
|
||||
|
||||
verify(dispatcher).dispatch(request, response, "uri");
|
||||
@@ -113,7 +110,7 @@ class HttpProtocolServletTest {
|
||||
@BeforeEach
|
||||
void prepareMocks() {
|
||||
when(userAgentParser.parse(request)).thenReturn(userAgent);
|
||||
when(userAgent.isBrowser()).thenReturn(false);
|
||||
when(userAgent.isScmClient()).thenReturn(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user