Skip to content

Commit d9d0819

Browse files
committed
lock down share info secrets a bit
1 parent ccce3fe commit d9d0819

2 files changed

Lines changed: 47 additions & 16 deletions

File tree

src/main/java/com/brennaswitzer/cookbook/util/ShareHelper.java

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import com.brennaswitzer.cookbook.domain.Named;
66
import com.brennaswitzer.cookbook.payload.ShareInfo;
77
import com.google.common.annotations.VisibleForTesting;
8+
import com.nimbusds.jose.jwk.source.ImmutableSecret;
9+
import com.nimbusds.jose.proc.SecurityContext;
810
import org.apache.commons.codec.digest.HmacAlgorithms;
911
import org.apache.commons.codec.digest.HmacUtils;
1012
import org.springframework.beans.factory.annotation.Autowired;
@@ -14,35 +16,39 @@
1416
@Component
1517
public class ShareHelper {
1618

19+
private ImmutableSecret<SecurityContext> secret;
20+
1721
@Autowired
18-
private AppProperties appProperties;
22+
public void setAppProperties(AppProperties appProperties) {
23+
this.secret = new ImmutableSecret<>(
24+
appProperties.getAuth()
25+
.getTokenSecret()
26+
.getBytes());
27+
}
1928

2029
public <T extends Identified> ShareInfo getInfo(Class<T> clazz, T object) {
2130
return new ShareInfo(object.getId(),
2231
SlugUtils.toSlug(object instanceof Named named
2332
? named.getName()
2433
: clazz.getSimpleName(), 40),
25-
getSecret(clazz, object.getId()));
34+
getHmacSecret(clazz, object.getId()));
2635
}
2736

2837
@VisibleForTesting
29-
String getSecret(Class<?> clazz, Long id) {
38+
String getHmacSecret(Class<?> clazz, Long id) {
3039
Assert.notNull(clazz, "Cannot generate a secret for the null class");
3140
Assert.notNull(id, "Cannot generate a secret for the null id");
32-
return new HmacUtils(
33-
HmacAlgorithms.HMAC_SHA_1,
34-
appProperties.getAuth().getTokenSecret().getBytes()
35-
).hmacHex(
36-
(clazz.getName() + '#' + id).getBytes()
37-
);
41+
return new HmacUtils(HmacAlgorithms.HMAC_SHA_1,
42+
secret.getSecret())
43+
.hmacHex((clazz.getName() + '#' + id).getBytes());
3844
}
3945

4046
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
4147
public boolean isSecretValid(Class<?> clazz, Long id, String secret) {
4248
Assert.notNull(clazz, "Cannot validate a secret for the null class");
4349
Assert.notNull(id, "Cannot validate a secret for the null id");
4450
Assert.notNull(secret, "Cannot validate the null secret");
45-
return secret.equals(getSecret(clazz, id));
51+
return secret.equals(getHmacSecret(clazz, id));
4652
}
4753

4854
}
Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
package com.brennaswitzer.cookbook.util;
22

3+
import com.brennaswitzer.cookbook.config.AppProperties;
34
import com.brennaswitzer.cookbook.domain.Identified;
45
import com.brennaswitzer.cookbook.domain.Named;
6+
import com.brennaswitzer.cookbook.domain.Recipe;
57
import com.brennaswitzer.cookbook.payload.ShareInfo;
68
import lombok.Value;
9+
import org.junit.jupiter.api.BeforeEach;
710
import org.junit.jupiter.api.Test;
811
import org.junit.jupiter.api.extension.ExtendWith;
912
import org.mockito.InjectMocks;
13+
import org.mockito.Mock;
1014
import org.mockito.Spy;
1115
import org.mockito.junit.jupiter.MockitoExtension;
1216

1317
import static org.junit.jupiter.api.Assertions.assertEquals;
14-
import static org.mockito.Mockito.doReturn;
18+
import static org.junit.jupiter.api.Assertions.assertTrue;
19+
import static org.mockito.Mockito.when;
1520

1621
@ExtendWith(MockitoExtension.class)
1722
class ShareHelperTest {
@@ -20,6 +25,19 @@ class ShareHelperTest {
2025
@Spy
2126
private ShareHelper helper;
2227

28+
@Mock
29+
private AppProperties appProperties;
30+
31+
@Mock
32+
private AppProperties.Auth auth;
33+
34+
@BeforeEach
35+
void setUp() {
36+
when(appProperties.getAuth()).thenReturn(auth);
37+
when(auth.getTokenSecret()).thenReturn("some-random-key");
38+
helper.setAppProperties(appProperties);
39+
}
40+
2341
@Value
2442
private static class Shareable implements Identified, Named {
2543

@@ -31,17 +49,24 @@ private static class Shareable implements Identified, Named {
3149
@Test
3250
void getInfo() {
3351
long id = 123L;
34-
String secret = "secret";
35-
doReturn(secret)
36-
.when(helper)
37-
.getSecret(Shareable.class, id);
52+
String anonSecret = "329bb9790fd6c157e68cb4187cf52b11b6e9f4ba";
3853

3954
ShareInfo info = helper.getInfo(Shareable.class,
4055
new Shareable(id, "A Thinger!"));
4156

4257
assertEquals(id, info.getId());
4358
assertEquals("a-thinger", info.getSlug());
44-
assertEquals(secret, info.getSecret());
59+
assertTrue(helper.isSecretValid(Shareable.class, id, info.getSecret()));
60+
assertTrue(helper.isSecretValid(Shareable.class, id, anonSecret));
61+
}
62+
63+
@Test
64+
void getHmacSecret() {
65+
long id = 877123L;
66+
String anonSecret = helper.getHmacSecret(Recipe.class, id);
67+
68+
assertEquals("6922b21b1364896cdfbd6ad930a50975c15a198a", anonSecret);
69+
assertTrue(helper.isSecretValid(Recipe.class, id, anonSecret));
4570
}
4671

4772
}

0 commit comments

Comments
 (0)