package org.pac4j.sql.profile.service;
import org.junit.*;
import org.pac4j.core.exception.*;
import org.pac4j.core.profile.CommonProfile;
import org.pac4j.core.profile.service.AbstractProfileService;
import org.pac4j.core.util.TestsConstants;
import org.pac4j.core.credentials.UsernamePasswordCredentials;
import org.pac4j.core.util.TestsHelper;
import org.pac4j.sql.profile.DbProfile;
import org.pac4j.sql.test.tools.DbServer;
import org.skife.jdbi.v2.DBI;
import org.skife.jdbi.v2.Handle;
import javax.sql.DataSource;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
/**
* Tests the {@link DbProfileService}.
*
* @author Jerome Leleu
* @since 1.8.0
*/
public final class DbProfileServiceTests implements TestsConstants {
private static final int DB_ID = 100000000;
private static final String DB_LINKED_ID = "dbLinkedId";
private static final String DB_PASS = "dbPass";
private static final String DB_USER = "dbUser";
private static final String DB_USER2 = "dbUser2";
private DataSource ds = DbServer.getInstance();
@Test
public void testNullPasswordEncoder() throws HttpAction, CredentialsException {
final DbProfileService dbProfileService = new DbProfileService(ds, FIRSTNAME);
TestsHelper.expectException(() -> dbProfileService.validate(null, null), TechnicalException.class, "passwordEncoder cannot be null");
}
@Test
public void testNullDataSource() throws HttpAction, CredentialsException {
final DbProfileService dbProfileService = new DbProfileService(null, FIRSTNAME);
dbProfileService.setPasswordEncoder(DbServer.PASSWORD_ENCODER);
TestsHelper.expectException(() -> dbProfileService.validate(null, null), TechnicalException.class, "dataSource cannot be null");
}
private UsernamePasswordCredentials login(final String username, final String password, final String attribute) throws HttpAction, CredentialsException {
final DbProfileService dbProfileService = new DbProfileService(ds, attribute);
dbProfileService.setPasswordEncoder(DbServer.PASSWORD_ENCODER);
final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password, CLIENT_NAME);
dbProfileService.validate(credentials, null);
return credentials;
}
@Test
public void testGoodUsernameAttribute() throws HttpAction, CredentialsException {
final UsernamePasswordCredentials credentials = login(GOOD_USERNAME, PASSWORD, FIRSTNAME);
final CommonProfile profile = credentials.getUserProfile();
assertNotNull(profile);
assertTrue(profile instanceof DbProfile);
final DbProfile dbProfile = (DbProfile) profile;
assertEquals(GOOD_USERNAME, dbProfile.getId());
assertEquals(FIRSTNAME_VALUE, dbProfile.getAttribute(FIRSTNAME));
}
@Test
public void testGoodUsernameNoAttribute() throws HttpAction, CredentialsException {
final UsernamePasswordCredentials credentials = login(GOOD_USERNAME, PASSWORD, "");
final CommonProfile profile = credentials.getUserProfile();
assertNotNull(profile);
assertTrue(profile instanceof DbProfile);
final DbProfile dbProfile = (DbProfile) profile;
assertEquals(GOOD_USERNAME, dbProfile.getId());
assertNull(dbProfile.getAttribute(FIRSTNAME));
}
@Test
public void testMultipleUsername() throws HttpAction, CredentialsException {
TestsHelper.expectException(() -> login(MULTIPLE_USERNAME, PASSWORD, ""), MultipleAccountsFoundException.class, "Too many accounts found for: misagh");
}
@Test
public void testBadUsername() throws HttpAction, CredentialsException {
TestsHelper.expectException(() -> login(BAD_USERNAME, PASSWORD, ""), AccountNotFoundException.class, "No account found for: michael");
}
@Test
public void testBadPassword() throws HttpAction, CredentialsException {
TestsHelper.expectException(() -> login(GOOD_USERNAME, PASSWORD + "bad", ""), BadCredentialsException.class, "Bad credentials for: jle");
}
@Test
public void testCreateUpdateFindDelete() throws HttpAction, CredentialsException {
final DbProfile profile = new DbProfile();
profile.setId(DB_ID);
profile.setLinkedId(DB_LINKED_ID);
profile.addAttribute(USERNAME, DB_USER);
final DbProfileService dbProfileService = new DbProfileService(ds);
dbProfileService.setPasswordEncoder(DbServer.PASSWORD_ENCODER);
// create
dbProfileService.create(profile, DB_PASS);
// check credentials
final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(DB_USER, DB_PASS, CLIENT_NAME);
dbProfileService.validate(credentials, null);
final CommonProfile profile1 = credentials.getUserProfile();
assertNotNull(profile1);
// check data
final List<Map<String, Object>> results = getData(DB_ID);
assertEquals(1, results.size());
final Map<String, Object> result = results.get(0);
assertEquals(5, result.size());
assertEquals(DB_ID, result.get(ID));
assertEquals(DB_LINKED_ID, result.get(AbstractProfileService.LINKEDID));
assertNotNull(result.get(AbstractProfileService.SERIALIZED_PROFILE));
assertTrue(DbServer.PASSWORD_ENCODER.matches(DB_PASS, (String) result.get(PASSWORD)));
assertEquals(DB_USER, result.get(USERNAME));
// findById
final DbProfile profile2 = dbProfileService.findById("" + DB_ID);
assertEquals("" + DB_ID, profile2.getId());
assertEquals(DB_LINKED_ID, profile2.getLinkedId());
assertEquals(DB_USER, profile2.getUsername());
assertEquals(1, profile2.getAttributes().size());
// update
profile.addAttribute(USERNAME, DB_USER2);
dbProfileService.update(profile, null);
final List<Map<String, Object>> results2 = getData(DB_ID);
assertEquals(1, results2.size());
final Map<String, Object> result2 = results2.get(0);
assertEquals(5, result2.size());
assertEquals(DB_ID, result2.get(ID));
assertEquals(DB_LINKED_ID, result2.get(AbstractProfileService.LINKEDID));
assertNotNull(result2.get(AbstractProfileService.SERIALIZED_PROFILE));
assertTrue(DbServer.PASSWORD_ENCODER.matches(DB_PASS, (String) result2.get(PASSWORD)));
assertEquals(DB_USER2, result2.get(USERNAME));
// remove
dbProfileService.remove(profile);
final List<Map<String, Object>> results3 = getData(DB_ID);
assertEquals(0, results3.size());
}
private List<Map<String, Object>> getData(final int id) {
final DBI dbi = new DBI(ds);
Handle h = null;
try {
h = dbi.open();
return h.createQuery("select id,username,linkedid,password,serializedprofile from users where id = :id").bind("id", id).list(2);
} finally {
if (h != null) {
h.close();
}
}
}
}