package de.vorb.platon.security;

import com.google.common.truth.Truth;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.test.annotation.Repeat;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.time.Instant;

@RunWith(MockitoJUnitRunner.class)
public class HmacRequestVerifierTest {

    @Mock
    private SecretKeyProvider secretKeyProvider;

    private HmacRequestVerifier requestVerifier;

    @Before
    public void setUp() throws Exception {

        // generate a secret key once and always return that secret key
        final SecretKey secretKey = KeyGenerator.getInstance(
                HmacRequestVerifier.HMAC_ALGORITHM.toString()).generateKey();
        Mockito.when(secretKeyProvider.getSecretKey()).thenReturn(secretKey);

        requestVerifier = new HmacRequestVerifier(secretKeyProvider);

    }

    @Test
    @Repeat(1)
    public void testGetSignatureTokenIsRepeatable() throws Exception {

        final String identifier = "comment/1";
        final Instant expirationDate = Instant.now();

        final byte[] firstSignatureToken = requestVerifier.getSignatureToken(identifier, expirationDate);
        final byte[] secondSignatureToken = requestVerifier.getSignatureToken(identifier, expirationDate);

        Truth.assertThat(firstSignatureToken).isEqualTo(secondSignatureToken);
    }
}

@@ -27,16 +27,58 @@
 urity;%0A%0A
+import de.vorb.platon.util.TimeProvider;%0A%0A
 import c
@@ -103,24 +103,24 @@
 ruth.Truth;%0A
-
 import org.j
@@ -192,40 +192,8 @@
 th;%0A
-import org.mockito.InjectMocks;%0A
 impo
@@ -563,24 +563,74 @@
 yProvider;%0A%0A
+    @Mock%0A    private TimeProvider timeProvider;%0A%0A
     private 
@@ -1081,16 +1081,30 @@
 Provider
+, timeProvider
 );%0A%0A    
@@ -1129,16 +1129,17 @@
 Repeat(1
+0
 )%0A    pu
@@ -1599,16 +1599,1363 @@
 Token);%0A
+%0A
     %7D%0A
+%0A    @Test%0A    public void testTokenExpiration() throws Exception %7B%0A%0A        final String identifier = %22comment/1%22;%0A%0A        final Instant currentTime = Instant.now();%0A        Mockito.when(timeProvider.getCurrentTime()).thenReturn(currentTime);%0A%0A        final Instant expirationDate = currentTime.minusMillis(1); // token expired 1ms ago%0A        final byte%5B%5D signatureToken = requestVerifier.getSignatureToken(identifier, expirationDate);%0A%0A        final boolean validity = requestVerifier.isRequestValid(identifier, expirationDate, signatureToken);%0A%0A        Truth.assertThat(validity).isFalse();%0A%0A    %7D%0A%0A    @Test%0A    public void testCannotFakeExpirationDate() throws Exception %7B%0A%0A        final String identifier = %22comment/1%22;%0A%0A        final Instant currentTime = Instant.now();%0A        Mockito.when(timeProvider.getCurrentTime()).thenReturn(currentTime);%0A%0A        final Instant expirationDate = currentTime.minusMillis(1);%0A        final byte%5B%5D signatureToken = requestVerifier.getSignatureToken(identifier, expirationDate);%0A%0A        // a user attempts to set the expiration date manually (without changing the token)%0A        final Instant fakedExpirationDate = currentTime;%0A%0A        final boolean validity = requestVerifier.isRequestValid(identifier, fakedExpirationDate, signatureToken);%0A%0A        Truth.assertThat(validity).isFalse();%0A%0A    %7D%0A%0A
 %7D%0A

Add tests for expiration, faked req. verification