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