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.OPTIONAL;
17 import static com.atlassian.asap.service.api.ValidationResult.Decision.NOT_AUTHENTICATED;
18 import static com.atlassian.asap.service.api.ValidationResult.Decision.NOT_AUTHORIZED;
19 import static com.atlassian.asap.service.api.ValidationResult.Decision.NOT_VERIFIED;
20 import static java.util.Optional.empty;
21 import static org.junit.Assert.assertThat;
22 import static org.mockito.Mockito.when;
23
24 public class TokenValidatorImplOptionalPolicyTest extends AbstractTokenValidatorImplTest {
25 @Rule
26 public final MockitoRule mockitoRule = MockitoJUnit.rule();
27 @Rule
28 public final ExpectedException thrown = ExpectedException.none();
29
30 @Test
31 public void noTokenReturnsAbstain() {
32 tokenValidator.policy(OPTIONAL);
33
34 assertThat(tokenValidator.validate(empty()), result(Decision.ABSTAIN));
35 }
36
37 @Test
38 public void invalidTokenReturnsNotAuthenticated() throws Exception {
39 tokenValidator.policy(OPTIONAL);
40 when(jwtValidator.readAndValidate(TOKEN)).thenThrow(new MissingRequiredClaimException(JwtClaims.RegisteredClaim.ISSUER));
41
42 assertThat(tokenValidator.validate(HEADER), result(NOT_AUTHENTICATED));
43 }
44
45 @Test
46 public void unresolvableKeyReturnsNotVerified() throws Exception {
47 tokenValidator.policy(OPTIONAL);
48 when(jwtValidator.readAndValidate(TOKEN)).thenThrow(new CannotRetrieveKeyException("Ouch!"));
49
50 assertThat(tokenValidator.validate(HEADER), result(NOT_VERIFIED, ISSUER));
51 }
52
53 @Test
54 public void badIssuerReturnsNotAuthorized() throws Exception {
55 tokenValidator.policy(OPTIONAL).issuer(AUDIENCE1);
56 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwtBuilder.build());
57
58 assertThat(tokenValidator.validate(HEADER), result(NOT_AUTHORIZED, ISSUER));
59 }
60
61 @Test
62 public void badEffectiveSubjectReturnsNotAuthorized() throws Exception {
63 tokenValidator.policy(OPTIONAL).subject(AUDIENCE1);
64 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwtBuilder.build());
65
66 assertThat(tokenValidator.validate(HEADER), result(Decision.NOT_AUTHORIZED, ISSUER));
67 }
68
69 @Test
70 public void goodEffectiveSubjectReturnsAuthorized() throws Exception {
71 tokenValidator.policy(OPTIONAL).subject(ISSUER);
72 final Jwt jwt = jwtBuilder.build();
73 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwt);
74
75 assertThat(tokenValidator.validate(HEADER), result(Decision.AUTHORIZED, jwt));
76 }
77
78 @Test
79
80 public void subjectImpersonationRequiresAnIssuerWhitelist() throws Exception {
81 tokenValidator.policy(OPTIONAL).subjectImpersonation(true);
82 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwtBuilder.build());
83
84 thrown.expect(IllegalStateException.class);
85 tokenValidator.validate(HEADER);
86 }
87
88 @Test
89
90 public void noEffectiveSubjectWhenImpersonationIsEnabled() throws Exception {
91 tokenValidator.policy(OPTIONAL)
92 .issuer(ISSUER)
93 .subject(ISSUER)
94 .subjectImpersonation(true);
95 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwtBuilder.build());
96
97 assertThat(tokenValidator.validate(HEADER), result(Decision.NOT_AUTHORIZED, ISSUER));
98 }
99
100 @Test
101 public void goodSubjectReturnsAuthorized() throws Exception {
102 tokenValidator.policy(OPTIONAL).subject(ISSUER);
103 final Jwt jwt = jwtBuilder.subject(Optional.of(ISSUER)).build();
104 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwt);
105
106 assertThat(tokenValidator.validate(HEADER), result(Decision.AUTHORIZED, jwt));
107 }
108
109 @Test
110
111 public void goodSubjectWithImpersonationReturnsAuthorized() throws Exception {
112 tokenValidator.policy(OPTIONAL)
113 .issuer(ISSUER)
114 .subject(AUDIENCE1)
115 .subjectImpersonation(true);
116 final Jwt jwt = jwtBuilder.subject(Optional.of(AUDIENCE1)).build();
117 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwt);
118
119 assertThat(tokenValidator.validate(HEADER), result(Decision.AUTHORIZED, jwt));
120 }
121
122 @Test
123 public void validImpersonationReturnsAuthorized() throws Exception {
124 tokenValidator.policy(OPTIONAL)
125 .issuer(ISSUER2)
126 .impersonationIssuer(ISSUER);
127 Jwt jwt = jwtBuilder.subject(Optional.of(AUDIENCE1)).build();
128 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwt);
129
130 assertThat(tokenValidator.validate(HEADER), result(Decision.AUTHORIZED, jwt));
131 }
132
133 @Test
134 public void validImpersonationReturnsAuthorizedIssuerIsEmpty() throws Exception {
135 tokenValidator.policy(OPTIONAL)
136 .impersonationIssuer(ISSUER);
137 Jwt jwt = jwtBuilder.subject(Optional.of(AUDIENCE1)).build();
138 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwt);
139
140 assertThat(tokenValidator.validate(HEADER), result(Decision.AUTHORIZED, jwt));
141 }
142
143 @Test
144 public void bothIssuerAndImpersonationIssuerAreEmpty() throws Exception {
145 tokenValidator.policy(OPTIONAL);
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 invalidImpersonationReturnsUnauthorized() throws Exception {
154 tokenValidator.policy(OPTIONAL)
155 .issuer(ISSUER)
156 .impersonationIssuer(ISSUER2);
157 Jwt jwt = jwtBuilder.subject(Optional.of(AUDIENCE1)).build();
158 when(jwtValidator.readAndValidate(TOKEN)).thenReturn(jwt);
159
160 assertThat(tokenValidator.validate(HEADER), result(Decision.AUTHORIZED, jwt));
161 }
162 }