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 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 this.options.put("debug", "true");
154 final Set<Principal> principals = new LinkedHashSet<>();
155 principals.add(new UserPrincipal("FQN"));
156 principals.add(new RolePrincipal("WindowsGroup"));
157 Whitebox.setInternalState(this.loginModule, principals);
158 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
159 Assertions.assertTrue(this.loginModule.commit());
160 }
161
162
163
164
165 @BeforeEach
166 void init() {
167 this.loginModule = new WindowsLoginModule();
168 this.subject = new Subject();
169 this.options = new HashMap<>();
170 }
171
172
173
174
175 @Test
176 void initialize_withOptions() {
177 this.options.put("debug", "true");
178 this.options.put("principalFormat", "sid");
179 this.options.put("roleFormat", "none");
180 this.options.put("junk", "junk");
181 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
182 Assertions.assertTrue(this.loginModule.isDebug());
183 Assertions.assertEquals(PrincipalFormat.SID, Whitebox.getInternalState(this.loginModule, "principalFormat"));
184 Assertions.assertEquals(PrincipalFormat.NONE, Whitebox.getInternalState(this.loginModule, "roleFormat"));
185 }
186
187
188
189
190
191
192
193 @Test
194 void login_invalidGuestLogin() throws LoginException {
195 this.callbackHandler = new UsernamePasswordCallbackHandler("Guest", "password");
196 this.options.put("debug", "true");
197 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
198 Assertions.assertTrue(this.loginModule.isAllowGuestLogin());
199 Assertions.assertThrows(LoginException.class, () -> {
200 this.loginModule.login();
201 });
202 }
203
204
205
206
207
208
209
210 @Test
211 void login_nullPassword() throws LoginException {
212 this.callbackHandler = new UsernamePasswordCallbackHandler("Guest", null);
213 this.options.put("debug", "true");
214 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
215 Assertions.assertTrue(this.loginModule.isAllowGuestLogin());
216 Assertions.assertThrows(LoginException.class, () -> {
217 this.loginModule.login();
218 });
219 }
220
221
222
223
224
225
226
227
228
229
230
231 @Test
232 void login_throwIOException() throws LoginException, IOException, UnsupportedCallbackException {
233 this.options.put("debug", "true");
234 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
235 Assertions.assertTrue(this.loginModule.isAllowGuestLogin());
236 Assertions.assertNotNull(new Expectations() {
237 {
238 WindowsLoginModuleTest.this.callbackHandler.handle(this.withInstanceOf(Callback[].class));
239 this.result = new IOException();
240 }
241 });
242 Assertions.assertThrows(LoginException.class, () -> {
243 this.loginModule.login();
244 });
245 }
246
247
248
249
250
251
252
253
254
255
256
257 @Test
258 void login_throwUnsupportedCallbackException() throws LoginException, IOException, UnsupportedCallbackException {
259 this.options.put("debug", "true");
260 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
261 Assertions.assertTrue(this.loginModule.isAllowGuestLogin());
262 Assertions.assertNotNull(new Expectations() {
263 {
264 WindowsLoginModuleTest.this.callbackHandler.handle(this.withInstanceOf(Callback[].class));
265 this.result = new UnsupportedCallbackException(new NameCallback("Callback Exception"));
266 }
267 });
268 Assertions.assertThrows(LoginException.class, () -> {
269 this.loginModule.login();
270 });
271 }
272
273
274
275
276
277
278
279 @Test
280 void logon_noCallbackHandler() throws LoginException {
281 Assertions.assertThrows(LoginException.class, () -> {
282 this.loginModule.login();
283 });
284 }
285
286
287
288
289
290
291
292 @Test
293 void logout_abortNoUser() throws LoginException {
294 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
295 Assertions.assertTrue(this.loginModule.abort());
296 }
297
298
299
300
301
302
303
304 @Test
305 void logout_noUser() throws LoginException {
306 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
307 Assertions.assertTrue(this.loginModule.logout());
308 }
309
310
311
312
313
314
315
316 @Test
317 void logout_subjectReadOnly() throws LoginException {
318 this.subject.setReadOnly();
319 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
320 Assertions.assertThrows(LoginException.class, () -> {
321 this.loginModule.logout();
322 });
323 }
324
325
326
327
328
329
330
331 @Test
332 void logout_validUser() throws LoginException {
333 Whitebox.setInternalState(this.loginModule, "username", "waffle-user");
334 this.loginModule.initialize(this.subject, this.callbackHandler, null, this.options);
335 Assertions.assertTrue(this.loginModule.logout());
336 }
337
338 }