1 package com.atlassian.asap.service.core.impl;
2
3 import com.atlassian.asap.api.Jwt;
4 import com.atlassian.asap.api.JwtClaims;
5 import com.atlassian.asap.api.exception.CannotRetrieveKeyException;
6 import com.atlassian.asap.core.exception.MissingRequiredClaimException;
7 import com.atlassian.asap.service.api.ValidationResult.Decision;
8 import org.junit.Rule;
9 import org.junit.Test;
10 import org.junit.rules.ExpectedException;
11 import org.mockito.junit.MockitoJUnit;
12 import org.mockito.junit.MockitoRule;
13
14 import java.util.Optional;
15
16 import static com.atlassian.asap.service.api.TokenValidator.Policy.REQUIRE;
17 import static java.util.Optional.empty;
18 import static org.junit.Assert.assertThat;
19 import static org.mockito.Mockito.verifyZeroInteractions;
20 import static org.mockito.Mockito.when;
21
22 public class TokenValidatorImplRequirePolicyTest extends AbstractTokenValidatorImplTest {
23 @Rule
24 public final MockitoRule mockitoRule = MockitoJUnit.rule();
25 @Rule
26 public final ExpectedException thrown = ExpectedException.none();
27
28 @Test
29 public void noTokenReturnsNotAuthenticated() {
30 tokenValidator.policy(REQUIRE);
31
32 assertThat(tokenValidator.validate(empty()), result(Decision.NOT_AUTHENTICATED));
33 }
34
35 @Test
36 public void wrongPrefixReturnsNotAuthenticated() throws Exception {
37 tokenValidator.policy(REQUIRE);
38
39 assertThat(tokenValidator.validate(Optional.of("Not a jwt")), result(Decision.NOT_AUTHENTICATED));
40
41 verifyZeroInteractions(jwtParser);
42 }
43
44 @Test
45 public void invalidTokenReturnsNotAuthenticated() throws Exception {
46 tokenValidator.policy(REQUIRE);
47 when(jwtValidator.readAndValidate(TOKEN)).thenThrow(new MissingRequiredClaimException(JwtClaims.RegisteredClaim.ISSUER));
48
49 assertThat(tokenValidator.validate(HEADER), result(Decision.NOT_AUTHENTICATED));
50 }
51
52 @Test
53 public void unresolvableKeyReturnsNotVerified() throws Exception {
54 tokenValidator.policy(REQUIRE);
55 when(jwtValidator.readAndValidate(TOKEN)).thenThrow(new CannotRetrieveKeyException("Ouch!"));
56
57 assertThat(tokenValidator.validate(HEADER), result(Decision.NOT_VERIFIED, ISSUER));
58 }
59
60 @Test
61 public void badIssuerReturnsNotAuthorized() throws Exception {
62 tokenValidator.policy(REQUIRE).issuer(AUDIENCE1);
63 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwtBuilder.build());
64
65 assertThat(tokenValidator.validate(HEADER), result(Decision.NOT_AUTHORIZED, ISSUER));
66 }
67
68 @Test
69 public void badEffectiveSubjectReturnsNotAuthorized() throws Exception {
70 tokenValidator.policy(REQUIRE).subject(AUDIENCE1);
71 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwtBuilder.build());
72
73 assertThat(tokenValidator.validate(HEADER), result(Decision.NOT_AUTHORIZED, ISSUER));
74 }
75
76 @Test
77 public void goodEffectiveSubjectReturnsAuthorized() throws Exception {
78 tokenValidator.policy(REQUIRE).subject(ISSUER);
79 final Jwt jwt = jwtBuilder.build();
80 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwt);
81
82 assertThat(tokenValidator.validate(HEADER), result(Decision.AUTHORIZED, jwt));
83 }
84
85 @Test
86
87 public void subjectImpersonationRequiresAnIssuerWhitelist() throws Exception {
88 tokenValidator.policy(REQUIRE)
89 .subject(ISSUER)
90 .subjectImpersonation(true);
91 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwtBuilder.build());
92
93 thrown.expect(IllegalStateException.class);
94 tokenValidator.validate(HEADER);
95 }
96
97 @Test
98
99 public void noEffectiveSubjectWhenImpersonationIsEnabled() throws Exception {
100 tokenValidator.policy(REQUIRE)
101 .issuer(ISSUER)
102 .subject(ISSUER)
103 .subjectImpersonation(true);
104 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwtBuilder.build());
105
106 assertThat(tokenValidator.validate(HEADER), result(Decision.NOT_AUTHORIZED, ISSUER));
107 }
108
109 @Test
110 public void goodSubjectReturnsAuthorized() throws Exception {
111 tokenValidator.policy(REQUIRE).subject(ISSUER);
112 final Jwt jwt = jwtBuilder.subject(Optional.of(ISSUER)).build();
113 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwt);
114
115 assertThat(tokenValidator.validate(HEADER), result(Decision.AUTHORIZED, jwt));
116 }
117
118 @Test
119
120 public void goodSubjectWithImpersonationReturnsAuthorized() throws Exception {
121 tokenValidator.policy(REQUIRE)
122 .issuer(ISSUER)
123 .subject(AUDIENCE1)
124 .subjectImpersonation(true);
125 final Jwt jwt = jwtBuilder.subject(Optional.of(AUDIENCE1)).build();
126 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwt);
127
128 assertThat(tokenValidator.validate(HEADER), result(Decision.AUTHORIZED, jwt));
129 }
130
131 @Test
132 public void validImpersonationReturnsAuthorized() throws Exception {
133 tokenValidator.policy(REQUIRE)
134 .issuer(ISSUER2)
135 .impersonationIssuer(ISSUER);
136 Jwt jwt = jwtBuilder.subject(Optional.of(AUDIENCE1)).build();
137 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwt);
138
139 assertThat(tokenValidator.validate(HEADER), result(Decision.AUTHORIZED, jwt));
140 }
141
142 @Test
143 public void validImpersonationReturnsAuthorizedIssuerIsEmpty() throws Exception {
144 tokenValidator.policy(REQUIRE)
145 .impersonationIssuer(ISSUER);
146 Jwt jwt = jwtBuilder.subject(Optional.of(AUDIENCE1)).build();
147 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwt);
148
149 assertThat(tokenValidator.validate(HEADER), result(Decision.AUTHORIZED, jwt));
150 }
151
152 @Test
153 public void bothIssuerAndImpersonationIssuerAreEmpty() throws Exception {
154 tokenValidator.policy(REQUIRE);
155 Jwt jwt = jwtBuilder.subject(Optional.of(AUDIENCE1)).build();
156 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwt);
157
158 assertThat(tokenValidator.validate(HEADER), result(Decision.AUTHORIZED, jwt));
159 }
160
161 @Test
162 public void impersonationReturnsAuthorized() throws Exception {
163 tokenValidator.policy(REQUIRE)
164 .issuer(ISSUER)
165 .impersonationIssuer(ISSUER2);
166 Jwt jwt = jwtBuilder.subject(Optional.of(AUDIENCE1)).build();
167 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwt);
168
169 assertThat(tokenValidator.validate(HEADER), result(Decision.AUTHORIZED, jwt));
170 }
171 }