1 package de.dlr.shepard.auth.apikey.services;
2
3 import static org.junit.jupiter.api.Assertions.assertEquals;
4 import static org.junit.jupiter.api.Assertions.assertThrows;
5 import static org.junit.jupiter.api.Assertions.assertTrue;
6 import static org.mockito.Mockito.when;
7
8 import de.dlr.shepard.BaseTestCase;
9 import de.dlr.shepard.auth.apikey.daos.ApiKeyDAO;
10 import de.dlr.shepard.auth.apikey.entities.ApiKey;
11 import de.dlr.shepard.auth.apikey.io.ApiKeyIO;
12 import de.dlr.shepard.auth.security.AuthenticationContext;
13 import de.dlr.shepard.auth.security.JWTPrincipal;
14 import de.dlr.shepard.auth.users.entities.User;
15 import de.dlr.shepard.auth.users.services.UserService;
16 import de.dlr.shepard.common.exceptions.InvalidPathException;
17 import de.dlr.shepard.common.util.DateHelper;
18 import de.dlr.shepard.common.util.PKIHelper;
19 import io.jsonwebtoken.Jwts;
20 import io.quarkus.test.InjectMock;
21 import io.quarkus.test.component.QuarkusComponentTest;
22 import jakarta.inject.Inject;
23 import java.security.KeyFactory;
24 import java.security.NoSuchAlgorithmException;
25 import java.security.PrivateKey;
26 import java.security.spec.InvalidKeySpecException;
27 import java.security.spec.PKCS8EncodedKeySpec;
28 import java.util.Base64;
29 import java.util.Date;
30 import java.util.List;
31 import java.util.UUID;
32 import org.junit.jupiter.api.BeforeEach;
33 import org.junit.jupiter.api.Test;
34
35 @QuarkusComponentTest
36 public class ApiKeyServiceTest extends BaseTestCase {
37
38 @InjectMock
39 ApiKeyDAO dao;
40
41 @InjectMock
42 UserService userService;
43
44 @InjectMock
45 AuthenticationContext authenticationContext;
46
47 @InjectMock
48 DateHelper dateHelper;
49
50 @InjectMock
51 PKIHelper pkiHelper;
52
53 @Inject
54 ApiKeyService service;
55
56 private PrivateKey key;
57
58 @BeforeEach
59 public void setUpKey() throws NoSuchAlgorithmException, InvalidKeySpecException, IllegalAccessException {
60 var privateKey =
61 "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCIDEXJ9+8zSiKBreHYTteke0m+7W9Oh2uf1jjboU6/zRglwzA+Rojm1djmGcuOA7CxU1IG/3ACEsvhtR8/5NWF2Dh2KMPYf/cVqaF5Bo+Z26KbK3NCOUcgh8W5mJ0fXZnJSs5Z8PGIeJEVDcN3x2VLsxsixa3+oEiDXpllrNMlOJpLI/+offTnH2JGOu0ZGa8TZUw51zkSG6MUwmdBZaDA6e/YL1T0ohyGQ8LP5MAviQonv0FSLhvT6PEvkJuDK3RsyjbtnHTNCNTt/TKcUiWWpnqd7DdDwdhuvgAiRxrikyN8patMeStAEvZwRccsge3zoLXuCgq15OioOOmGTAibAgMBAAECggEABBqirFIPZDOzUMgnDPhr5ulVMy5EclEBfSPgOTfngT+1n8YAmZBVJumCjoZuro0L8n159v4TqexZPCjTlYDYtB3urhnStqA9muiwF0+MW27Vu+qWooPJ0oBmBZBGBSE0t27LRMlQ7/X7InB02hMoyhzQD7943TqGlXfwFrIc+H1uXN8MrB4boRX71/yEPT8hv8nWB0FLcgfwtl1l+81otJFveMO/RLStHUH3Auomb/Hh4u96H6S6lUZ8TJ6+8jh2LXmg/RpsqHIWhDbZaNQJE1YdySe3bijov3s/PISaE8pRec6l6KaYkUuFUa6RoGP1RnopsFuN+EeLRMXTRtxgEQKBgQDDB1YRjE7YAYUqeuohhMgx9Ms39zsJGrs6KHE4uWtJFR/Jo3Kq093ykGA+IO+DK/IhBXGzy53SIQ9J7WEONpMmaahY6/Bkhn2nRI9biNaPCovHeO+nIpwtIdTUQLg/d+om+jC2My0YLGk71A5TRkIBPBE9NirbITxibo6jwWWOwwKBgQCylI1fx6f1gdEAP0qM7/LVLrZU3Qx+Q9rPcGG2FI1gWYu69o3JBGpSXqKcAc9hxtFVBaOGpaj9sB8+fPfMXWAvM7c808eL0zOmDC6RlQs0N4XmpV/vUeurgkLQfgB4sfUXbVWHQNsAkvB64BVbbmWFEcHzaBMytb2whvU9hcExSQKBgQCDuSjAoWt/KUev8WTBTtWIKDY5jpopBA0AsuAF1/ZGXiYiImsIRiDZ+/mE/OnIRp46/1pUfWoSypFw9Qtgdivc/e/eXzz2KIAlwYCx6jJAWnceOuhiklW5heghk7Td6TgVK1ZLOTVz5ksNRaSHSiS6gL+EAFnhtwj50oI0yCK30QKBgF7k028HADhUYEQaXbogs1AW/2p+/+mEkxxR4opHx4xgaQDTjSo5P2o/wXbW+2VAqfHdCjU9iFwuH5wr+d1N7ROIDqGzA8FIXJSquoA/y/FWY7/ZNu5MAMhlcq2plwSLw+pL/fveOcHHUyRoONEaC7Y3ZnG6ZyE2M/M+88hab/uJAoGARSSJgG3rRz8hcfQEfopo3rzdeAMY0ws+fXlHp6u51PP+238rB0Y+/b/NeHzwwuqeIxqVTcbd5E8Va7KESPuuzfIQtKbGuVwFpZzWHmROt312AoxeSwRDpOQibpfBAF59D40+SCl6N64whiVoEgJvOQGYB6BIcunIhSpLSD2YId4=";
62 var kFactory = KeyFactory.getInstance("RSA");
63 var decoded = Base64.getDecoder().decode(privateKey);
64 var spec = new PKCS8EncodedKeySpec(decoded);
65 key = kFactory.generatePrivate(spec);
66 authenticationContext.setPrincipal(new JWTPrincipal("bob", "key"));
67 }
68
69 @Test
70 public void getApiKeyTest() {
71 var uid = UUID.randomUUID();
72 var key = new ApiKey(uid);
73 var user = new User("bob");
74 key.setBelongsTo(user);
75 when(dao.find(uid)).thenReturn(key);
76 var actual = service.getApiKey("bob", uid);
77 assertEquals(key, actual);
78 }
79
80 @Test
81 public void getAllApiKeysTest() {
82 var uid = UUID.randomUUID();
83 var key = new ApiKey(uid);
84 var user = new User("bob");
85 user.setApiKeys(List.of(key));
86
87 when(userService.getUser("bob")).thenReturn(user);
88
89 var actual = service.getAllApiKeys("bob");
90 assertEquals(List.of(key), actual);
91 }
92
93 @Test
94 public void getAllApiKeysTest_noUser() {
95 when(userService.getUser("bob")).thenThrow(InvalidPathException.class);
96
97 assertThrows(InvalidPathException.class, () -> service.getAllApiKeys("bob"));
98 }
99
100 @Test
101 public void deleteApiKeyTest() {
102 var uid = UUID.randomUUID();
103 var key = new ApiKey(uid);
104 var user = new User("bob");
105 key.setBelongsTo(user);
106 when(dao.find(uid)).thenReturn(key);
107 when(dao.delete(uid)).thenReturn(true);
108 var actual = service.deleteApiKey("bob", uid);
109
110 assertTrue(actual);
111 }
112
113 @Test
114 public void createApiKeyTest() {
115 var uid = UUID.randomUUID();
116 var user = new User("bob");
117 var date = new Date(30L);
118 var jws = Jwts.builder()
119 .setSubject("bob")
120 .setIssuer("uri")
121 .setNotBefore(date)
122 .setIssuedAt(date)
123 .setId(uid.toString())
124 .signWith(key)
125 .compact();
126 var input = new ApiKeyIO();
127 input.setName("MyKey");
128 var toCreate = new ApiKey() {
129 {
130 setBelongsTo(user);
131 setCreatedAt(date);
132 setName("MyKey");
133 }
134 };
135 var created = new ApiKey() {
136 {
137 setUid(uid);
138 setBelongsTo(user);
139 setCreatedAt(date);
140 setName("MyKey");
141 }
142 };
143 var signed = new ApiKey() {
144 {
145 setUid(uid);
146 setBelongsTo(user);
147 setCreatedAt(date);
148 setName("MyKey");
149 setJws(jws);
150 }
151 };
152
153 when(dateHelper.getDate()).thenReturn(date);
154 when(userService.getUser("bob")).thenReturn(user);
155 when(dao.createOrUpdate(toCreate)).thenReturn(created);
156 when(dao.createOrUpdate(signed)).thenReturn(signed);
157 when(pkiHelper.getPrivateKey()).thenReturn(key);
158
159 var actual = service.createApiKey(input, "bob", "uri");
160 assertEquals(signed, actual);
161 }
162 }