mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-06-17 15:40:56 +02:00
Merge with 2.0.0-m3
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import sonia.scm.repository.Branch;
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class BranchToBranchDtoMapperTest {
|
||||
|
||||
private final URI baseUri = URI.create("https://hitchhiker.com");
|
||||
|
||||
@SuppressWarnings("unused") // Is injected
|
||||
private final ResourceLinks resourceLinks = ResourceLinksMock.createMock(baseUri);
|
||||
|
||||
@InjectMocks
|
||||
private BranchToBranchDtoMapperImpl mapper;
|
||||
|
||||
@Test
|
||||
void shouldAppendLinks() {
|
||||
LinkEnricherRegistry registry = new LinkEnricherRegistry();
|
||||
registry.register(Branch.class, (ctx, appender) -> {
|
||||
NamespaceAndName namespaceAndName = ctx.oneRequireByType(NamespaceAndName.class);
|
||||
Branch branch = ctx.oneRequireByType(Branch.class);
|
||||
|
||||
appender.appendOne("ka", "http://" + namespaceAndName.logString() + "/" + branch.getName());
|
||||
});
|
||||
mapper.setRegistry(registry);
|
||||
|
||||
Branch branch = new Branch("master", "42");
|
||||
|
||||
BranchDto dto = mapper.map(branch, new NamespaceAndName("hitchhiker", "heart-of-gold"));
|
||||
assertThat(dto.getLinks().getLinkBy("ka").get().getHref()).isEqualTo("http://hitchhiker/heart-of-gold/master");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import de.otto.edison.hal.Link;
|
||||
import de.otto.edison.hal.Links;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static de.otto.edison.hal.Links.linkingTo;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class EdisonLinkAppenderTest {
|
||||
|
||||
private Links.Builder builder;
|
||||
private EdisonLinkAppender appender;
|
||||
|
||||
@BeforeEach
|
||||
void prepare() {
|
||||
builder = linkingTo();
|
||||
appender = new EdisonLinkAppender(builder);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldAppendOneLink() {
|
||||
appender.appendOne("self", "https://scm.hitchhiker.com");
|
||||
|
||||
Links links = builder.build();
|
||||
assertThat(links.getLinkBy("self").get().getHref()).isEqualTo("https://scm.hitchhiker.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldAppendMultipleLinks() {
|
||||
appender.arrayBuilder("items")
|
||||
.append("one", "http://one")
|
||||
.append("two", "http://two")
|
||||
.build();
|
||||
|
||||
List<Link> items = builder.build().getLinksBy("items");
|
||||
assertThat(items).hasSize(2);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -71,6 +71,24 @@ public class FileObjectToFileObjectDtoMapperTest {
|
||||
assertThat(dto.getLinks().getLinkBy("self").get().getHref()).isEqualTo(expectedBaseUri.resolve("namespace/name/content/revision/foo/bar").toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAppendLinks() {
|
||||
LinkEnricherRegistry registry = new LinkEnricherRegistry();
|
||||
registry.register(FileObject.class, (ctx, appender) -> {
|
||||
NamespaceAndName repository = ctx.oneRequireByType(NamespaceAndName.class);
|
||||
FileObject fo = ctx.oneRequireByType(FileObject.class);
|
||||
String rev = ctx.oneRequireByType(String.class);
|
||||
|
||||
appender.appendOne("hog", "http://" + repository.logString() + "/" + fo.getName() + "/" + rev);
|
||||
});
|
||||
mapper.setRegistry(registry);
|
||||
|
||||
FileObject fileObject = createFileObject();
|
||||
FileObjectDto dto = mapper.map(fileObject, new NamespaceAndName("hitchhiker", "hog"), "42");
|
||||
|
||||
assertThat(dto.getLinks().getLinkBy("hog").get().getHref()).isEqualTo("http://hitchhiker/hog/foo/42");
|
||||
}
|
||||
|
||||
private FileObject createDirectoryObject() {
|
||||
FileObject fileObject = createFileObject();
|
||||
fileObject.setDirectory(true);
|
||||
|
||||
@@ -35,7 +35,7 @@ public class GroupToGroupDtoMapperTest {
|
||||
private URI expectedBaseUri;
|
||||
|
||||
@Before
|
||||
public void init() throws URISyntaxException {
|
||||
public void init() {
|
||||
initMocks(this);
|
||||
expectedBaseUri = baseUri.resolve(GroupRootResource.GROUPS_PATH_V2 + "/");
|
||||
subjectThreadState.bind();
|
||||
@@ -89,6 +89,21 @@ public class GroupToGroupDtoMapperTest {
|
||||
assertEquals("http://example.com/base/v2/users/user0", actualMember.getLinks().getLinkBy("self").get().getHref());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAppendLinks() {
|
||||
LinkEnricherRegistry registry = new LinkEnricherRegistry();
|
||||
registry.register(Group.class, (ctx, appender) -> {
|
||||
Group group = ctx.oneRequireByType(Group.class);
|
||||
appender.appendOne("some", "http://" + group.getName());
|
||||
});
|
||||
mapper.setRegistry(registry);
|
||||
|
||||
Group group = createDefaultGroup();
|
||||
GroupDto dto = mapper.map(group);
|
||||
|
||||
assertEquals("http://abc", dto.getLinks().getLinkBy("some").get().getHref());
|
||||
}
|
||||
|
||||
private Group createDefaultGroup() {
|
||||
Group group = new Group();
|
||||
group.setName("abc");
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static org.assertj.core.api.Java6Assertions.assertThat;
|
||||
|
||||
class LinkEnricherAutoRegistrationTest {
|
||||
|
||||
@Test
|
||||
void shouldRegisterAllAvailableLinkEnrichers() {
|
||||
LinkEnricher one = new One();
|
||||
LinkEnricher two = new Two();
|
||||
LinkEnricher three = new Three();
|
||||
LinkEnricher four = new Four();
|
||||
Set<LinkEnricher> enrichers = ImmutableSet.of(one, two, three, four);
|
||||
|
||||
LinkEnricherRegistry registry = new LinkEnricherRegistry();
|
||||
|
||||
LinkEnricherAutoRegistration autoRegistration = new LinkEnricherAutoRegistration(registry, enrichers);
|
||||
autoRegistration.contextInitialized(null);
|
||||
|
||||
assertThat(registry.allByType(String.class)).containsOnly(one, two);
|
||||
assertThat(registry.allByType(Integer.class)).containsOnly(three);
|
||||
}
|
||||
|
||||
@Enrich(String.class)
|
||||
public static class One implements LinkEnricher {
|
||||
|
||||
@Override
|
||||
public void enrich(LinkEnricherContext context, LinkAppender appender) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Enrich(String.class)
|
||||
public static class Two implements LinkEnricher {
|
||||
|
||||
@Override
|
||||
public void enrich(LinkEnricherContext context, LinkAppender appender) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Enrich(Integer.class)
|
||||
public static class Three implements LinkEnricher {
|
||||
|
||||
@Override
|
||||
public void enrich(LinkEnricherContext context, LinkAppender appender) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static class Four implements LinkEnricher {
|
||||
|
||||
@Override
|
||||
public void enrich(LinkEnricherContext context, LinkAppender appender) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.user.UserManager;
|
||||
import sonia.scm.user.UserTestData;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
@@ -124,6 +125,21 @@ public class MeToUserDtoMapperTest {
|
||||
assertThat(userDto.getPassword()).as("hide password for the me resource").isBlank();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAppendLinks() {
|
||||
LinkEnricherRegistry registry = new LinkEnricherRegistry();
|
||||
registry.register(Me.class, (ctx, appender) -> {
|
||||
User user = ctx.oneRequireByType(User.class);
|
||||
appender.appendOne("profile", "http://hitchhiker.com/users/" + user.getName());
|
||||
});
|
||||
mapper.setRegistry(registry);
|
||||
|
||||
User trillian = UserTestData.createTrillian();
|
||||
UserDto dto = mapper.map(trillian);
|
||||
|
||||
assertEquals("http://hitchhiker.com/users/trillian", dto.getLinks().getLinkBy("profile").get().getHref());
|
||||
}
|
||||
|
||||
private User createDefaultUser() {
|
||||
User user = new User();
|
||||
user.setName("abc");
|
||||
|
||||
@@ -211,6 +211,19 @@ public class RepositoryToRepositoryDtoMapperTest {
|
||||
assertTrue(dto.getLinks().getLinksBy("protocol").isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAppendLinks() {
|
||||
LinkEnricherRegistry registry = new LinkEnricherRegistry();
|
||||
registry.register(Repository.class, (ctx, appender) -> {
|
||||
Repository repository = ctx.oneRequireByType(Repository.class);
|
||||
appender.appendOne("id", "http://" + repository.getId());
|
||||
});
|
||||
mapper.setRegistry(registry);
|
||||
|
||||
RepositoryDto dto = mapper.map(createTestRepository());
|
||||
assertEquals("http://1", dto.getLinks().getLinkBy("id").get().getHref());
|
||||
}
|
||||
|
||||
private ScmProtocol mockProtocol(String type, String protocol) {
|
||||
return new MockScmProtocol(type, protocol);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.Tag;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TagToTagDtoMapperTest {
|
||||
|
||||
@SuppressWarnings("unused") // Is injected
|
||||
private final ResourceLinks resourceLinks = ResourceLinksMock.createMock(URI.create("https://hitchhiker.com"));
|
||||
|
||||
@InjectMocks
|
||||
private TagToTagDtoMapperImpl mapper;
|
||||
|
||||
@Test
|
||||
void shouldAppendLinks() {
|
||||
LinkEnricherRegistry registry = new LinkEnricherRegistry();
|
||||
registry.register(Tag.class, (ctx, appender) -> {
|
||||
NamespaceAndName repository = ctx.oneRequireByType(NamespaceAndName.class);
|
||||
Tag tag = ctx.oneRequireByType(Tag.class);
|
||||
appender.appendOne("yo", "http://" + repository.logString() + "/" + tag.getName());
|
||||
});
|
||||
mapper.setRegistry(registry);
|
||||
|
||||
TagDto dto = mapper.map(new Tag("1.0.0", "42"), new NamespaceAndName("hitchhiker", "hog"));
|
||||
assertThat(dto.getLinks().getLinkBy("yo").get().getHref()).isEqualTo("http://hitchhiker/hog/1.0.0");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.user.UserManager;
|
||||
import sonia.scm.user.UserTestData;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.Instant;
|
||||
@@ -149,4 +150,17 @@ public class UserToUserDtoMapperTest {
|
||||
assertEquals(expectedCreationDate, userDto.getCreationDate());
|
||||
assertEquals(expectedModificationDate, userDto.getLastModified());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAppendLink() {
|
||||
User trillian = UserTestData.createTrillian();
|
||||
|
||||
LinkEnricherRegistry registry = new LinkEnricherRegistry();
|
||||
registry.register(User.class, (ctx, appender) -> appender.appendOne("sample", "http://" + ctx.oneByType(User.class).get().getName()));
|
||||
mapper.setRegistry(registry);
|
||||
|
||||
UserDto userDto = mapper.map(trillian);
|
||||
|
||||
assertEquals("http://trillian", userDto.getLinks().getLinkBy("sample").get().getHref());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,271 +29,98 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.security;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Sets;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.JwsHeader;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.AuthenticationInfo;
|
||||
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||
import org.apache.shiro.subject.PrincipalCollection;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import sonia.scm.group.GroupDAO;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.user.UserDAO;
|
||||
import sonia.scm.user.UserTestData;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
import java.util.HashMap;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static sonia.scm.security.SecureKeyTestUtil.createSecureKey;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link BearerRealm}.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class BearerRealmTest
|
||||
{
|
||||
|
||||
@Rule
|
||||
public ExpectedException expectedException = ExpectedException.none();
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class BearerRealmTest {
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testDoGetAuthenticationInfo()
|
||||
{
|
||||
SecureKey key = createSecureKey();
|
||||
@Mock
|
||||
private DAORealmHelperFactory realmHelperFactory;
|
||||
|
||||
User marvin = UserTestData.createMarvin();
|
||||
@Mock
|
||||
private DAORealmHelper realmHelper;
|
||||
|
||||
when(userDAO.get(marvin.getName())).thenReturn(marvin);
|
||||
@Mock
|
||||
private AccessTokenResolver accessTokenResolver;
|
||||
|
||||
resolveKey(key);
|
||||
|
||||
String compact = createCompactToken(marvin.getName(), key);
|
||||
|
||||
BearerToken token = BearerToken.valueOf(compact);
|
||||
AuthenticationInfo info = realm.doGetAuthenticationInfo(token);
|
||||
|
||||
assertNotNull(info);
|
||||
|
||||
PrincipalCollection principals = info.getPrincipals();
|
||||
|
||||
assertEquals(marvin.getName(), principals.getPrimaryPrincipal());
|
||||
assertEquals(marvin, principals.oneByType(User.class));
|
||||
assertNotNull(principals.oneByType(Scope.class));
|
||||
assertTrue(principals.oneByType(Scope.class).isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link BearerRealm#doGetAuthenticationInfo(AuthenticationToken)} with scope.
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testDoGetAuthenticationInfoWithScope()
|
||||
{
|
||||
SecureKey key = createSecureKey();
|
||||
|
||||
User marvin = UserTestData.createMarvin();
|
||||
|
||||
when(userDAO.get(marvin.getName())).thenReturn(marvin);
|
||||
|
||||
resolveKey(key);
|
||||
|
||||
String compact = createCompactToken(
|
||||
marvin.getName(),
|
||||
key,
|
||||
new Date(System.currentTimeMillis() + 60000),
|
||||
Scope.valueOf("repo:*", "user:*")
|
||||
);
|
||||
|
||||
AuthenticationInfo info = realm.doGetAuthenticationInfo(BearerToken.valueOf(compact));
|
||||
Scope scope = info.getPrincipals().oneByType(Scope.class);
|
||||
assertThat(scope, Matchers.containsInAnyOrder("repo:*", "user:*"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link BearerRealm#doGetAuthenticationInfo(AuthenticationToken)} with a failed
|
||||
* claims validation.
|
||||
*/
|
||||
@Test
|
||||
public void testDoGetAuthenticationInfoWithInvalidClaims()
|
||||
{
|
||||
SecureKey key = createSecureKey();
|
||||
User marvin = UserTestData.createMarvin();
|
||||
|
||||
resolveKey(key);
|
||||
|
||||
String compact = createCompactToken(marvin.getName(), key);
|
||||
|
||||
// treat claims as invalid
|
||||
when(validator.validate(Mockito.anyMap())).thenReturn(false);
|
||||
|
||||
// expect exception
|
||||
expectedException.expect(AuthenticationException.class);
|
||||
expectedException.expectMessage(Matchers.containsString("claims"));
|
||||
|
||||
// kick authentication
|
||||
realm.doGetAuthenticationInfo(BearerToken.valueOf(compact));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test(expected = AuthenticationException.class)
|
||||
public void testDoGetAuthenticationInfoWithExpiredToken()
|
||||
{
|
||||
User trillian = UserTestData.createTrillian();
|
||||
|
||||
SecureKey key = createSecureKey();
|
||||
|
||||
resolveKey(key);
|
||||
|
||||
Date exp = new Date(System.currentTimeMillis() - 600l);
|
||||
String compact = createCompactToken(trillian.getName(), key, exp, Scope.empty());
|
||||
|
||||
realm.doGetAuthenticationInfo(BearerToken.valueOf(compact));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test(expected = AuthenticationException.class)
|
||||
public void testDoGetAuthenticationInfoWithInvalidSignature()
|
||||
{
|
||||
resolveKey(createSecureKey());
|
||||
|
||||
User trillian = UserTestData.createTrillian();
|
||||
String compact = createCompactToken(trillian.getName(), createSecureKey());
|
||||
|
||||
realm.doGetAuthenticationInfo(BearerToken.valueOf(compact));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test(expected = AuthenticationException.class)
|
||||
public void testDoGetAuthenticationInfoWithoutSignature()
|
||||
{
|
||||
String compact = Jwts.builder().setSubject("test").compact();
|
||||
|
||||
realm.doGetAuthenticationInfo(BearerToken.valueOf(compact));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testDoGetAuthenticationInfoWrongToken()
|
||||
{
|
||||
realm.doGetAuthenticationInfo(new UsernamePasswordToken("test", "test"));
|
||||
}
|
||||
|
||||
//~--- set methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
when(validator.validate(Mockito.anyMap())).thenReturn(true);
|
||||
Set<TokenClaimsValidator> validators = Sets.newHashSet(validator);
|
||||
realm = new BearerRealm(helperFactory, keyResolver, validators);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
private String createCompactToken(String subject, SecureKey key) {
|
||||
return createCompactToken(subject, key, Scope.empty());
|
||||
}
|
||||
|
||||
private String createCompactToken(String subject, SecureKey key, Scope scope) {
|
||||
return createCompactToken(subject, key, new Date(System.currentTimeMillis() + 60000), scope);
|
||||
}
|
||||
|
||||
private String createCompactToken(String subject, SecureKey key, Date exp, Scope scope) {
|
||||
return Jwts.builder()
|
||||
.claim(Scopes.CLAIMS_KEY, ImmutableList.copyOf(scope))
|
||||
.setSubject(subject)
|
||||
.setExpiration(exp)
|
||||
.signWith(SignatureAlgorithm.HS256, key.getBytes())
|
||||
.compact();
|
||||
}
|
||||
|
||||
private void resolveKey(SecureKey key) {
|
||||
when(
|
||||
keyResolver.resolveSigningKey(
|
||||
any(JwsHeader.class),
|
||||
any(Claims.class)
|
||||
)
|
||||
)
|
||||
.thenReturn(
|
||||
new SecretKeySpec(
|
||||
key.getBytes(),
|
||||
SignatureAlgorithm.HS256.getJcaName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
@InjectMocks
|
||||
private DAORealmHelperFactory helperFactory;
|
||||
|
||||
@Mock
|
||||
private LoginAttemptHandler loginAttemptHandler;
|
||||
|
||||
@Mock
|
||||
private TokenClaimsValidator validator;
|
||||
|
||||
/** Field description */
|
||||
@Mock
|
||||
private GroupDAO groupDAO;
|
||||
|
||||
/** Field description */
|
||||
@Mock
|
||||
private SecureKeyResolver keyResolver;
|
||||
|
||||
/** Field description */
|
||||
private BearerRealm realm;
|
||||
|
||||
/** Field description */
|
||||
@Mock
|
||||
private UserDAO userDAO;
|
||||
private AuthenticationInfo authenticationInfo;
|
||||
|
||||
@BeforeEach
|
||||
void prepareObjectUnderTest() {
|
||||
when(realmHelperFactory.create(BearerRealm.REALM)).thenReturn(realmHelper);
|
||||
realm = new BearerRealm(realmHelperFactory, accessTokenResolver);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldDoGetAuthentication() {
|
||||
BearerToken bearerToken = BearerToken.valueOf("__bearer__");
|
||||
AccessToken accessToken = mock(AccessToken.class);
|
||||
when(accessToken.getSubject()).thenReturn("trillian");
|
||||
when(accessToken.getClaims()).thenReturn(new HashMap<>());
|
||||
|
||||
when(accessTokenResolver.resolve(bearerToken)).thenReturn(accessToken);
|
||||
|
||||
// we have to use answer, because we could not mock the result of Scopes
|
||||
when(realmHelper.getAuthenticationInfo(
|
||||
anyString(), anyString(), any(Scope.class)
|
||||
)).thenAnswer(createAnswer("trillian", "__bearer__", true));
|
||||
|
||||
AuthenticationInfo result = realm.doGetAuthenticationInfo(bearerToken);
|
||||
assertThat(result).isSameAs(authenticationInfo);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowIllegalArgumentExceptionForWrongTypeOfToken() {
|
||||
assertThrows(IllegalArgumentException.class, () -> realm.doGetAuthenticationInfo(new UsernamePasswordToken()));
|
||||
}
|
||||
|
||||
private Answer<AuthenticationInfo> createAnswer(String expectedSubject, String expectedCredentials, boolean scopeEmpty) {
|
||||
return (iom) -> {
|
||||
String subject = iom.getArgument(0);
|
||||
assertThat(subject).isEqualTo(expectedSubject);
|
||||
String credentials = iom.getArgument(1);
|
||||
assertThat(credentials).isEqualTo(expectedCredentials);
|
||||
Scope scope = iom.getArgument(2);
|
||||
assertThat(scope.isEmpty()).isEqualTo(scopeEmpty);
|
||||
|
||||
return authenticationInfo;
|
||||
};
|
||||
}
|
||||
|
||||
private class MyAnswer implements Answer<AuthenticationInfo> {
|
||||
|
||||
@Override
|
||||
public AuthenticationInfo answer(InvocationOnMock invocationOnMock) throws Throwable {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,26 +40,27 @@ import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import io.jsonwebtoken.SignatureException;
|
||||
import io.jsonwebtoken.UnsupportedJwtException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static sonia.scm.security.SecureKeyTestUtil.createSecureKey;
|
||||
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static sonia.scm.security.SecureKeyTestUtil.createSecureKey;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link JwtAccessTokenResolver}.
|
||||
*
|
||||
@@ -70,14 +71,12 @@ public class JwtAccessTokenResolverTest {
|
||||
|
||||
@Rule
|
||||
public ExpectedException expectedException = ExpectedException.none();
|
||||
|
||||
private final SecureRandom random = new SecureRandom();
|
||||
|
||||
|
||||
@Mock
|
||||
private SecureKeyResolver keyResolver;
|
||||
|
||||
@Mock
|
||||
private TokenClaimsValidator validator;
|
||||
private AccessTokenValidator validator;
|
||||
|
||||
private JwtAccessTokenResolver resolver;
|
||||
|
||||
@@ -86,8 +85,8 @@ public class JwtAccessTokenResolverTest {
|
||||
*/
|
||||
@Before
|
||||
public void prepareObjectUnderTest() {
|
||||
Set<TokenClaimsValidator> validators = Sets.newHashSet(validator);
|
||||
when(validator.validate(anyMap())).thenReturn(true);
|
||||
Set<AccessTokenValidator> validators = Sets.newHashSet(validator);
|
||||
when(validator.validate(Mockito.any(AccessToken.class))).thenReturn(true);
|
||||
resolver = new JwtAccessTokenResolver(keyResolver, validators);
|
||||
}
|
||||
|
||||
@@ -115,11 +114,11 @@ public class JwtAccessTokenResolverTest {
|
||||
String compact = createCompactToken("marvin", secureKey);
|
||||
|
||||
// prepare mock
|
||||
when(validator.validate(anyMap())).thenReturn(false);
|
||||
when(validator.validate(Mockito.any(AccessToken.class))).thenReturn(false);
|
||||
|
||||
// expect exception
|
||||
expectedException.expect(AuthenticationException.class);
|
||||
expectedException.expectMessage(Matchers.containsString("claims"));
|
||||
expectedException.expectMessage(Matchers.containsString("token"));
|
||||
|
||||
BearerToken bearer = BearerToken.valueOf(compact);
|
||||
resolver.resolve(bearer);
|
||||
|
||||
@@ -31,88 +31,90 @@
|
||||
|
||||
package sonia.scm.security;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import java.util.Map;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import static org.mockito.Mockito.*;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Tests {@link XsrfTokenClaimsValidator}.
|
||||
* Tests {@link XsrfAccessTokenValidator}.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class XsrfTokenClaimsValidatorTest {
|
||||
public class XsrfAccessTokenValidatorTest {
|
||||
|
||||
@Mock
|
||||
private HttpServletRequest request;
|
||||
|
||||
private XsrfTokenClaimsValidator validator;
|
||||
@Mock
|
||||
private AccessToken accessToken;
|
||||
|
||||
private XsrfAccessTokenValidator validator;
|
||||
|
||||
/**
|
||||
* Prepare object under test.
|
||||
*/
|
||||
@Before
|
||||
public void prepareObjectUnderTest() {
|
||||
validator = new XsrfTokenClaimsValidator(() -> request);
|
||||
validator = new XsrfAccessTokenValidator(() -> request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link XsrfTokenClaimsValidator#validate(java.util.Map)}.
|
||||
* Tests {@link XsrfAccessTokenValidator#validate(AccessToken)}.
|
||||
*/
|
||||
@Test
|
||||
public void testValidate() {
|
||||
// prepare
|
||||
Map<String, Object> claims = Maps.newHashMap();
|
||||
claims.put(Xsrf.TOKEN_KEY, "abc");
|
||||
when(accessToken.getCustom(Xsrf.TOKEN_KEY)).thenReturn(Optional.of("abc"));
|
||||
when(request.getHeader(Xsrf.HEADER_KEY)).thenReturn("abc");
|
||||
|
||||
// execute and assert
|
||||
assertTrue(validator.validate(claims));
|
||||
assertTrue(validator.validate(accessToken));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link XsrfTokenClaimsValidator#validate(java.util.Map)} with wrong header.
|
||||
* Tests {@link XsrfAccessTokenValidator#validate(AccessToken)} with wrong header.
|
||||
*/
|
||||
@Test
|
||||
public void testValidateWithWrongHeader() {
|
||||
// prepare
|
||||
Map<String, Object> claims = Maps.newHashMap();
|
||||
claims.put(Xsrf.TOKEN_KEY, "abc");
|
||||
when(accessToken.getCustom(Xsrf.TOKEN_KEY)).thenReturn(Optional.of("abc"));
|
||||
when(request.getHeader(Xsrf.HEADER_KEY)).thenReturn("123");
|
||||
|
||||
// execute and assert
|
||||
assertFalse(validator.validate(claims));
|
||||
assertFalse(validator.validate(accessToken));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link XsrfTokenClaimsValidator#validate(java.util.Map)} without header.
|
||||
* Tests {@link XsrfAccessTokenValidator#validate(AccessToken)} without header.
|
||||
*/
|
||||
@Test
|
||||
public void testValidateWithoutHeader() {
|
||||
// prepare
|
||||
Map<String, Object> claims = Maps.newHashMap();
|
||||
claims.put(Xsrf.TOKEN_KEY, "abc");
|
||||
when(accessToken.getCustom(Xsrf.TOKEN_KEY)).thenReturn(Optional.of("abc"));
|
||||
|
||||
// execute and assert
|
||||
assertFalse(validator.validate(claims));
|
||||
assertFalse(validator.validate(accessToken));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link XsrfTokenClaimsValidator#validate(java.util.Map)} without claims key.
|
||||
* Tests {@link XsrfAccessTokenValidator#validate(AccessToken)} without claims key.
|
||||
*/
|
||||
@Test
|
||||
public void testValidateWithoutClaimsKey() {
|
||||
// prepare
|
||||
Map<String, Object> claims = Maps.newHashMap();
|
||||
when(accessToken.getCustom(Xsrf.TOKEN_KEY)).thenReturn(Optional.empty());
|
||||
|
||||
// execute and assert
|
||||
assertTrue(validator.validate(claims));
|
||||
assertTrue(validator.validate(accessToken));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user