/org.amdatu.security.account/test/org/amdatu/security/account/admin/AccountAdminImplTest.java

https://bitbucket.org/amdatu/amdatu-security · Java · 680 lines · 478 code · 182 blank · 20 comment · 5 complexity · 5aaf144975d7df84adf4826657f9a3f3 MD5 · raw file

  1. /*
  2. * Licensed under the Apache License, Version 2.0 (the "License");
  3. * you may not use this file except in compliance with the License.
  4. * You may obtain a copy of the License at
  5. *
  6. * http://www.apache.org/licenses/LICENSE-2.0
  7. *
  8. * Unless required by applicable law or agreed to in writing, software
  9. * distributed under the License is distributed on an "AS IS" BASIS,
  10. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. * See the License for the specific language governing permissions and
  12. * limitations under the License.
  13. */
  14. package org.amdatu.security.account.admin;
  15. import static org.amdatu.security.account.admin.AccountAdminConfig.KEY_ACCOUNT_REMOVAL_ALLOWED;
  16. import static org.amdatu.security.account.admin.AccountAdminConfig.KEY_ACCOUNT_VERIFICATION_NEEDED;
  17. import static org.junit.Assert.assertEquals;
  18. import static org.junit.Assert.assertFalse;
  19. import static org.junit.Assert.assertNotNull;
  20. import static org.junit.Assert.assertNull;
  21. import static org.junit.Assert.assertTrue;
  22. import static org.mockito.ArgumentMatchers.any;
  23. import static org.mockito.ArgumentMatchers.anyMap;
  24. import static org.mockito.ArgumentMatchers.anyString;
  25. import static org.mockito.Mockito.atLeast;
  26. import static org.mockito.Mockito.doThrow;
  27. import static org.mockito.Mockito.reset;
  28. import static org.mockito.Mockito.verify;
  29. import static org.mockito.Mockito.when;
  30. import java.util.Dictionary;
  31. import java.util.HashMap;
  32. import java.util.Hashtable;
  33. import java.util.Map;
  34. import java.util.Optional;
  35. import org.amdatu.security.account.Account;
  36. import org.amdatu.security.account.Account.State;
  37. import org.amdatu.security.account.AccountAdminBackend;
  38. import org.amdatu.security.account.AccountCredentialResetException;
  39. import org.amdatu.security.account.AccountException;
  40. import org.amdatu.security.account.AccountLockedException;
  41. import org.amdatu.security.account.AccountValidationException;
  42. import org.amdatu.security.account.AccountValidator;
  43. import org.amdatu.security.account.NoSuchAccountException;
  44. import org.amdatu.security.account.TestPasswordHasher;
  45. import org.amdatu.security.account.UnverifiedAccountException;
  46. import org.amdatu.security.password.hash.PasswordHasher;
  47. import org.amdatu.security.tokenprovider.InvalidTokenException;
  48. import org.amdatu.security.tokenprovider.InvalidTokenException.Reason;
  49. import org.amdatu.security.tokenprovider.TokenProvider;
  50. import org.junit.Before;
  51. import org.junit.Rule;
  52. import org.junit.Test;
  53. import org.junit.rules.ExpectedException;
  54. import org.junit.runner.RunWith;
  55. import org.mockito.InjectMocks;
  56. import org.mockito.Mock;
  57. import org.mockito.Spy;
  58. import org.mockito.junit.MockitoJUnitRunner;
  59. import org.osgi.service.event.EventAdmin;
  60. import org.osgi.service.log.LogService;
  61. /**
  62. * Test cases for {@link AccountAdminImpl}.
  63. */
  64. @RunWith(MockitoJUnitRunner.class)
  65. public class AccountAdminImplTest {
  66. private static final String SECRET_PLAIN = "secret";
  67. private static final String SECRET_SHA256 = "$5$K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols=";
  68. private static final String PASSWORD_PLAIN = "password";
  69. private static final String PASSWORD_SHA256 = "$5$XohImNooBHFR0OVvjcYpJ3NgPQ1qq73WKhHvch0VQtg=";
  70. private static final String EXISTING_ACCOUNT_ID = "existing_user@amdatu.org";
  71. private static final String NEW_ACCOUNT_ID = "new_user@amdatu.org";
  72. private static final String LOCKED_ACCOUNT_ID = "bad_user@amdatu.org";
  73. private static final String NON_EXISTING_ACCOUNT_ID = "does_not_exist@amdatu.org";
  74. private PasswordHasher m_pwdHasher = new TestPasswordHasher();
  75. @Spy
  76. private AccountAdminBackend m_backend = new MockAccountAdminBackend();
  77. @Mock
  78. private AccountValidator m_accountValidator;
  79. @Mock
  80. private EventAdmin m_eventAdmin;
  81. @Mock
  82. private LogService m_logService;
  83. @Mock
  84. private TokenProvider m_tokenProvider;
  85. @InjectMocks
  86. private AccountAdminImpl m_accountAdmin = new AccountAdminImpl(m_backend, m_pwdHasher);
  87. @Rule
  88. public final ExpectedException m_rule = ExpectedException.none();
  89. private static Dictionary<String, Object> asDictionary(String... entries) {
  90. Dictionary<String, Object> result = new Hashtable<>();
  91. for (int i = 0; i < entries.length; i += 2) {
  92. result.put(entries[i], entries[i + 1]);
  93. }
  94. return result;
  95. }
  96. private static Map<String, String> asMap(String... entries) {
  97. Map<String, String> result = new HashMap<>();
  98. for (int i = 0; i < entries.length; i += 2) {
  99. result.put(entries[i], entries[i + 1]);
  100. }
  101. return result;
  102. }
  103. private static Map<String, String> createCredentials(String email, String password) {
  104. return asMap("email", email, "password", password);
  105. }
  106. @Before
  107. @SuppressWarnings("unchecked")
  108. public void setUp() throws Exception {
  109. when(m_tokenProvider.generateToken(anyMap())).thenAnswer(mock -> {
  110. String sub = ((Map<String, String>) mock.getArguments()[0]).get("sub");
  111. return sub;
  112. });
  113. when(m_tokenProvider.verifyToken(anyString())).thenAnswer(mock -> {
  114. String token = mock.getArguments()[0].toString();
  115. if (EXISTING_ACCOUNT_ID.equals(token) || NEW_ACCOUNT_ID.equals(token) || LOCKED_ACCOUNT_ID.equals(token)) {
  116. return asMap("sub", token);
  117. }
  118. throw new InvalidTokenException(Reason.UNKNOWN, "invalid token!", null);
  119. });
  120. // Inject a couple of accounts with specific properties...
  121. Map<String, String> creds = createCredentials(EXISTING_ACCOUNT_ID, m_pwdHasher.hash(SECRET_PLAIN));
  122. m_backend.update(new Account(EXISTING_ACCOUNT_ID, creds, State.NORMAL, null, false /* locked */));
  123. creds = createCredentials(LOCKED_ACCOUNT_ID, m_pwdHasher.hash("bad"));
  124. m_backend.update(new Account(LOCKED_ACCOUNT_ID, creds, State.NORMAL, null, true /* locked */));
  125. when(m_backend.accountExists(EXISTING_ACCOUNT_ID)).thenReturn(Boolean.TRUE);
  126. m_accountAdmin.updated(null); // ensure we've got a default configuration...
  127. reset(m_backend); // make sure we've got a clear state...
  128. }
  129. @Test
  130. public void testAccountExists() throws Exception {
  131. assertTrue(m_accountAdmin.accountExists(EXISTING_ACCOUNT_ID));
  132. assertFalse(m_accountAdmin.accountExists(NON_EXISTING_ACCOUNT_ID));
  133. assertFalse(m_accountAdmin.accountExists(null));
  134. }
  135. @Test
  136. public void testCreateAccount() throws Exception {
  137. Account account = m_accountAdmin.createAccount(createCredentials(NEW_ACCOUNT_ID, SECRET_PLAIN));
  138. assertNotNull(account);
  139. assertEquals(NEW_ACCOUNT_ID, account.getId());
  140. assertEquals(NEW_ACCOUNT_ID, account.getCredentials().get("email"));
  141. assertEquals(SECRET_SHA256, account.getCredentials().get("password"));
  142. assertEquals(State.ACCOUNT_VERIFICATION_NEEDED, account.getState());
  143. assertEquals(Optional.of(NEW_ACCOUNT_ID), account.getAccessToken());
  144. }
  145. @Test
  146. public void testCreateAccount_AccountExists() throws Exception {
  147. m_rule.expect(AccountException.class);
  148. assertNull(m_accountAdmin.createAccount(createCredentials(EXISTING_ACCOUNT_ID, SECRET_PLAIN)));
  149. }
  150. @Test
  151. public void testCreateAccount_AccountValidationFails() throws Exception {
  152. doThrow(new AccountValidationException()).when(m_accountValidator).validate(any());
  153. m_rule.expect(AccountValidationException.class);
  154. assertNull(m_accountAdmin.createAccount(createCredentials(NEW_ACCOUNT_ID, PASSWORD_PLAIN)));
  155. }
  156. @Test
  157. public void testCreateAccount_EmptyCredentials() throws Exception {
  158. m_rule.expect(AccountException.class);
  159. assertNull(m_accountAdmin.createAccount(asMap()));
  160. }
  161. @Test
  162. public void testCreateAccount_MissingAccountId() throws Exception {
  163. m_rule.expect(AccountException.class);
  164. assertNull(m_accountAdmin.createAccount(asMap("password", "secret")));
  165. }
  166. @Test
  167. public void testCreateAccount_MissingPassword() throws Exception {
  168. m_rule.expect(AccountException.class);
  169. assertNull(m_accountAdmin.createAccount(asMap("email", EXISTING_ACCOUNT_ID)));
  170. }
  171. @Test
  172. public void testCreateAccount_NoVerificationNeeded() throws Exception {
  173. m_accountAdmin.updated(asDictionary(KEY_ACCOUNT_VERIFICATION_NEEDED, "false"));
  174. Account account = m_accountAdmin.createAccount(createCredentials(NEW_ACCOUNT_ID, PASSWORD_PLAIN));
  175. assertNotNull(account);
  176. assertEquals(NEW_ACCOUNT_ID, account.getId());
  177. assertEquals(NEW_ACCOUNT_ID, account.getCredentials().get("email"));
  178. assertEquals(PASSWORD_SHA256, account.getCredentials().get("password"));
  179. assertEquals(State.NORMAL, account.getState());
  180. assertEquals(Optional.of(NEW_ACCOUNT_ID), account.getAccessToken());
  181. }
  182. @Test
  183. public void testGetAccount() throws Exception {
  184. Optional<Account> account = m_accountAdmin.getAccount(createCredentials(EXISTING_ACCOUNT_ID, SECRET_PLAIN));
  185. assertNotNull(account);
  186. assertTrue(account.isPresent());
  187. }
  188. @Test
  189. public void testGetAccount_ForcedCredentialsReset() throws Exception {
  190. m_accountAdmin.resetCredentials(EXISTING_ACCOUNT_ID, true /* force */);
  191. m_rule.expect(AccountCredentialResetException.class);
  192. assertNull(m_accountAdmin.getAccount(createCredentials(EXISTING_ACCOUNT_ID, SECRET_PLAIN)));
  193. }
  194. @Test
  195. public void testGetAccount_IncorrectCredentials() throws Exception {
  196. Optional<Account> account;
  197. // Wrong password...
  198. account = m_accountAdmin.getAccount(createCredentials(EXISTING_ACCOUNT_ID, "incorrect"));
  199. assertNotNull(account);
  200. assertFalse(account.isPresent());
  201. // Wrong email address...
  202. account = m_accountAdmin.getAccount(createCredentials(NON_EXISTING_ACCOUNT_ID, SECRET_PLAIN));
  203. assertNotNull(account);
  204. assertFalse(account.isPresent());
  205. }
  206. @Test
  207. public void testGetAccount_LockedAccount() throws Exception {
  208. m_rule.expect(AccountLockedException.class);
  209. assertNull(m_accountAdmin.getAccount(createCredentials(LOCKED_ACCOUNT_ID, "bad")));
  210. }
  211. @Test
  212. public void testGetAccount_NonExistingAccount() throws Exception {
  213. Optional<Account> account = m_accountAdmin.getAccount(createCredentials(NON_EXISTING_ACCOUNT_ID, SECRET_PLAIN));
  214. assertNotNull(account);
  215. assertFalse(account.isPresent());
  216. }
  217. @Test
  218. public void testGetAccount_UnverifiedAccount() throws Exception {
  219. m_accountAdmin.createAccount(createCredentials(NEW_ACCOUNT_ID, SECRET_PLAIN));
  220. m_rule.expect(UnverifiedAccountException.class);
  221. assertNull(m_accountAdmin.getAccount(createCredentials(NEW_ACCOUNT_ID, SECRET_PLAIN)));
  222. }
  223. @Test
  224. public void testGetAccount_WithAccessToken() throws Exception {
  225. Account account = m_accountAdmin.createAccount(createCredentials(NEW_ACCOUNT_ID, PASSWORD_PLAIN));
  226. assertNotNull(account);
  227. String token = account.getAccessToken().get(); // cannot fail!
  228. account = m_accountAdmin.getAccountByAccessToken(token);
  229. assertNotNull(account);
  230. }
  231. @Test
  232. public void testGetAccount_WithAccessTokenForAccountWithoutToken() throws Exception {
  233. m_rule.expect(NoSuchAccountException.class);
  234. assertNull(m_accountAdmin.getAccountByAccessToken(EXISTING_ACCOUNT_ID));
  235. }
  236. @Test
  237. public void testGetAccount_WithAccessTokenForLockedAccount() throws Exception {
  238. m_rule.expect(AccountLockedException.class);
  239. assertNull(m_accountAdmin.getAccountByAccessToken(LOCKED_ACCOUNT_ID));
  240. }
  241. @Test
  242. public void testGetAccount_WithInvalidAccessToken() throws Exception {
  243. m_rule.expect(NoSuchAccountException.class);
  244. assertNull(m_accountAdmin.getAccountByAccessToken("someToken"));
  245. }
  246. @Test
  247. public void testGetAccount_WithPartialMissingCredentials() throws Exception {
  248. Map<String, String> creds;
  249. creds = asMap("email", EXISTING_ACCOUNT_ID, "foo", "bar");
  250. assertFalse(m_accountAdmin.getAccount(creds).isPresent());
  251. creds = asMap("password", "bar", "foo", "bar");
  252. assertFalse(m_accountAdmin.getAccount(creds).isPresent());
  253. creds = asMap("foo", "bar");
  254. assertFalse(m_accountAdmin.getAccount(creds).isPresent());
  255. creds = asMap();
  256. assertFalse(m_accountAdmin.getAccount(creds).isPresent());
  257. }
  258. @Test
  259. public void testGetAccount_WithSuperfluousCredentials() throws Exception {
  260. Map<String, String> creds = createCredentials(EXISTING_ACCOUNT_ID, SECRET_PLAIN);
  261. // Add some additional credentials that aren't present in the stored account...
  262. creds.put("type", "local");
  263. creds.put("other", "token");
  264. Optional<Account> account = m_accountAdmin.getAccount(creds);
  265. assertNotNull(account);
  266. assertTrue(account.isPresent());
  267. }
  268. @Test
  269. public void testRemoveAccount() throws Exception {
  270. m_accountAdmin.updated(asDictionary(KEY_ACCOUNT_REMOVAL_ALLOWED, "true"));
  271. Account account = m_accountAdmin.removeAccount(EXISTING_ACCOUNT_ID);
  272. assertNotNull(account);
  273. assertEquals(EXISTING_ACCOUNT_ID, account.getId());
  274. assertEquals(EXISTING_ACCOUNT_ID, account.getCredentials().get("email"));
  275. }
  276. @Test
  277. public void testRemoveAccount_NonExistingAccount() throws Exception {
  278. m_accountAdmin.updated(asDictionary(KEY_ACCOUNT_REMOVAL_ALLOWED, "true"));
  279. m_rule.expect(NoSuchAccountException.class);
  280. assertNull(m_accountAdmin.removeAccount(NON_EXISTING_ACCOUNT_ID));
  281. }
  282. @Test
  283. public void testRemoveAccount_NotAllowed() throws Exception {
  284. m_accountAdmin.updated(asDictionary(KEY_ACCOUNT_REMOVAL_ALLOWED, "false"));
  285. m_rule.expect(AccountException.class);
  286. assertNull(m_accountAdmin.removeAccount(EXISTING_ACCOUNT_ID));
  287. }
  288. @Test
  289. public void testRemoveAccount_NotAllowedByBackend() throws Exception {
  290. m_accountAdmin.updated(asDictionary(KEY_ACCOUNT_REMOVAL_ALLOWED, "true"));
  291. ((MockAccountAdminBackend) m_backend).setRemovalSupported(false);
  292. m_rule.expect(AccountException.class);
  293. assertNull(m_accountAdmin.removeAccount(EXISTING_ACCOUNT_ID));
  294. }
  295. @Test
  296. public void testResetCredentials_Forced() throws Exception {
  297. Account account = m_accountAdmin.getAccount(createCredentials(EXISTING_ACCOUNT_ID, SECRET_PLAIN)).get();
  298. account = m_accountAdmin.resetCredentials(EXISTING_ACCOUNT_ID, true /* forced */);
  299. assertEquals(EXISTING_ACCOUNT_ID, account.getAccessToken().get());
  300. assertEquals(State.FORCED_CREDENTIALS_RESET, account.getState());
  301. verify(m_backend).update(account);
  302. }
  303. @Test
  304. public void testResetCredentials_ForcedFlagNotCleared() throws Exception {
  305. Account account = m_accountAdmin.getAccount(createCredentials(EXISTING_ACCOUNT_ID, SECRET_PLAIN)).get();
  306. account = m_accountAdmin.resetCredentials(EXISTING_ACCOUNT_ID, true /* forced */);
  307. assertEquals(EXISTING_ACCOUNT_ID, account.getAccessToken().get());
  308. assertEquals(State.FORCED_CREDENTIALS_RESET, account.getState());
  309. m_rule.expect(AccountCredentialResetException.class);
  310. assertNull(m_accountAdmin.getAccount(createCredentials(EXISTING_ACCOUNT_ID, SECRET_PLAIN)));
  311. }
  312. @Test
  313. public void testResetCredentials_ForcedTwice() throws Exception {
  314. Account account = m_accountAdmin.getAccount(createCredentials(EXISTING_ACCOUNT_ID, SECRET_PLAIN)).get();
  315. account = m_accountAdmin.resetCredentials(EXISTING_ACCOUNT_ID, true /* forced */);
  316. assertTrue(account.getAccessToken().isPresent());
  317. account = m_accountAdmin.resetCredentials(EXISTING_ACCOUNT_ID, true /* forced */);
  318. assertEquals(State.FORCED_CREDENTIALS_RESET, account.getState());
  319. verify(m_backend, atLeast(2)).update(account);
  320. }
  321. @Test
  322. public void testResetCredentials_LockedAccount() throws Exception {
  323. m_rule.expect(AccountLockedException.class);
  324. assertNull(m_accountAdmin.resetCredentials(LOCKED_ACCOUNT_ID, false /* forced */));
  325. }
  326. @Test
  327. public void testResetCredentials_NonExistingAccount() throws Exception {
  328. m_rule.expect(NoSuchAccountException.class);
  329. assertNull(m_accountAdmin.resetCredentials(NON_EXISTING_ACCOUNT_ID, false /* forced */));
  330. }
  331. @Test
  332. public void testResetCredentials_RequestForcedResetAfterVoluntaryReset() throws Exception {
  333. Account account = m_accountAdmin.getAccount(createCredentials(EXISTING_ACCOUNT_ID, SECRET_PLAIN)).get();
  334. account = m_accountAdmin.resetCredentials(EXISTING_ACCOUNT_ID, false /* forced */);
  335. assertTrue(account.getAccessToken().isPresent());
  336. assertEquals(State.VOLUNTARY_CREDENTIALS_RESET, account.getState());
  337. account = m_accountAdmin.resetCredentials(EXISTING_ACCOUNT_ID, true /* forced */);
  338. assertEquals(State.FORCED_CREDENTIALS_RESET, account.getState());
  339. verify(m_backend, atLeast(2)).update(account);
  340. }
  341. @Test
  342. public void testResetCredentials_RequestVoluntaryResetAfterForcedReset() throws Exception {
  343. Account account = m_accountAdmin.getAccount(createCredentials(EXISTING_ACCOUNT_ID, SECRET_PLAIN)).get();
  344. account = m_accountAdmin.resetCredentials(EXISTING_ACCOUNT_ID, true /* forced */);
  345. assertTrue(account.getAccessToken().isPresent());
  346. assertEquals(State.FORCED_CREDENTIALS_RESET, account.getState());
  347. account = m_accountAdmin.resetCredentials(EXISTING_ACCOUNT_ID, false /* forced */);
  348. assertEquals(State.FORCED_CREDENTIALS_RESET, account.getState());
  349. verify(m_backend, atLeast(2)).update(account);
  350. }
  351. @Test
  352. public void testResetCredentials_Twice() throws Exception {
  353. Account account = m_accountAdmin.getAccount(createCredentials(EXISTING_ACCOUNT_ID, SECRET_PLAIN)).get();
  354. account = m_accountAdmin.resetCredentials(EXISTING_ACCOUNT_ID, false /* forced */);
  355. assertTrue(account.getAccessToken().isPresent());
  356. assertEquals(State.VOLUNTARY_CREDENTIALS_RESET, account.getState());
  357. account = m_accountAdmin.resetCredentials(EXISTING_ACCOUNT_ID, false /* forced */);
  358. assertEquals(State.VOLUNTARY_CREDENTIALS_RESET, account.getState());
  359. verify(m_backend, atLeast(2)).update(account);
  360. }
  361. @Test
  362. public void testResetCredentials_UnverifiedAccount() throws Exception {
  363. Account account = m_accountAdmin.createAccount(createCredentials(NEW_ACCOUNT_ID, SECRET_PLAIN));
  364. assertNotNull(account);
  365. m_rule.expect(AccountCredentialResetException.class);
  366. assertNull(m_accountAdmin.resetCredentials(NEW_ACCOUNT_ID, true /* forced */));
  367. }
  368. @Test
  369. public void testResetCredentials_Voluntary() throws Exception {
  370. Account account = m_accountAdmin.getAccount(createCredentials(EXISTING_ACCOUNT_ID, SECRET_PLAIN)).get();
  371. assertFalse(account.getAccessToken().isPresent());
  372. account = m_accountAdmin.resetCredentials(EXISTING_ACCOUNT_ID, false /* forced */);
  373. assertTrue(account.getAccessToken().isPresent());
  374. assertEquals(State.VOLUNTARY_CREDENTIALS_RESET, account.getState());
  375. verify(m_backend).update(account);
  376. }
  377. @Test
  378. public void testResetCredentials_VoluntaryFlagClearedAfterSuccessfulGet() throws Exception {
  379. Account account = m_accountAdmin.getAccount(createCredentials(EXISTING_ACCOUNT_ID, SECRET_PLAIN)).get();
  380. account = m_accountAdmin.resetCredentials(EXISTING_ACCOUNT_ID, false /* forced */);
  381. assertEquals(State.VOLUNTARY_CREDENTIALS_RESET, account.getState());
  382. account = m_accountAdmin.getAccount(createCredentials(EXISTING_ACCOUNT_ID, SECRET_PLAIN)).get();
  383. verify(m_backend, atLeast(2)).update(account);
  384. assertEquals(State.NORMAL, account.getState());
  385. }
  386. @Test
  387. public void testUpdateAccount_AccountValidationFails() throws Exception {
  388. Map<String, String> creds = createCredentials(EXISTING_ACCOUNT_ID, "secret");
  389. doThrow(new AccountValidationException()).when(m_accountValidator).validate(any());
  390. m_rule.expect(AccountValidationException.class);
  391. assertNull(m_accountAdmin.updateAccount(creds, creds));
  392. }
  393. @Test
  394. public void testUpdateAccount_LockedAccount() throws Exception {
  395. Map<String, String> creds = createCredentials(LOCKED_ACCOUNT_ID, "bad");
  396. m_rule.expect(AccountLockedException.class);
  397. assertNull(m_accountAdmin.updateAccount(creds, creds));
  398. }
  399. @Test
  400. public void testUpdateAccount_NonExistingAccount() throws Exception {
  401. m_rule.expect(NoSuchAccountException.class);
  402. Map<String, String> creds = createCredentials(NON_EXISTING_ACCOUNT_ID, "bad");
  403. assertNull(m_accountAdmin.updateAccount(creds, creds));
  404. }
  405. @Test
  406. public void testUpdateAccount_NoResetTokenRequested() throws Exception {
  407. m_rule.expect(NoSuchAccountException.class);
  408. assertNull(m_accountAdmin.updateAccount(createCredentials(EXISTING_ACCOUNT_ID, "password"), EXISTING_ACCOUNT_ID));
  409. }
  410. @Test
  411. public void testUpdateAccount_WithInvalidResetToken() throws Exception {
  412. Account account = m_accountAdmin.resetCredentials(EXISTING_ACCOUNT_ID, false /* forced */);
  413. assertTrue(account.getAccessToken().isPresent());
  414. m_rule.expect(NoSuchAccountException.class);
  415. assertNull(m_accountAdmin.updateAccount(createCredentials(EXISTING_ACCOUNT_ID, "password"), "invalidToken"));
  416. }
  417. @Test
  418. public void testUpdateAccount_WithoutResetToken() throws Exception {
  419. Map<String, String> oldCreds = createCredentials(EXISTING_ACCOUNT_ID, SECRET_PLAIN);
  420. Map<String, String> newCreds = createCredentials(EXISTING_ACCOUNT_ID, PASSWORD_PLAIN);
  421. Account account = m_accountAdmin.updateAccount(oldCreds, newCreds);
  422. assertNotNull(account);
  423. assertEquals(EXISTING_ACCOUNT_ID, account.getId());
  424. assertEquals(EXISTING_ACCOUNT_ID, account.getCredentials().get("email"));
  425. assertEquals(PASSWORD_SHA256, account.getCredentials().get("password"));
  426. assertEquals(State.NORMAL, account.getState());
  427. assertEquals(Optional.empty(), account.getAccessToken());
  428. }
  429. @Test
  430. public void testUpdateAccount_WithoutResetToken_ForcedUpdate() throws Exception {
  431. Account account = m_accountAdmin.resetCredentials(EXISTING_ACCOUNT_ID, true /* forced */);
  432. assertTrue(account.getAccessToken().isPresent());
  433. Map<String, String> oldCreds = createCredentials(EXISTING_ACCOUNT_ID, SECRET_PLAIN);
  434. Map<String, String> newCreds = createCredentials(EXISTING_ACCOUNT_ID, "password");
  435. m_rule.expect(AccountCredentialResetException.class);
  436. assertNotNull(m_accountAdmin.updateAccount(oldCreds, newCreds));
  437. }
  438. @Test
  439. public void testUpdateAccount_WithoutResetToken_InvalidOldCredentials() throws Exception {
  440. Map<String, String> oldCreds = createCredentials(EXISTING_ACCOUNT_ID, "incorrect");
  441. Map<String, String> newCreds = createCredentials(EXISTING_ACCOUNT_ID, "password");
  442. m_rule.expect(NoSuchAccountException.class);
  443. assertNull(m_accountAdmin.updateAccount(oldCreds, newCreds));
  444. }
  445. @Test
  446. public void testUpdateAccount_WithResetToken() throws Exception {
  447. Account account = m_accountAdmin.resetCredentials(EXISTING_ACCOUNT_ID, false /* forced */);
  448. assertTrue(account.getAccessToken().isPresent());
  449. account = m_accountAdmin.updateAccount(createCredentials(EXISTING_ACCOUNT_ID, PASSWORD_PLAIN), EXISTING_ACCOUNT_ID);
  450. assertEquals(EXISTING_ACCOUNT_ID, account.getId());
  451. assertEquals(EXISTING_ACCOUNT_ID, account.getCredentials().get("email"));
  452. assertEquals(PASSWORD_SHA256, account.getCredentials().get("password"));
  453. assertEquals(State.NORMAL, account.getState());
  454. assertEquals(Optional.empty(), account.getAccessToken());
  455. }
  456. @Test
  457. public void testUpdateAccount_WithResetToken_AccountValidationFails() throws Exception {
  458. Account account = m_accountAdmin.resetCredentials(EXISTING_ACCOUNT_ID, false /* forced */);
  459. assertTrue(account.getAccessToken().isPresent());
  460. doThrow(new AccountValidationException()).when(m_accountValidator).validate(any());
  461. m_rule.expect(AccountValidationException.class);
  462. assertNull(m_accountAdmin.updateAccount(createCredentials(EXISTING_ACCOUNT_ID, "password"), EXISTING_ACCOUNT_ID));
  463. }
  464. @Test
  465. public void testUpdateAccount_WithResetToken_LockedAccount() throws Exception {
  466. m_rule.expect(AccountLockedException.class);
  467. assertNull(m_accountAdmin.updateAccount(createCredentials(LOCKED_ACCOUNT_ID, "password"), LOCKED_ACCOUNT_ID));
  468. }
  469. @Test
  470. public void testVerifyAccount() throws Exception {
  471. Account account = m_accountAdmin.createAccount(createCredentials(NEW_ACCOUNT_ID, SECRET_PLAIN));
  472. assertNotNull(account);
  473. account = m_accountAdmin.verifyAccount(NEW_ACCOUNT_ID, NEW_ACCOUNT_ID);
  474. assertNotNull(account);
  475. assertEquals(NEW_ACCOUNT_ID, account.getId());
  476. assertEquals(NEW_ACCOUNT_ID, account.getCredentials().get("email"));
  477. assertEquals(SECRET_SHA256, account.getCredentials().get("password"));
  478. assertEquals(State.NORMAL, account.getState());
  479. assertEquals(Optional.empty(), account.getAccessToken());
  480. }
  481. @Test
  482. public void testVerifyAccount_WithInvalidVerificationToken() throws Exception {
  483. Account account = m_accountAdmin.createAccount(createCredentials(NEW_ACCOUNT_ID, SECRET_PLAIN));
  484. assertNotNull(account);
  485. m_rule.expect(AccountException.class);
  486. assertNull(m_accountAdmin.verifyAccount(NEW_ACCOUNT_ID, "invalidToken"));
  487. }
  488. @Test
  489. public void testVerifyAccount_WithInvalidVerificationToken2() throws Exception {
  490. m_rule.expect(AccountException.class);
  491. assertNull(m_accountAdmin.verifyAccount(EXISTING_ACCOUNT_ID, EXISTING_ACCOUNT_ID));
  492. }
  493. @Test
  494. public void testVerifyAccount_WithResetToken_LockedAccount() throws Exception {
  495. m_rule.expect(AccountLockedException.class);
  496. assertNull(m_accountAdmin.verifyAccount(LOCKED_ACCOUNT_ID, LOCKED_ACCOUNT_ID));
  497. }
  498. }