diff --git a/README.md b/README.md index 0679ed9e3a..74e63984d8 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,8 @@ They depend on the `pac4j-core` module (groupId: `org.pac4j`): 7. **OpenID Connect** 1.0 using the `pac4j-oidc` module 8. **JWT** using the `pac4j-jwt` module 9. **LDAP** using the `pac4j-ldap` module -10. **relational DB** using the `pac4j-sql` module. +10. **relational DB** using the `pac4j-sql` module +11. **MongoDB** using the `pac4j-mongo` module. See [all authentication mechanisms](https://github.com/pac4j/pac4j/wiki/Clients). diff --git a/pac4j-core/src/main/java/org/pac4j/core/profile/ProfileHelper.java b/pac4j-core/src/main/java/org/pac4j/core/profile/ProfileHelper.java index 7fdec82a61..bb5e36451f 100644 --- a/pac4j-core/src/main/java/org/pac4j/core/profile/ProfileHelper.java +++ b/pac4j-core/src/main/java/org/pac4j/core/profile/ProfileHelper.java @@ -75,6 +75,8 @@ public static UserProfile buildProfile(final String typedId, final Map attributes = (Collection) ldapProfile.getAttribute(LdapServer.ROLE); assertEquals(2, attributes.size()); diff --git a/pac4j-ldap/src/test/java/org/pac4j/ldap/test/tools/LdapServer.java b/pac4j-ldap/src/test/java/org/pac4j/ldap/test/tools/LdapServer.java index 1d56b92680..d0aa15f57c 100644 --- a/pac4j-ldap/src/test/java/org/pac4j/ldap/test/tools/LdapServer.java +++ b/pac4j-ldap/src/test/java/org/pac4j/ldap/test/tools/LdapServer.java @@ -18,6 +18,7 @@ import com.unboundid.ldap.listener.InMemoryDirectoryServer; import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; import com.unboundid.ldap.listener.InMemoryListenerConfig; +import org.pac4j.core.util.TestsConstants; /** * Simulates a basic LDAP server. @@ -25,17 +26,13 @@ * @author Jerome Leleu * @since 1.8.0 */ -public class LdapServer { +public class LdapServer implements TestsConstants { public final static String BASE_DN = "dc=example,dc=com"; public final static String BASE_PEOPLE_DN = "ou=people,dc=example,dc=com"; public final static int PORT = 33389; public final static String CN = "cn"; public final static String SN = "sn"; - public final static String USERNAME = "jle"; - public final static String USERNAME2 = "jleleu"; - public final static String PASSWORD = "password"; - public final static String FIRSTNAME = "Jerome"; public final static String ROLE = "role"; public final static String ROLE1 = "role1"; public final static String ROLE2 = "role2"; @@ -49,14 +46,14 @@ public void start() { dsConfig.setEnforceAttributeSyntaxCompliance(false); dsConfig.setEnforceSingleStructuralObjectClass(false); dsConfig.setListenerConfigs(new InMemoryListenerConfig("myListener", null, PORT, null, null, null)); - dsConfig.addAdditionalBindCredentials(CN + "=" + USERNAME + "," + BASE_PEOPLE_DN, PASSWORD); - dsConfig.addAdditionalBindCredentials(CN + "=" + USERNAME2 + "," + BASE_PEOPLE_DN, PASSWORD); + dsConfig.addAdditionalBindCredentials(CN + "=" + GOOD_USERNAME + "," + BASE_PEOPLE_DN, PASSWORD); + dsConfig.addAdditionalBindCredentials(CN + "=" + GOOD_USERNAME2 + "," + BASE_PEOPLE_DN, PASSWORD); this.ds = new InMemoryDirectoryServer(dsConfig); this.ds.add("dn: " + BASE_DN, "objectClass: organizationalUnit", "objectClass: top"); this.ds.add("dn: " + BASE_PEOPLE_DN, "objectClass: organizationalUnit"); - this.ds.add("dn: " + CN + "=" + USERNAME + "," + BASE_PEOPLE_DN, CN + ": " + USERNAME, SN + ": " - + FIRSTNAME, "objectClass: person"); - this.ds.add("dn: " + CN + "=" + USERNAME2 + "," + BASE_PEOPLE_DN, ROLE + ": " + ROLE1, ROLE + ": " + ROLE2, + this.ds.add("dn: " + CN + "=" + GOOD_USERNAME + "," + BASE_PEOPLE_DN, CN + ": " + GOOD_USERNAME, SN + ": " + + FIRSTNAME_VALUE, "objectClass: person"); + this.ds.add("dn: " + CN + "=" + GOOD_USERNAME2 + "," + BASE_PEOPLE_DN, ROLE + ": " + ROLE1, ROLE + ": " + ROLE2, "objectClass: person"); //Debug.setEnabled(true); diff --git a/pac4j-mongo/pom.xml b/pac4j-mongo/pom.xml new file mode 100644 index 0000000000..04e70b1aab --- /dev/null +++ b/pac4j-mongo/pom.xml @@ -0,0 +1,78 @@ + + + + 4.0.0 + + + org.pac4j + pac4j + 1.8.0-SNAPSHOT + + + pac4j-mongo + jar + pac4j for MongoDB + + + + org.pac4j + pac4j-core + + + org.pac4j + pac4j-http + + + org.mongodb + mongo-java-driver + + + + junit + junit + test + + + org.pac4j + pac4j-core + test-jar + test + + + de.flapdoodle.embed + de.flapdoodle.embed.mongo + + + + + + + + org.apache.felix + maven-bundle-plugin + + + org.pac4j.mongo + org.pac4j.mongo.*;version=${project.version} + * + + + + + + + diff --git a/pac4j-mongo/src/main/java/org/pac4j/mongo/credentials/authenticator/MongoAuthenticator.java b/pac4j-mongo/src/main/java/org/pac4j/mongo/credentials/authenticator/MongoAuthenticator.java new file mode 100644 index 0000000000..de924e9ac1 --- /dev/null +++ b/pac4j-mongo/src/main/java/org/pac4j/mongo/credentials/authenticator/MongoAuthenticator.java @@ -0,0 +1,174 @@ +/* + Copyright 2012 - 2015 pac4j organization + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ +package org.pac4j.mongo.credentials.authenticator; + +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoCursor; +import com.mongodb.client.MongoDatabase; +import org.bson.Document; +import org.pac4j.core.exception.AccountNotFoundException; +import org.pac4j.core.exception.BadCredentialsException; +import org.pac4j.core.exception.MultipleAccountsFoundException; +import org.pac4j.core.util.CommonHelper; +import org.pac4j.http.credentials.UsernamePasswordCredentials; +import org.pac4j.http.credentials.authenticator.AbstractUsernamePasswordAuthenticator; +import org.pac4j.http.credentials.password.PasswordEncoder; +import org.pac4j.mongo.profile.MongoProfile; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static com.mongodb.client.model.Filters.*; + +/** + * Authenticator for users stored in a MongoDB database, based on the {@link MongoClient} class from the Java Mongo driver. + * It creates the user profile and stores it in the credentials for the {@link org.pac4j.http.profile.creator.AuthenticatorProfileCreator}. + * + * @author Jerome Leleu + * @since 1.8.0 + */ +public class MongoAuthenticator extends AbstractUsernamePasswordAuthenticator { + + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + protected MongoClient mongoClient; + + /** + * This must a list of attribute names separated by commas. + */ + protected String attributes = ""; + protected String usernameAttribute = "username"; + protected String passwordAttribute = "password"; + protected String usersDatabase = "users"; + protected String usersCollection = "users"; + + public MongoAuthenticator() { + } + + public MongoAuthenticator(final MongoClient mongoClient) { + this.mongoClient = mongoClient; + } + + public MongoAuthenticator(final MongoClient mongoClient, final String attributes) { + this.mongoClient = mongoClient; + this.attributes = attributes; + } + + public MongoAuthenticator(final MongoClient mongoClient, final String attributes, final PasswordEncoder passwordEncoder) { + this.mongoClient = mongoClient; + this.attributes = attributes; + this.passwordEncoder = passwordEncoder; + } + + public void validate(UsernamePasswordCredentials credentials) { + CommonHelper.assertNotNull("mongoClient", this.mongoClient); + CommonHelper.assertNotNull("usernameAttribute", this.usernameAttribute); + CommonHelper.assertNotNull("passwordAttribute", this.passwordAttribute); + CommonHelper.assertNotNull("usersDatabase", this.usersDatabase); + CommonHelper.assertNotNull("usersCollection", this.usersCollection); + CommonHelper.assertNotNull("attributes", this.attributes); + CommonHelper.assertNotNull("passwordEncoder", this.passwordEncoder); + + final String username = credentials.getUsername(); + + final MongoDatabase db = mongoClient.getDatabase(usersDatabase); + final MongoCollection collection = db.getCollection(usersCollection); + final MongoCursor cursor = collection.find(eq(usernameAttribute, username)).iterator(); + final List users = new ArrayList<>(); + int i= 0; + while (cursor.hasNext() && i <= 2) { + users.add(cursor.next()); + i++; + } + + if (users.size() == 0) { + throw new AccountNotFoundException("No account found for: " + username); + } else if (users.size() > 1) { + throw new MultipleAccountsFoundException("Too many accounts found for: " + username); + } else { + final Map user = users.get(0); + final String expectedPassword = passwordEncoder.encode(credentials.getPassword()); + final String returnedPassword = (String) user.get(passwordAttribute); + if (CommonHelper.areNotEquals(returnedPassword, expectedPassword)) { + throw new BadCredentialsException("Bad credentials for: " + username); + } else { + final MongoProfile profile = createProfile(username, attributes.split(","), user); + credentials.setUserProfile(profile); + } + } + } + + protected MongoProfile createProfile(final String username, final String[] attributes, final Map result) { + final MongoProfile profile = new MongoProfile(); + profile.setId(username); + for (String attribute: attributes) { + profile.addAttribute(attribute, result.get(attribute)); + } + return profile; + } + + public MongoClient getMongoClient() { + return mongoClient; + } + + public void setMongoClient(MongoClient mongoClient) { + this.mongoClient = mongoClient; + } + + public String getAttributes() { + return attributes; + } + + public void setAttributes(String attributes) { + this.attributes = attributes; + } + + public String getUsernameAttribute() { + return usernameAttribute; + } + + public void setUsernameAttribute(String usernameAttribute) { + this.usernameAttribute = usernameAttribute; + } + + public String getPasswordAttribute() { + return passwordAttribute; + } + + public void setPasswordAttribute(String passwordAttribute) { + this.passwordAttribute = passwordAttribute; + } + + public String getUsersDatabase() { + return usersDatabase; + } + + public void setUsersDatabase(String usersDatabase) { + this.usersDatabase = usersDatabase; + } + + public String getUsersCollection() { + return usersCollection; + } + + public void setUsersCollection(String usersCollection) { + this.usersCollection = usersCollection; + } +} diff --git a/pac4j-mongo/src/main/java/org/pac4j/mongo/profile/MongoProfile.java b/pac4j-mongo/src/main/java/org/pac4j/mongo/profile/MongoProfile.java new file mode 100644 index 0000000000..029f409311 --- /dev/null +++ b/pac4j-mongo/src/main/java/org/pac4j/mongo/profile/MongoProfile.java @@ -0,0 +1,31 @@ +/* + Copyright 2012 - 2015 pac4j organization + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ +package org.pac4j.mongo.profile; + +import org.pac4j.core.profile.CommonProfile; +import org.pac4j.mongo.credentials.authenticator.MongoAuthenticator; + +/** + *

The user profile returned from a MongoDB.

+ * + * @see MongoAuthenticator + * @author Jerome Leleu + * @since 1.8.0 + */ +public class MongoProfile extends CommonProfile { + + private static final long serialVersionUID = 7289249610131900281L; +} diff --git a/pac4j-mongo/src/test/java/org/pac4j/mongo/credentials/authenticator/MongoAuthenticatorIT.java b/pac4j-mongo/src/test/java/org/pac4j/mongo/credentials/authenticator/MongoAuthenticatorIT.java new file mode 100644 index 0000000000..ae592a8c8f --- /dev/null +++ b/pac4j-mongo/src/test/java/org/pac4j/mongo/credentials/authenticator/MongoAuthenticatorIT.java @@ -0,0 +1,162 @@ +/* + Copyright 2012 - 2015 pac4j organization + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ +package org.pac4j.mongo.credentials.authenticator; + +import com.mongodb.MongoClient; +import org.junit.*; +import org.pac4j.core.exception.AccountNotFoundException; +import org.pac4j.core.exception.BadCredentialsException; +import org.pac4j.core.exception.MultipleAccountsFoundException; +import org.pac4j.core.exception.TechnicalException; +import org.pac4j.core.profile.UserProfile; +import org.pac4j.core.util.TestsConstants; +import org.pac4j.http.credentials.UsernamePasswordCredentials; +import org.pac4j.http.credentials.password.NopPasswordEncoder; +import org.pac4j.http.credentials.password.SaltedSha512PasswordEncoder; +import org.pac4j.mongo.profile.MongoProfile; +import org.pac4j.mongo.test.tools.MongoServer; + +import static org.junit.Assert.*; + +/** + * Tests the {@link MongoAuthenticator}. + * + * @author Jerome Leleu + * @since 1.8.0 + */ +public class MongoAuthenticatorIT implements TestsConstants { + + private final static int PORT = 37017; + + private final MongoServer mongoServer = new MongoServer(); + + @Before + public void setUp() { + mongoServer.start(PORT); + } + + @After + public void tearDown() { + mongoServer.stop(); + } + + + @Test(expected = TechnicalException.class) + public void testNullPasswordEncoder() { + final MongoAuthenticator authenticator = new MongoAuthenticator(getClient(), FIRSTNAME); + + authenticator.validate(null); + } + + @Test(expected = TechnicalException.class) + public void testNullAttribute() { + final MongoAuthenticator authenticator = new MongoAuthenticator(getClient(), null, new NopPasswordEncoder()); + + authenticator.validate(null); + } + + @Test(expected = TechnicalException.class) + public void testNullMongoClient() { + final MongoAuthenticator authenticator = new MongoAuthenticator(null, FIRSTNAME, new NopPasswordEncoder()); + + authenticator.validate(null); + } + + @Test(expected = TechnicalException.class) + public void testNullDatabase() { + final MongoAuthenticator authenticator = new MongoAuthenticator(getClient(), FIRSTNAME, new NopPasswordEncoder()); + authenticator.setUsersDatabase(null); + + authenticator.validate(null); + } + + @Test(expected = TechnicalException.class) + public void testNullCollection() { + final MongoAuthenticator authenticator = new MongoAuthenticator(getClient(), FIRSTNAME, new NopPasswordEncoder()); + authenticator.setUsersCollection(null); + + authenticator.validate(null); + } + + @Test(expected = TechnicalException.class) + public void testNullUsername() { + final MongoAuthenticator authenticator = new MongoAuthenticator(getClient(), FIRSTNAME, new NopPasswordEncoder()); + authenticator.setUsernameAttribute(null); + + authenticator.validate(null); + } + + @Test(expected = TechnicalException.class) + public void testNullPassword() { + final MongoAuthenticator authenticator = new MongoAuthenticator(getClient(), FIRSTNAME, new NopPasswordEncoder()); + authenticator.setPasswordAttribute(null); + + authenticator.validate(null); + } + + private MongoClient getClient() { + return new MongoClient("localhost", PORT); + } + + private UsernamePasswordCredentials login(final String username, final String password, final String attribute) { + final MongoAuthenticator authenticator = new MongoAuthenticator(getClient(), attribute); + authenticator.setPasswordEncoder(new SaltedSha512PasswordEncoder(SALT)); + + final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password, CLIENT_NAME); + authenticator.validate(credentials); + + return credentials; + } + + @Test + public void testGoodUsernameAttribute() { + final UsernamePasswordCredentials credentials = login(GOOD_USERNAME, PASSWORD, FIRSTNAME); + + final UserProfile profile = credentials.getUserProfile(); + assertNotNull(profile); + assertTrue(profile instanceof MongoProfile); + final MongoProfile dbProfile = (MongoProfile) profile; + assertEquals(GOOD_USERNAME, dbProfile.getId()); + assertEquals(FIRSTNAME_VALUE, dbProfile.getAttribute(FIRSTNAME)); + } + + @Test + public void testGoodUsernameNoAttribute() { + final UsernamePasswordCredentials credentials = login(GOOD_USERNAME, PASSWORD, ""); + + final UserProfile profile = credentials.getUserProfile(); + assertNotNull(profile); + assertTrue(profile instanceof MongoProfile); + final MongoProfile dbProfile = (MongoProfile) profile; + assertEquals(GOOD_USERNAME, dbProfile.getId()); + assertNull(dbProfile.getAttribute(FIRSTNAME)); + } + + @Test(expected = MultipleAccountsFoundException.class) + public void testMultipleUsername() { + final UsernamePasswordCredentials credentials = login(MULTIPLE_USERNAME, PASSWORD, ""); + } + + @Test(expected = AccountNotFoundException.class) + public void testBadUsername() { + final UsernamePasswordCredentials credentials = login(BAD_USERNAME, PASSWORD, ""); + } + + @Test(expected = BadCredentialsException.class) + public void testBadPassword() { + final UsernamePasswordCredentials credentials = login(GOOD_USERNAME, PASSWORD + "bad", ""); + } +} diff --git a/pac4j-mongo/src/test/java/org/pac4j/mongo/profile/TestMongoProfileHelper.java b/pac4j-mongo/src/test/java/org/pac4j/mongo/profile/TestMongoProfileHelper.java new file mode 100644 index 0000000000..99aabc0273 --- /dev/null +++ b/pac4j-mongo/src/test/java/org/pac4j/mongo/profile/TestMongoProfileHelper.java @@ -0,0 +1,43 @@ +/* + Copyright 2012 - 2015 pac4j organization + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ +package org.pac4j.mongo.profile; + +import org.pac4j.core.profile.CommonProfile; +import org.pac4j.core.profile.ProfileHelper; + +/** + * This class tests the {@link ProfileHelper} class for the {@link MongoProfile}. + * + * @author Jerome Leleu + * @since 1.8.0 + */ +public final class TestMongoProfileHelper extends org.pac4j.core.profile.TestProfileHelper { + + @Override + protected Class getProfileClass() { + return MongoProfile.class; + } + + @Override + protected String getProfileType() { + return "MongoProfile"; + } + + @Override + protected String getAttributeName() { + return "whatever"; + } +} diff --git a/pac4j-mongo/src/test/java/org/pac4j/mongo/test/tools/MongoServer.java b/pac4j-mongo/src/test/java/org/pac4j/mongo/test/tools/MongoServer.java new file mode 100644 index 0000000000..d8f7061e59 --- /dev/null +++ b/pac4j-mongo/src/test/java/org/pac4j/mongo/test/tools/MongoServer.java @@ -0,0 +1,91 @@ +/* + Copyright 2012 - 2015 pac4j organization + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ +package org.pac4j.mongo.test.tools; + +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import de.flapdoodle.embed.mongo.MongodExecutable; +import de.flapdoodle.embed.mongo.MongodProcess; +import de.flapdoodle.embed.mongo.MongodStarter; +import de.flapdoodle.embed.mongo.config.IMongodConfig; +import de.flapdoodle.embed.mongo.config.MongodConfigBuilder; +import de.flapdoodle.embed.mongo.config.Net; +import de.flapdoodle.embed.mongo.distribution.Version; +import de.flapdoodle.embed.process.runtime.Network; +import org.bson.Document; +import org.pac4j.core.util.TestsConstants; +import org.pac4j.http.credentials.password.PasswordEncoder; +import org.pac4j.http.credentials.password.SaltedSha512PasswordEncoder; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * Simulates a MongoDB server. + * + * @author Jerome Leleu + * @since 1.8.0 + */ +public class MongoServer implements TestsConstants { + + private MongodExecutable mongodExecutable; + + public void start(final int port) { + MongodStarter starter = MongodStarter.getDefaultInstance(); + + try { + IMongodConfig mongodConfig = new MongodConfigBuilder() + .version(Version.Main.PRODUCTION) + .net(new Net(port, Network.localhostIsIPv6())) + .build(); + + mongodExecutable = starter.prepare(mongodConfig); + MongodProcess mongod = mongodExecutable.start(); + + // populate + final MongoClient mongo = new MongoClient("localhost", port); + final MongoDatabase db = mongo.getDatabase("users"); + db.createCollection("users"); + final MongoCollection collection = db.getCollection("users"); + final PasswordEncoder encoder = new SaltedSha512PasswordEncoder(SALT); + final String password = encoder.encode(PASSWORD); + Map properties1 = new HashMap<>(); + properties1.put(USERNAME, GOOD_USERNAME); + properties1.put(PASSWORD, password); + properties1.put(FIRSTNAME, FIRSTNAME_VALUE); + collection.insertOne(new Document(properties1)); + Map properties2 = new HashMap<>(); + properties2.put(USERNAME, MULTIPLE_USERNAME); + properties2.put(PASSWORD, password); + collection.insertOne(new Document(properties2)); + Map properties3 = new HashMap<>(); + properties3.put(USERNAME, MULTIPLE_USERNAME); + properties3.put(PASSWORD, password); + collection.insertOne(new Document(properties3)); + + } catch (final IOException e) { + throw new RuntimeException(e); + } + } + + public void stop() { + if (mongodExecutable != null) { + mongodExecutable.stop(); + } + } +} diff --git a/pac4j-sql/src/test/java/org/pac4j/sql/credentials/authenticator/DbAuthenticatorTests.java b/pac4j-sql/src/test/java/org/pac4j/sql/credentials/authenticator/DbAuthenticatorTests.java index 029e7d9ad1..8d2f7475ea 100644 --- a/pac4j-sql/src/test/java/org/pac4j/sql/credentials/authenticator/DbAuthenticatorTests.java +++ b/pac4j-sql/src/test/java/org/pac4j/sql/credentials/authenticator/DbAuthenticatorTests.java @@ -21,6 +21,7 @@ import org.pac4j.core.exception.MultipleAccountsFoundException; import org.pac4j.core.exception.TechnicalException; import org.pac4j.core.profile.UserProfile; +import org.pac4j.core.util.TestsConstants; import org.pac4j.http.credentials.UsernamePasswordCredentials; import org.pac4j.http.credentials.password.NopPasswordEncoder; import org.pac4j.http.credentials.password.SaltedSha512PasswordEncoder; @@ -37,15 +38,13 @@ * @author Jerome Leleu * @since 1.8.0 */ -public class DbAuthenticatorTests { - - private final static String CLIENT_NAME = "clientname"; +public class DbAuthenticatorTests implements TestsConstants { private DataSource ds = DbServer.getInstance(); @Test(expected = TechnicalException.class) public void testNullPasswordEncoder() { - final DbAuthenticator authenticator = new DbAuthenticator(ds, DbServer.ATTRIBUTE); + final DbAuthenticator authenticator = new DbAuthenticator(ds, FIRSTNAME); authenticator.validate(null); } @@ -60,7 +59,7 @@ public void testNullAttribute() { @Test(expected = TechnicalException.class) public void testNullDataSource() { - final DbAuthenticator authenticator = new DbAuthenticator(null, DbServer.ATTRIBUTE); + final DbAuthenticator authenticator = new DbAuthenticator(null, FIRSTNAME); authenticator.setPasswordEncoder(new NopPasswordEncoder()); authenticator.validate(null); @@ -68,7 +67,7 @@ public void testNullDataSource() { private UsernamePasswordCredentials login(final String username, final String password, final String attribute) { final DbAuthenticator authenticator = new DbAuthenticator(ds, attribute); - authenticator.setPasswordEncoder(new SaltedSha512PasswordEncoder(DbServer.SALT)); + authenticator.setPasswordEncoder(new SaltedSha512PasswordEncoder(SALT)); final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password, CLIENT_NAME); authenticator.validate(credentials); @@ -78,40 +77,40 @@ private UsernamePasswordCredentials login(final String username, final String pa @Test public void testGoodUsernameAttribute() { - final UsernamePasswordCredentials credentials = login(DbServer.GOOD_USERNAME, DbServer.PASSWORD, DbServer.ATTRIBUTE); + final UsernamePasswordCredentials credentials = login(GOOD_USERNAME, PASSWORD, FIRSTNAME); final UserProfile profile = credentials.getUserProfile(); assertNotNull(profile); assertTrue(profile instanceof DbProfile); final DbProfile dbProfile = (DbProfile) profile; - assertEquals(DbServer.GOOD_USERNAME, dbProfile.getId()); - assertEquals(DbServer.NICKNAME, dbProfile.getAttribute(DbServer.ATTRIBUTE)); + assertEquals(GOOD_USERNAME, dbProfile.getId()); + assertEquals(FIRSTNAME_VALUE, dbProfile.getAttribute(FIRSTNAME)); } @Test public void testGoodUsernameNoAttribute() { - final UsernamePasswordCredentials credentials = login(DbServer.GOOD_USERNAME, DbServer.PASSWORD, ""); + final UsernamePasswordCredentials credentials = login(GOOD_USERNAME, PASSWORD, ""); final UserProfile profile = credentials.getUserProfile(); assertNotNull(profile); assertTrue(profile instanceof DbProfile); final DbProfile dbProfile = (DbProfile) profile; - assertEquals(DbServer.GOOD_USERNAME, dbProfile.getId()); - assertNull(dbProfile.getAttribute(DbServer.ATTRIBUTE)); + assertEquals(GOOD_USERNAME, dbProfile.getId()); + assertNull(dbProfile.getAttribute(FIRSTNAME)); } @Test(expected = MultipleAccountsFoundException.class) public void testMultipleUsername() { - final UsernamePasswordCredentials credentials = login(DbServer.MULTIPLE_USERNAME, DbServer.PASSWORD, ""); + final UsernamePasswordCredentials credentials = login(MULTIPLE_USERNAME, PASSWORD, ""); } @Test(expected = AccountNotFoundException.class) public void testBadUsername() { - final UsernamePasswordCredentials credentials = login(DbServer.BAD_USERNAME, DbServer.PASSWORD, ""); + final UsernamePasswordCredentials credentials = login(BAD_USERNAME, PASSWORD, ""); } @Test(expected = BadCredentialsException.class) public void testBadPassword() { - final UsernamePasswordCredentials credentials = login(DbServer.GOOD_USERNAME, DbServer.PASSWORD + "bad", ""); + final UsernamePasswordCredentials credentials = login(GOOD_USERNAME, PASSWORD + "bad", ""); } } diff --git a/pac4j-sql/src/test/java/org/pac4j/sql/test/tools/DbServer.java b/pac4j-sql/src/test/java/org/pac4j/sql/test/tools/DbServer.java index 725d6014ca..bd761f300f 100644 --- a/pac4j-sql/src/test/java/org/pac4j/sql/test/tools/DbServer.java +++ b/pac4j-sql/src/test/java/org/pac4j/sql/test/tools/DbServer.java @@ -16,6 +16,7 @@ package org.pac4j.sql.test.tools; import org.h2.jdbcx.JdbcConnectionPool; +import org.pac4j.core.util.TestsConstants; import org.pac4j.http.credentials.password.PasswordEncoder; import org.pac4j.http.credentials.password.SaltedSha512PasswordEncoder; import org.skife.jdbi.v2.DBI; @@ -29,15 +30,7 @@ * @author Jerome Leleu * @since 1.8.0 */ -public class DbServer { - - public final static String SALT = "sel"; - public final static String GOOD_USERNAME = "jleleu"; - public final static String BAD_USERNAME = "michael"; - public final static String MULTIPLE_USERNAME = "misagh"; - public final static String PASSWORD = "pwd"; - public final static String ATTRIBUTE = "nickname"; - public final static String NICKNAME = "theboss"; +public class DbServer implements TestsConstants{ private static DataSource ds; @@ -47,8 +40,8 @@ public class DbServer { final Handle h = dbi.open(); final PasswordEncoder encoder = new SaltedSha512PasswordEncoder(SALT); final String password = encoder.encode(PASSWORD); - h.execute("create table users (id int primary key, username varchar(100), password varchar(300), " + ATTRIBUTE + " varchar(100))"); - h.execute("insert into users values(1, '" + GOOD_USERNAME + "', '" + password + "', '" + NICKNAME + "')"); + h.execute("create table users (id int primary key, username varchar(100), password varchar(300), " + FIRSTNAME + " varchar(100))"); + h.execute("insert into users values(1, '" + GOOD_USERNAME + "', '" + password + "', '" + FIRSTNAME_VALUE + "')"); h.execute("insert into users values(2, '" + MULTIPLE_USERNAME + "', '" + password + "', '')"); h.execute("insert into users values(3, '" + MULTIPLE_USERNAME + "', '" + password + "', '')"); h.close(); diff --git a/pom.xml b/pom.xml index 8b5eabcf73..d00dc97090 100644 --- a/pom.xml +++ b/pom.xml @@ -77,6 +77,7 @@ pac4j-jwt pac4j-ldap pac4j-sql + pac4j-mongo @@ -205,6 +206,11 @@ jdbi 2.63 + + org.mongodb + mongo-java-driver + 3.0.3 + org.pac4j @@ -282,6 +288,12 @@ 1.4.187 test + + de.flapdoodle.embed + de.flapdoodle.embed.mongo + 1.48.2 + test +