1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package waffle.jaas;
25
26 import java.io.IOException;
27 import java.security.Principal;
28 import java.util.HashMap;
29 import java.util.LinkedHashSet;
30 import java.util.Map;
31 import java.util.Set;
32
33 import javax.security.auth.Subject;
34 import javax.security.auth.callback.Callback;
35 import javax.security.auth.callback.CallbackHandler;
36 import javax.security.auth.callback.NameCallback;
37 import javax.security.auth.callback.UnsupportedCallbackException;
38 import javax.security.auth.login.LoginException;
39
40 import mockit.Expectations;
41 import mockit.Mocked;
42
43 import org.junit.jupiter.api.Assertions;
44 import org.junit.jupiter.api.BeforeEach;
45 import org.junit.jupiter.api.Test;
46 import org.powermock.reflect.Whitebox;
47
48 import waffle.windows.auth.PrincipalFormat;
49
50
51
52
53 class WindowsLoginModuleTest {
54
55
56 private WindowsLoginModule loginModule;
57
58
59 private Subject subject;
60
61
62 @Mocked
63 private CallbackHandler callbackHandler;
64
65
66 private Map<String, String> options;
67
68
69
70
71 @Test
72 void checkAuth() {
73 Assertions.assertNotNull(this.loginModule.getAuth());
74 this.loginModule.setAuth(null);
75 Assertions.assertNull(this.loginModule.getAuth());
76 }
77
78
79
80
81 @Test
82 void checkGuestLogin() {
83 Assertions.assertTrue(this.loginModule.isAllowGuestLogin());
84 this.loginModule.setAllowGuestLogin(false);
85 Assertions.assertFalse(this.loginModule.isAllowGuestLogin());
86 }
87
88
89
90
91
92
93
94 @Test
95 void commit_noPrincipal() throws LoginException {
96 Assertions.assertFalse(this.loginModule.commit());
97 }
98
99
100
101
102
103
104
105 @Test
106 void commit_subjectReadOnly() throws LoginException {
107 this.subject.setReadOnly();
108 Whitebox.setInternalState(this.loginModule, new LinkedHashSet<Principal>());
109 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
110 Assertions.assertThrows(LoginException.class, () -> {
111 this.loginModule.commit();
112 });
113 }
114
115
116
117
118
119
120
121 @Test
122 void commit_success() throws LoginException {
123 Whitebox.setInternalState(this.loginModule, new LinkedHashSet<Principal>());
124 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
125 Assertions.assertTrue(this.loginModule.commit());
126 }
127
128
129
130
131
132
133
134 @Test
135 void commit_withDebug() throws LoginException {
136 this.options.put("debug", "true");
137 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
138 final Set<Principal> principals = new LinkedHashSet<>();
139 principals.add(new UserPrincipal("FQN"));
140 Whitebox.setInternalState(this.loginModule, principals);
141 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
142 Assertions.assertTrue(this.loginModule.commit());
143 }
144
145
146
147
148
149
150
151 @Test
152 void commit_withRoles() throws LoginException {
153 final Set<Principal> principals = new LinkedHashSet<>();
154 principals.add(new UserPrincipal("FQN"));
155 final GroupPrincipal group = new GroupPrincipal("Roles");
156 final RolePrincipal role = new RolePrincipal("WindowsGroup");
157 group.addMember(role);
158 principals.add(role);
159 principals.add(group);
160 Whitebox.setInternalState(this.loginModule, principals);
161 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
162 Assertions.assertTrue(this.loginModule.commit());
163 }
164
165
166
167
168 @BeforeEach
169 void init() {
170 this.loginModule = new WindowsLoginModule();
171 this.subject = new Subject();
172 this.options = new HashMap<>();
173 }
174
175
176
177
178 @Test
179 void initialize_withOptions() {
180 this.options.put("debug", "true");
181 this.options.put("principalFormat", "sid");
182 this.options.put("roleFormat", "none");
183 this.options.put("junk", "junk");
184 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
185 Assertions.assertTrue(this.loginModule.isDebug());
186 Assertions.assertEquals(PrincipalFormat.SID, Whitebox.getInternalState(this.loginModule, "principalFormat"));
187 Assertions.assertEquals(PrincipalFormat.NONE, Whitebox.getInternalState(this.loginModule, "roleFormat"));
188 }
189
190
191
192
193
194
195
196 @Test
197 void login_invalidGuestLogin() throws LoginException {
198 this.callbackHandler = new UsernamePasswordCallbackHandler("Guest", "password");
199 this.options.put("debug", "true");
200 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
201 Assertions.assertTrue(this.loginModule.isAllowGuestLogin());
202 Assertions.assertThrows(LoginException.class, () -> {
203 this.loginModule.login();
204 });
205 }
206
207
208
209
210
211
212
213 @Test
214 void login_nullPassword() throws LoginException {
215 this.callbackHandler = new UsernamePasswordCallbackHandler("Guest", null);
216 this.options.put("debug", "true");
217 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
218 Assertions.assertTrue(this.loginModule.isAllowGuestLogin());
219 Assertions.assertThrows(LoginException.class, () -> {
220 this.loginModule.login();
221 });
222 }
223
224
225
226
227
228
229
230
231
232
233
234 @Test
235 void login_throwIOException() throws LoginException, IOException, UnsupportedCallbackException {
236 this.options.put("debug", "true");
237 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
238 Assertions.assertTrue(this.loginModule.isAllowGuestLogin());
239 Assertions.assertNotNull(new Expectations() {
240 {
241 WindowsLoginModuleTest.this.callbackHandler.handle(this.withInstanceOf(Callback[].class));
242 this.result = new IOException();
243 }
244 });
245 Assertions.assertThrows(LoginException.class, () -> {
246 this.loginModule.login();
247 });
248 }
249
250
251
252
253
254
255
256
257
258
259
260 @Test
261 void login_throwUnsupportedCallbackException() throws LoginException, IOException, UnsupportedCallbackException {
262 this.options.put("debug", "true");
263 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
264 Assertions.assertTrue(this.loginModule.isAllowGuestLogin());
265 Assertions.assertNotNull(new Expectations() {
266 {
267 WindowsLoginModuleTest.this.callbackHandler.handle(this.withInstanceOf(Callback[].class));
268 this.result = new UnsupportedCallbackException(new NameCallback("Callback Exception"));
269 }
270 });
271 Assertions.assertThrows(LoginException.class, () -> {
272 this.loginModule.login();
273 });
274 }
275
276
277
278
279
280
281
282 @Test
283 void logon_noCallbackHandler() throws LoginException {
284 Assertions.assertThrows(LoginException.class, () -> {
285 this.loginModule.login();
286 });
287 }
288
289
290
291
292
293
294
295 @Test
296 void logout_abortNoUser() throws LoginException {
297 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
298 Assertions.assertTrue(this.loginModule.abort());
299 }
300
301
302
303
304
305
306
307 @Test
308 void logout_noUser() throws LoginException {
309 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
310 Assertions.assertTrue(this.loginModule.logout());
311 }
312
313
314
315
316
317
318
319 @Test
320 void logout_subjectReadOnly() throws LoginException {
321 this.subject.setReadOnly();
322 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
323 Assertions.assertThrows(LoginException.class, () -> {
324 this.loginModule.logout();
325 });
326 }
327
328
329
330
331
332
333
334 @Test
335 void logout_validUser() throws LoginException {
336 Whitebox.setInternalState(this.loginModule, "username", "waffle-user");
337 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
338 Assertions.assertTrue(this.loginModule.logout());
339 }
340
341 }