/* * Copyright (C) 2007-2014 Crafter Software Corporation. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.craftercms.profile.services; import com.icegreen.greenmail.util.GreenMail; import com.icegreen.greenmail.util.GreenMailUtil; import com.icegreen.greenmail.util.ServerSetupTest; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.bson.types.ObjectId; import org.craftercms.commons.collections.SetUtils; import org.craftercms.profile.api.Profile; import org.craftercms.profile.api.SortOrder; import org.craftercms.profile.api.Ticket; import org.craftercms.profile.api.VerificationToken; import org.craftercms.profile.api.exceptions.ErrorCode; import org.craftercms.profile.api.services.AuthenticationService; import org.craftercms.profile.api.services.ProfileService; import org.craftercms.profile.api.services.TenantService; import org.craftercms.profile.exceptions.ProfileRestServiceException; import org.craftercms.profile.services.impl.SingleAccessTokenIdResolver; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import static org.craftercms.profile.api.ProfileConstants.BASE_URL_PROFILE; import static org.craftercms.profile.api.ProfileConstants.NO_ATTRIBUTE; import static org.craftercms.profile.api.ProfileConstants.URL_PROFILE_CHANGE_PASSWORD; import static org.craftercms.profile.api.ProfileConstants.URL_PROFILE_VERIFY; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** * Integration tests for {@link org.craftercms.profile.api.services.ProfileService}. * * @author avasquez */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:crafter/profile/extension/client-context.xml") public class ProfileServiceIT { private static final String VERIFICATION_EMAIL_REGEX = ".+<a id=\"verificationLink\" href=\".+\\?tokenId=(.+)\">.+"; private static final String ADMIN_CONSOLE_ACCESS_TOKEN_ID = "e8f5170c-877b-416f-b70f-4b09772f8e2d"; private static final String RANDOM_APP_ACCESS_TOKEN_ID = "f91cdaf0-e5c6-11e3-ac10-0800200c9a66"; private static final String DEFAULT_TENANT = "default"; private static final String ADMIN_USERNAME = "admin"; private static final String ADMIN_PASSWORD = "admin"; private static final String ADMIN_EMAIL = "admin@craftersoftware.com"; private static final Set<String> ADMIN_ROLES = new HashSet<>(Arrays.asList("PROFILE_SUPERADMIN", "SOCIAL_ADMIN")); private static final String JDOE_USERNAME = "jdoe"; private static final String JDOE_EMAIL = "john.doe@craftersoftware.com"; private static final Set<String> JDOE_ROLES = new HashSet<>(Arrays.asList("SOCIAL_ADMIN")); private static final String JDOE_FIRST_NAME = "John"; private static final String JDOE_LAST_NAME = "Doe"; private static final String JDOE_SUBSCRIPTIONS_FREQUENCY = "instant"; private static final boolean JDOE_SUBSCRIPTIONS_AUTO_WATCH = true; private static final List<String> JDOE_SUBSCRIPTIONS_TARGETS = Arrays.asList("news"); private static final String AVASQUEZ_USERNAME = "avasquez"; private static final String AVASQUEZ_PASSWORD1 = "1234"; private static final String AVASQUEZ_PASSWORD2 = "4321"; private static final String AVASQUEZ_EMAIL1 = "alfonso.vasquez@craftersoftware.com"; private static final String AVASQUEZ_EMAIL2 = "avasquez@rivetlogic.com"; private static final Set<String> AVASQUEZ_ROLES1 = SetUtils.asSet("PROFILE_SUPERADMIN", "SOCIAL_MODERATOR"); private static final Set<String> AVASQUEZ_ROLES2 = SetUtils.asSet("SOCIAL_AUTHOR"); private static final String AVASQUEZ_FIRST_NAME = "Alfonso"; private static final String AVASQUEZ_LAST_NAME = "Vasquez"; private static final String VERIFICATION_URL = "http://localhost:8983/crafter-profile" + BASE_URL_PROFILE + URL_PROFILE_VERIFY; private static final String RESET_PASSWORD_URL = "http://localhost:8983/crafter-profile" + BASE_URL_PROFILE + URL_PROFILE_CHANGE_PASSWORD; private static final String QUERY1 = "{email: 'admin@craftersoftware.com'}"; private static final String QUERY2 = "{attributes.subscriptions.targets: 'news'}"; private static final String QUERY3 = "{roles: 'SOCIAL_ADMIN'}"; private static final String INVALID_QUERY1 = "{tenant: 'default'}"; private static final String INVALID_QUERY2 = "{$where: \"this.email == 'admin@craftersoftware.com'\"}"; @Autowired private ProfileService profileService; @Autowired private TenantService tenantService; @Autowired private AuthenticationService authenticationService; @Autowired private SingleAccessTokenIdResolver accessTokenIdResolver; @Test public void testCreateProfile() throws Exception { Map<String, Object> attributes = new LinkedHashMap<>(2); attributes.put("firstName", AVASQUEZ_FIRST_NAME); attributes.put("lastName", AVASQUEZ_LAST_NAME); Profile profile = profileService.createProfile(DEFAULT_TENANT, AVASQUEZ_USERNAME, AVASQUEZ_PASSWORD1, AVASQUEZ_EMAIL1, true, AVASQUEZ_ROLES1, attributes, VERIFICATION_URL); try { assertNotNull(profile); assertNotNull(profile.getId()); assertEquals(AVASQUEZ_USERNAME, profile.getUsername()); assertNull(profile.getPassword()); assertEquals(AVASQUEZ_EMAIL1, profile.getEmail()); assertFalse(profile.isVerified()); assertTrue(profile.isEnabled()); assertNotNull(profile.getCreatedOn()); assertNotNull(profile.getLastModified()); assertEquals(DEFAULT_TENANT, profile.getTenant()); assertEquals(AVASQUEZ_ROLES1, profile.getRoles()); assertNotNull(profile.getAttributes()); assertEquals(attributes, profile.getAttributes()); } finally { profileService.deleteProfile(profile.getId().toString()); } } @Test public void testCreateAndVerifyProfile() throws Exception { GreenMail mailServer = new GreenMail(ServerSetupTest.SMTP); mailServer.start(); tenantService.verifyNewProfiles(DEFAULT_TENANT, true); Profile profile = profileService.createProfile(DEFAULT_TENANT, AVASQUEZ_USERNAME, AVASQUEZ_PASSWORD1, AVASQUEZ_EMAIL1, true, AVASQUEZ_ROLES1, null, VERIFICATION_URL); try { assertNotNull(profile); assertNotNull(profile.getId()); assertEquals(AVASQUEZ_USERNAME, profile.getUsername()); assertNull(profile.getPassword()); assertEquals(AVASQUEZ_EMAIL1, profile.getEmail()); assertFalse(profile.isVerified()); assertFalse(profile.isEnabled()); assertNotNull(profile.getCreatedOn()); assertNotNull(profile.getLastModified()); assertEquals(DEFAULT_TENANT, profile.getTenant()); assertEquals(AVASQUEZ_ROLES1, profile.getRoles()); assertNotNull(profile.getAttributes()); assertEquals(0, profile.getAttributes().size()); // Wait a few seconds so that the email can be sent Thread.sleep(3000); String email = GreenMailUtil.getBody(mailServer.getReceivedMessages()[0]); assertNotNull(email); Pattern emailPattern = Pattern.compile(VERIFICATION_EMAIL_REGEX, Pattern.DOTALL); Matcher emailMatcher = emailPattern.matcher(email); assertTrue(emailMatcher.matches()); String verificationTokenId = emailMatcher.group(1); Profile verifiedProfile = profileService.verifyProfile(verificationTokenId); assertNotNull(verifiedProfile); assertEquals(profile.getId(), verifiedProfile.getId()); assertTrue(verifiedProfile.isEnabled()); assertTrue(verifiedProfile.isVerified()); } finally { profileService.deleteProfile(profile.getId().toString()); tenantService.verifyNewProfiles(DEFAULT_TENANT, false); mailServer.stop(); } } @Test public void testUpdateProfile() throws Exception { Profile profile = profileService.createProfile(DEFAULT_TENANT, AVASQUEZ_USERNAME, AVASQUEZ_PASSWORD1, AVASQUEZ_EMAIL1, true, AVASQUEZ_ROLES1, null, VERIFICATION_URL); try { assertNotNull(profile); Map<String, Object> attributes = new LinkedHashMap<>(2); attributes.put("firstName", AVASQUEZ_FIRST_NAME); attributes.put("lastName", AVASQUEZ_LAST_NAME); Profile updatedProfile = profileService.updateProfile(profile.getId().toString(), AVASQUEZ_USERNAME, AVASQUEZ_PASSWORD2, AVASQUEZ_EMAIL2, false, AVASQUEZ_ROLES2, attributes); assertNotNull(updatedProfile); assertEquals(profile.getId(), updatedProfile.getId()); assertEquals(profile.getUsername(), updatedProfile.getUsername()); assertNull(updatedProfile.getPassword()); assertEquals(AVASQUEZ_EMAIL2, updatedProfile.getEmail()); assertEquals(profile.isVerified(), updatedProfile.isVerified()); assertFalse(updatedProfile.isEnabled()); assertEquals(profile.getCreatedOn(), updatedProfile.getCreatedOn()); assertTrue(profile.getLastModified().before(updatedProfile.getLastModified())); assertEquals(profile.getTenant(), updatedProfile.getTenant()); assertEquals(AVASQUEZ_ROLES2, updatedProfile.getRoles()); assertEquals(attributes, updatedProfile.getAttributes()); } finally { profileService.deleteProfile(profile.getId().toString()); } } @Test public void testEnableProfile() throws Exception { Profile profile = profileService.createProfile(DEFAULT_TENANT, AVASQUEZ_USERNAME, AVASQUEZ_PASSWORD1, AVASQUEZ_EMAIL1, false, AVASQUEZ_ROLES1, null, VERIFICATION_URL); try { assertNotNull(profile); assertFalse(profile.isEnabled()); Profile updatedProfile = profileService.enableProfile(profile.getId().toString()); assertNotNull(updatedProfile); assertEquals(profile.getId(), updatedProfile.getId()); assertEquals(profile.getUsername(), updatedProfile.getUsername()); assertNull(updatedProfile.getPassword()); assertEquals(profile.getEmail(), updatedProfile.getEmail()); assertEquals(profile.isVerified(), updatedProfile.isVerified()); assertTrue(updatedProfile.isEnabled()); assertEquals(profile.getCreatedOn(), updatedProfile.getCreatedOn()); assertTrue(profile.getLastModified().before(updatedProfile.getLastModified())); assertEquals(profile.getTenant(), updatedProfile.getTenant()); assertEquals(profile.getRoles(), updatedProfile.getRoles()); assertEquals(profile.getAttributes(), updatedProfile.getAttributes()); } finally { profileService.deleteProfile(profile.getId().toString()); } } @Test public void testDisableProfile() throws Exception { Profile profile = profileService.createProfile(DEFAULT_TENANT, AVASQUEZ_USERNAME, AVASQUEZ_PASSWORD1, AVASQUEZ_EMAIL1, true, AVASQUEZ_ROLES1, null, VERIFICATION_URL); try { assertNotNull(profile); assertTrue(profile.isEnabled()); Profile updatedProfile = profileService.disableProfile(profile.getId().toString()); assertNotNull(updatedProfile); assertEquals(profile.getId(), updatedProfile.getId()); assertEquals(profile.getUsername(), updatedProfile.getUsername()); assertNull(updatedProfile.getPassword()); assertEquals(profile.getEmail(), updatedProfile.getEmail()); assertEquals(profile.isVerified(), updatedProfile.isVerified()); assertFalse(updatedProfile.isEnabled()); assertEquals(profile.getCreatedOn(), updatedProfile.getCreatedOn()); assertTrue(profile.getLastModified().before(updatedProfile.getLastModified())); assertEquals(profile.getTenant(), updatedProfile.getTenant()); assertEquals(profile.getRoles(), updatedProfile.getRoles()); assertEquals(profile.getAttributes(), updatedProfile.getAttributes()); } finally { profileService.deleteProfile(profile.getId().toString()); } } @Test public void testAddRoles() throws Exception { Profile profile = profileService.createProfile(DEFAULT_TENANT, AVASQUEZ_USERNAME, AVASQUEZ_PASSWORD1, AVASQUEZ_EMAIL1, false, AVASQUEZ_ROLES1, null, VERIFICATION_URL); try { assertNotNull(profile); assertEquals(AVASQUEZ_ROLES1, profile.getRoles()); Profile updatedProfile = profileService.addRoles(profile.getId().toString(), Arrays.asList("SOCIAL_AUTHOR")); Set<String> expectedRoles = new HashSet<>(AVASQUEZ_ROLES1); expectedRoles.add("SOCIAL_AUTHOR"); assertNotNull(updatedProfile); assertEquals(profile.getId(), updatedProfile.getId()); assertEquals(profile.getUsername(), updatedProfile.getUsername()); assertNull(updatedProfile.getPassword()); assertEquals(profile.getEmail(), updatedProfile.getEmail()); assertEquals(profile.isVerified(), updatedProfile.isVerified()); assertEquals(profile.isEnabled(), updatedProfile.isEnabled()); assertEquals(profile.getCreatedOn(), updatedProfile.getCreatedOn()); assertTrue(profile.getLastModified().before(updatedProfile.getLastModified())); assertEquals(profile.getTenant(), updatedProfile.getTenant()); assertEquals(expectedRoles, updatedProfile.getRoles()); assertEquals(profile.getAttributes(), updatedProfile.getAttributes()); } finally { profileService.deleteProfile(profile.getId().toString()); } } @Test public void testRemoveRoles() throws Exception { Profile profile = profileService.createProfile(DEFAULT_TENANT, AVASQUEZ_USERNAME, AVASQUEZ_PASSWORD1, AVASQUEZ_EMAIL1, false, AVASQUEZ_ROLES1, null, VERIFICATION_URL); try { assertNotNull(profile); assertEquals(AVASQUEZ_ROLES1, profile.getRoles()); Profile updatedProfile = profileService.removeRoles(profile.getId().toString(), Arrays.asList ("SOCIAL_MODERATOR")); Set<String> expectedRoles = new HashSet<>(AVASQUEZ_ROLES1); expectedRoles.remove("SOCIAL_MODERATOR"); assertNotNull(updatedProfile); assertEquals(profile.getId(), updatedProfile.getId()); assertEquals(profile.getUsername(), updatedProfile.getUsername()); assertNull(updatedProfile.getPassword()); assertEquals(profile.getEmail(), updatedProfile.getEmail()); assertEquals(profile.isVerified(), updatedProfile.isVerified()); assertEquals(profile.isEnabled(), updatedProfile.isEnabled()); assertEquals(profile.getCreatedOn(), updatedProfile.getCreatedOn()); assertTrue(profile.getLastModified().before(updatedProfile.getLastModified())); assertEquals(profile.getTenant(), updatedProfile.getTenant()); assertEquals(expectedRoles, updatedProfile.getRoles()); assertEquals(profile.getAttributes(), updatedProfile.getAttributes()); } finally { profileService.deleteProfile(profile.getId().toString()); } } @Test @DirtiesContext public void testGetAllAttributes() throws Exception { // Get all attributes ObjectId profileId = profileService.getProfileByUsername(DEFAULT_TENANT, JDOE_USERNAME).getId(); Map<String, Object> attributes = profileService.getAttributes(profileId.toString()); assertNotNull(attributes); assertEquals(3, attributes.size()); assertEquals(JDOE_FIRST_NAME, attributes.get("firstName")); assertEquals(JDOE_LAST_NAME, attributes.get("lastName")); Map<String, Object> subscriptions = (Map<String, Object>)attributes.get("subscriptions"); assertNotNull(subscriptions); assertEquals(3, subscriptions.size()); assertEquals(JDOE_SUBSCRIPTIONS_FREQUENCY, subscriptions.get("frequency")); assertEquals(JDOE_SUBSCRIPTIONS_AUTO_WATCH, subscriptions.get("autoWatch")); assertEquals(JDOE_SUBSCRIPTIONS_TARGETS, subscriptions.get("targets")); accessTokenIdResolver.setAccessTokenId(RANDOM_APP_ACCESS_TOKEN_ID); // Get only allowed attributes attributes = profileService.getAttributes(profileId.toString()); assertNotNull(attributes); assertEquals(2, attributes.size()); assertEquals(JDOE_FIRST_NAME, attributes.get("firstName")); assertEquals(JDOE_LAST_NAME, attributes.get("lastName")); // Get a specific attribute attributes = profileService.getAttributes(profileId.toString(), "firstName"); assertNotNull(attributes); assertEquals(1, attributes.size()); assertEquals(JDOE_FIRST_NAME, attributes.get("firstName")); // Get no attributes attributes = profileService.getAttributes(profileId.toString(), NO_ATTRIBUTE); assertNotNull(attributes); assertEquals(0, attributes.size()); } @Test @DirtiesContext public void testUpdateAttributes() throws Exception { // Update a bunch attributes Profile profile = profileService.createProfile(DEFAULT_TENANT, AVASQUEZ_USERNAME, AVASQUEZ_PASSWORD1, AVASQUEZ_EMAIL1, false, AVASQUEZ_ROLES1, null, VERIFICATION_URL); Map<String, Object> attributes = new HashMap<>(); try { Map<String, Object> subscriptions = new HashMap<>(); subscriptions.put("frequency", JDOE_SUBSCRIPTIONS_FREQUENCY); subscriptions.put("autoWatch", JDOE_SUBSCRIPTIONS_AUTO_WATCH); subscriptions.put("targets", JDOE_SUBSCRIPTIONS_TARGETS); attributes.put("subscriptions", subscriptions); profile = profileService.updateAttributes(profile.getId().toString(), attributes); attributes = profile.getAttributes(); assertNotNull(attributes); assertEquals(1, attributes.size()); subscriptions = (Map<String, Object>)attributes.get("subscriptions"); assertNotNull(subscriptions); assertEquals(3, subscriptions.size()); assertEquals(JDOE_SUBSCRIPTIONS_FREQUENCY, subscriptions.get("frequency")); assertEquals(JDOE_SUBSCRIPTIONS_AUTO_WATCH, subscriptions.get("autoWatch")); assertEquals(JDOE_SUBSCRIPTIONS_TARGETS, subscriptions.get("targets")); accessTokenIdResolver.setAccessTokenId(RANDOM_APP_ACCESS_TOKEN_ID); // Unallowed updates should be rejected try { profileService.updateAttributes(profile.getId().toString(), attributes); fail("Exception " + ProfileRestServiceException.class.getName() + " expected"); } catch (ProfileRestServiceException e) { assertEquals(HttpStatus.FORBIDDEN, e.getStatus()); assertEquals(ErrorCode.ACTION_DENIED, e.getErrorCode()); } } finally { profileService.deleteProfile(profile.getId().toString()); } } @Test @DirtiesContext public void testDeleteAttributes() throws Exception { Profile profile = profileService.createProfile(DEFAULT_TENANT, AVASQUEZ_USERNAME, AVASQUEZ_PASSWORD1, AVASQUEZ_EMAIL1, false, AVASQUEZ_ROLES1, null, VERIFICATION_URL); Map<String, Object> attributes = new HashMap<>(); try { Map<String, Object> subscriptions = new HashMap<>(); subscriptions.put("frequency", JDOE_SUBSCRIPTIONS_FREQUENCY); subscriptions.put("autoWatch", JDOE_SUBSCRIPTIONS_AUTO_WATCH); subscriptions.put("targets", JDOE_SUBSCRIPTIONS_TARGETS); attributes.put("subscriptions", subscriptions); profileService.updateAttributes(profile.getId().toString(), attributes); accessTokenIdResolver.setAccessTokenId(RANDOM_APP_ACCESS_TOKEN_ID); // Unallowed deletes should be rejected try { profileService.removeAttributes(profile.getId().toString(), Arrays.asList("subscriptions")); fail("Exception " + ProfileRestServiceException.class.getName() + " expected"); } catch (ProfileRestServiceException e) { assertEquals(HttpStatus.FORBIDDEN, e.getStatus()); assertEquals(ErrorCode.ACTION_DENIED, e.getErrorCode()); } accessTokenIdResolver.setAccessTokenId(ADMIN_CONSOLE_ACCESS_TOKEN_ID); // Delete an attribute profile = profileService.removeAttributes(profile.getId().toString(), Arrays.asList("subscriptions")); attributes = profile.getAttributes(); assertNotNull(attributes); assertEquals(0, attributes.size()); } finally { profileService.deleteProfile(profile.getId().toString()); } } @Test public void testDeleteProfile() throws Exception { Profile profile = profileService.createProfile(DEFAULT_TENANT, AVASQUEZ_USERNAME, AVASQUEZ_PASSWORD1, AVASQUEZ_EMAIL1, false, AVASQUEZ_ROLES1, null, VERIFICATION_URL); assertNotNull(profile); profileService.deleteProfile(profile.getId().toString()); profile = profileService.getProfile(profile.getId().toString()); assertNull(profile); } @Test @DirtiesContext public void testGetProfileByQuery() throws Exception { Profile profile = profileService.getProfileByQuery(DEFAULT_TENANT, QUERY1); assertAdminProfile(profile); // Try with tenant field in query try { profileService.getProfileByQuery(DEFAULT_TENANT, INVALID_QUERY1); fail("Exception " + ProfileRestServiceException.class.getName() + " expected"); } catch (ProfileRestServiceException e) { assertEquals(HttpStatus.BAD_REQUEST, e.getStatus()); assertEquals(ErrorCode.INVALID_QUERY, e.getErrorCode()); } // Try with $where operator in query try { profileService.getProfileByQuery(DEFAULT_TENANT, INVALID_QUERY2); fail("Exception " + ProfileRestServiceException.class.getName() + " expected"); } catch (ProfileRestServiceException e) { assertEquals(HttpStatus.BAD_REQUEST, e.getStatus()); assertEquals(ErrorCode.INVALID_QUERY, e.getErrorCode()); } accessTokenIdResolver.setAccessTokenId(RANDOM_APP_ACCESS_TOKEN_ID); // Try with unreadable attribute in query try { profileService.getProfileByQuery(DEFAULT_TENANT, QUERY2); fail("Exception " + ProfileRestServiceException.class.getName() + " expected"); } catch (ProfileRestServiceException e) { assertEquals(HttpStatus.BAD_REQUEST, e.getStatus()); assertEquals(ErrorCode.INVALID_QUERY, e.getErrorCode()); } } @Test public void testGetProfile() throws Exception { ObjectId profileId = profileService.getProfileByUsername(DEFAULT_TENANT, ADMIN_USERNAME).getId(); Profile profile = profileService.getProfile(profileId.toString()); assertAdminProfile(profile); } @Test public void testGetProfileByUsername() throws Exception { Profile profile = profileService.getProfileByUsername(DEFAULT_TENANT, ADMIN_USERNAME); assertAdminProfile(profile); } @Test public void testGetProfileByTicket() throws Exception { Ticket ticket = authenticationService.authenticate(DEFAULT_TENANT, ADMIN_USERNAME, ADMIN_PASSWORD); Profile profile = profileService.getProfileByTicket(ticket.getId().toString()); assertAdminProfile(profile); authenticationService.invalidateTicket(ticket.getId().toString()); // Try with invalid ticket try { profileService.getProfileByTicket("507c7f79bcf86cd7994f6c0e"); fail("Exception " + ProfileRestServiceException.class.getName() + " expected"); } catch (ProfileRestServiceException e) { assertEquals(HttpStatus.BAD_REQUEST, e.getStatus()); assertEquals(ErrorCode.NO_SUCH_TICKET, e.getErrorCode()); } } @Test public void testGetProfileCount() throws Exception { long count = profileService.getProfileCount(DEFAULT_TENANT); assertEquals(2, count); } @Test @DirtiesContext public void testGetProfileCountByQuery() throws Exception { long count = profileService.getProfileCountByQuery(DEFAULT_TENANT, QUERY2); assertEquals(1, count); // Try with tenant field in query try { profileService.getProfileCountByQuery(DEFAULT_TENANT, INVALID_QUERY1); fail("Exception " + ProfileRestServiceException.class.getName() + " expected"); } catch (ProfileRestServiceException e) { assertEquals(HttpStatus.BAD_REQUEST, e.getStatus()); assertEquals(ErrorCode.INVALID_QUERY, e.getErrorCode()); } // Try with $where operator in query try { profileService.getProfileCountByQuery(DEFAULT_TENANT, INVALID_QUERY2); fail("Exception " + ProfileRestServiceException.class.getName() + " expected"); } catch (ProfileRestServiceException e) { assertEquals(HttpStatus.BAD_REQUEST, e.getStatus()); assertEquals(ErrorCode.INVALID_QUERY, e.getErrorCode()); } accessTokenIdResolver.setAccessTokenId(RANDOM_APP_ACCESS_TOKEN_ID); // Try with unreadable attribute in query try { profileService.getProfileCountByQuery(DEFAULT_TENANT, QUERY2); fail("Exception " + ProfileRestServiceException.class.getName() + " expected"); } catch (ProfileRestServiceException e) { assertEquals(HttpStatus.BAD_REQUEST, e.getStatus()); assertEquals(ErrorCode.INVALID_QUERY, e.getErrorCode()); } } @Test @DirtiesContext public void testGetProfilesByQuery() throws Exception { List<Profile> profiles = profileService.getProfilesByQuery(DEFAULT_TENANT, QUERY2, null, null, null, null); assertNotNull(profiles); assertEquals(1, profiles.size()); assertJdoeProfile(profiles.get(0)); // With sort and start/limit profiles = profileService.getProfilesByQuery(DEFAULT_TENANT, QUERY3, "username", SortOrder.DESC, 1, 1); assertNotNull(profiles); assertEquals(1, profiles.size()); assertAdminProfile(profiles.get(0)); // Try with tenant field in query try { profileService.getProfilesByQuery(DEFAULT_TENANT, INVALID_QUERY1, null, null, null, null); fail("Exception " + ProfileRestServiceException.class.getName() + " expected"); } catch (ProfileRestServiceException e) { assertEquals(HttpStatus.BAD_REQUEST, e.getStatus()); assertEquals(ErrorCode.INVALID_QUERY, e.getErrorCode()); } // Try with $where operator in query try { profileService.getProfilesByQuery(DEFAULT_TENANT, INVALID_QUERY2, null, null, null, null); fail("Exception " + ProfileRestServiceException.class.getName() + " expected"); } catch (ProfileRestServiceException e) { assertEquals(HttpStatus.BAD_REQUEST, e.getStatus()); assertEquals(ErrorCode.INVALID_QUERY, e.getErrorCode()); } accessTokenIdResolver.setAccessTokenId(RANDOM_APP_ACCESS_TOKEN_ID); // Try with unreadable attribute in query try { profileService.getProfilesByQuery(DEFAULT_TENANT, QUERY2, null, null, null, null); fail("Exception " + ProfileRestServiceException.class.getName() + " expected"); } catch (ProfileRestServiceException e) { assertEquals(HttpStatus.BAD_REQUEST, e.getStatus()); assertEquals(ErrorCode.INVALID_QUERY, e.getErrorCode()); } } @Test public void testGetProfileByIds() throws Exception { ObjectId adminProfileId = profileService.getProfileByUsername(DEFAULT_TENANT, ADMIN_USERNAME).getId(); ObjectId jdoeProfileId = profileService.getProfileByUsername(DEFAULT_TENANT, JDOE_USERNAME).getId(); List<Profile> profiles = profileService.getProfilesByIds(Arrays.asList(adminProfileId.toString(), jdoeProfileId.toString()), null, null); assertNotNull(profiles); assertEquals(2, profiles.size()); assertAdminProfile(profiles.get(0)); assertJdoeProfile(profiles.get(1)); // With sort profiles = profileService.getProfilesByIds(Arrays.asList(adminProfileId.toString(), jdoeProfileId.toString()), "username", SortOrder.DESC); assertNotNull(profiles); assertEquals(2, profiles.size()); assertJdoeProfile(profiles.get(0)); assertAdminProfile(profiles.get(1)); } @Test public void testGetProfileRange() throws Exception { List<Profile> profiles = profileService.getProfileRange(DEFAULT_TENANT, null, null, 1, 1); assertNotNull(profiles); assertEquals(1, profiles.size()); assertJdoeProfile(profiles.get(0)); // With sort profiles = profileService.getProfileRange(DEFAULT_TENANT, "username", SortOrder.DESC, 1, 1); assertNotNull(profiles); assertEquals(1, profiles.size()); assertAdminProfile(profiles.get(0)); } @Test public void testGetProfileByRole() throws Exception { List<Profile> profiles = profileService.getProfilesByRole(DEFAULT_TENANT, "SOCIAL_ADMIN", null, null); assertNotNull(profiles); assertEquals(2, profiles.size()); assertAdminProfile(profiles.get(0)); assertJdoeProfile(profiles.get(1)); // With sort profiles = profileService.getProfilesByRole(DEFAULT_TENANT, "SOCIAL_ADMIN", "username", SortOrder.DESC); assertNotNull(profiles); assertEquals(2, profiles.size()); assertJdoeProfile(profiles.get(0)); assertAdminProfile(profiles.get(1)); } @Test public void testGetProfileByExistingAttribute() throws Exception { List<Profile> profiles = profileService.getProfilesByExistingAttribute(DEFAULT_TENANT, "subscriptions." + "frequency", null, null); assertNotNull(profiles); assertEquals(1, profiles.size()); assertJdoeProfile(profiles.get(0)); // With sort profiles = profileService.getProfilesByExistingAttribute(DEFAULT_TENANT, "subscriptions.frequency", "username", SortOrder.DESC); assertNotNull(profiles); assertEquals(1, profiles.size()); assertJdoeProfile(profiles.get(0)); } @Test public void testGetProfileByAttributeValue() throws Exception { List<Profile> profiles = profileService.getProfilesByAttributeValue(DEFAULT_TENANT, "subscriptions." + "frequency", "instant", null, null); assertNotNull(profiles); assertEquals(1, profiles.size()); assertJdoeProfile(profiles.get(0)); // With sort profiles = profileService.getProfilesByAttributeValue(DEFAULT_TENANT, "subscriptions.frequency", "instant", "username", SortOrder.DESC); assertNotNull(profiles); assertEquals(1, profiles.size()); assertJdoeProfile(profiles.get(0)); } @Test public void testResetAndChangePassword() throws Exception { GreenMail mailServer = new GreenMail(ServerSetupTest.SMTP); mailServer.start(); Profile profile = profileService.createProfile(DEFAULT_TENANT, AVASQUEZ_USERNAME, AVASQUEZ_PASSWORD1, AVASQUEZ_EMAIL1, true, AVASQUEZ_ROLES1, null, VERIFICATION_URL); try { profile = profileService.resetPassword(profile.getId().toString(), RESET_PASSWORD_URL); assertNotNull(profile); // Wait a few seconds so that the email can be sent Thread.sleep(3000); String email = GreenMailUtil.getBody(mailServer.getReceivedMessages()[0]); assertNotNull(email); Pattern emailPattern = Pattern.compile(VERIFICATION_EMAIL_REGEX, Pattern.DOTALL); Matcher emailMatcher = emailPattern.matcher(email); assertTrue(emailMatcher.matches()); String resetTokenId = emailMatcher.group(1); Profile profileAfterPswdReset = profileService.changePassword(resetTokenId, AVASQUEZ_PASSWORD2); assertNotNull(profileAfterPswdReset); assertEquals(profile.getId(), profileAfterPswdReset.getId()); assertNull(profileAfterPswdReset.getPassword()); } finally { profileService.deleteProfile(profile.getId().toString()); mailServer.stop(); } } @Test public void testCreateVerificationToken() throws Exception { Profile profile = profileService.getProfileByUsername(DEFAULT_TENANT, ADMIN_USERNAME); String profileId = profile.getId().toString(); VerificationToken token = profileService.createVerificationToken(profileId); assertNotNull(token); try { assertNotNull(token.getId()); assertEquals(profile.getTenant(), token.getTenant()); assertEquals(profileId, token.getProfileId()); assertNotNull(token.getTimestamp()); } finally { profileService.deleteVerificationToken(token.getId()); } } @Test public void testGetVerificationToken() throws Exception { Profile profile = profileService.getProfileByUsername(DEFAULT_TENANT, ADMIN_USERNAME); String profileId = profile.getId().toString(); VerificationToken originalToken = profileService.createVerificationToken(profileId); assertNotNull(originalToken); try { VerificationToken token = profileService.getVerificationToken(originalToken.getId()); assertNotNull(token); assertEquals(originalToken.getId(), token.getId()); assertEquals(originalToken.getTenant(), token.getTenant()); assertEquals(originalToken.getProfileId(), token.getProfileId()); assertEquals(originalToken.getTimestamp(), token.getTimestamp()); } finally { profileService.deleteVerificationToken(originalToken.getId()); } } @Test public void testDeleteVerificationToken() throws Exception { Profile profile = profileService.getProfileByUsername(DEFAULT_TENANT, ADMIN_USERNAME); String profileId = profile.getId().toString(); VerificationToken token = profileService.createVerificationToken(profileId); assertNotNull(token); profileService.deleteVerificationToken(token.getId()); token = profileService.getVerificationToken(token.getId()); assertNull(token); } private void assertAdminProfile(Profile profile) { assertNotNull(profile); assertEquals(ADMIN_USERNAME, profile.getUsername()); assertNull(profile.getPassword()); assertEquals(ADMIN_EMAIL, profile.getEmail()); assertFalse(profile.isVerified()); assertTrue(profile.isEnabled()); assertNotNull(profile.getCreatedOn()); assertNotNull(profile.getLastModified()); assertEquals(DEFAULT_TENANT, profile.getTenant()); assertEquals(ADMIN_ROLES, profile.getRoles()); assertNotNull(profile.getAttributes()); assertEquals(0, profile.getAttributes().size()); } private void assertJdoeProfile(Profile profile) { assertNotNull(profile); assertEquals(JDOE_USERNAME, profile.getUsername()); assertNull(profile.getPassword()); assertEquals(JDOE_EMAIL, profile.getEmail()); assertFalse(profile.isVerified()); assertFalse(profile.isEnabled()); assertNotNull(profile.getCreatedOn()); assertNotNull(profile.getLastModified()); assertEquals(DEFAULT_TENANT, profile.getTenant()); assertEquals(JDOE_ROLES, profile.getRoles()); Map<String, Object> attributes = profile.getAttributes(); assertNotNull(attributes); assertEquals(3, attributes.size()); assertEquals(JDOE_FIRST_NAME, attributes.get("firstName")); assertEquals(JDOE_LAST_NAME, attributes.get("lastName")); Map<String, Object> subscriptions = (Map<String, Object>)attributes.get("subscriptions"); assertNotNull(subscriptions); assertEquals(3, subscriptions.size()); assertEquals(JDOE_SUBSCRIPTIONS_FREQUENCY, subscriptions.get("frequency")); assertEquals(JDOE_SUBSCRIPTIONS_AUTO_WATCH, subscriptions.get("autoWatch")); assertEquals(JDOE_SUBSCRIPTIONS_TARGETS, subscriptions.get("targets")); } }