You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2010/03/03 12:13:28 UTC
svn commit: r918412 - in /jackrabbit/trunk/jackrabbit-core/src:
main/java/org/apache/jackrabbit/core/security/authentication/
main/java/org/apache/jackrabbit/core/security/user/
test/java/org/apache/jackrabbit/api/security/user/ test/java/org/apache/ja...
Author: angela
Date: Wed Mar 3 11:13:27 2010
New Revision: 918412
URL: http://svn.apache.org/viewvc?rev=918412&view=rev
Log:
- JCR-2527: Fix and simplify CryptedSimpleCredentials
- minor improvements: comments, @Override annotation, redundant throws clause
- consistently use AbstractUserTest#buildPassword(String) for simple user creation
Modified:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentials.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/AuthorizableImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/AbstractUserTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/UserManagerCreateUserTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentialsTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/AuthorizableImplTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImplTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserManagerImplTest.java
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentials.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentials.java?rev=918412&r1=918411&r2=918412&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentials.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentials.java Wed Mar 3 11:13:27 2010
@@ -18,11 +18,14 @@
import org.apache.jackrabbit.core.security.SecurityConstants;
import org.apache.jackrabbit.util.Text;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.jcr.Credentials;
import javax.jcr.SimpleCredentials;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
+import java.security.MessageDigest;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -32,14 +35,18 @@
*/
public class CryptedSimpleCredentials implements Credentials {
+ private static final Logger log = LoggerFactory.getLogger(CryptedSimpleCredentials.class);
+
private final String algorithm;
private final String cryptedPassword;
private final String userId;
private final Map<String, Object> attributes;
/**
- * Take {@link javax.jcr.SimpleCredentials SimpleCredentials} and
- * digest the password if it is plain-text
+ * Build a new instance of <code>CryptedSimpleCredentials</code> from the
+ * given {@link javax.jcr.SimpleCredentials SimpleCredentials} and create
+ * the crypted password field using the {@link SecurityConstants#DEFAULT_DIGEST
+ * default digest}.
*
* @param credentials
* @throws NoSuchAlgorithmException
@@ -56,16 +63,8 @@
throw new IllegalArgumentException();
}
String password = new String(pwd);
- String algo = getAlgorithm(password);
- if (algo == null) {
- // password is plain text
- algorithm = SecurityConstants.DEFAULT_DIGEST;
- cryptedPassword = crypt(password, algorithm);
- } else {
- // password is already encrypted
- algorithm = algo;
- cryptedPassword = password;
- }
+ algorithm = SecurityConstants.DEFAULT_DIGEST;
+ cryptedPassword = crypt(password, algorithm);
String[] attNames = credentials.getAttributeNames();
attributes = new HashMap<String, Object>(attNames.length);
@@ -74,20 +73,39 @@
}
}
- public CryptedSimpleCredentials(String userId, String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {
- if (userId == null || userId.length() == 0 || password == null) {
- throw new IllegalArgumentException("Invalid userID or password. Neither may be null, the userID must have a length > 0.");
+ /**
+ * Create a new instanceof <code>CryptedSimpleCredentials</code> from the
+ * given <code>userId</code> and <code>cryptedPassword</code> strings.
+ * In contrast to {@link CryptedSimpleCredentials(SimpleCredentials)} that
+ * expects the password to be plain text this constructor expects the
+ * password to be already crypted. However, it performs a simple validation
+ * and calls {@link Text#digest(String, byte[])} using the
+ * {@link SecurityConstants#DEFAULT_DIGEST default digest} in case the
+ * given password is found to be plain text.
+ *
+ * @param userId
+ * @param cryptedPassword
+ * @throws NoSuchAlgorithmException
+ * @throws UnsupportedEncodingException
+ */
+ public CryptedSimpleCredentials(String userId, String cryptedPassword) throws NoSuchAlgorithmException, UnsupportedEncodingException {
+ if (userId == null || userId.length() == 0) {
+ throw new IllegalArgumentException("Invalid userID: The userID must have a length > 0.");
+ }
+ if (cryptedPassword == null) {
+ throw new IllegalArgumentException("Password may not be null.");
}
this.userId = userId;
- String algo = getAlgorithm(password);
+ String algo = extractAlgorithm(cryptedPassword);
if (algo == null) {
- // password is plain text
+ // password is plain text including those starting with {invalidAlgorithm}
+ log.debug("Plain text password -> Using " + SecurityConstants.DEFAULT_DIGEST + " to create digest.");
algorithm = SecurityConstants.DEFAULT_DIGEST;
- cryptedPassword = crypt(password, algorithm);
+ this.cryptedPassword = crypt(cryptedPassword, algorithm);
} else {
- // password is already encrypted
+ // password is already encrypted and started with {validAlgorithm}
algorithm = algo;
- cryptedPassword = password;
+ this.cryptedPassword = cryptedPassword;
}
attributes = Collections.emptyMap();
}
@@ -114,9 +132,18 @@
/**
* Compares this instance with the given <code>SimpleCredentials</code> and
- * returns <code>true</code> if both match.
+ * returns <code>true</code> if both match. Successful match is defined to
+ * be the result of
+ * <ul>
+ * <li>Case-insensitive comparison of the UserIDs</li>
+ * <li>Equality of the passwords if the password contained in the simple
+ * credentials is hashed with the algorithm defined in this credentials object.</li>
+ * </ul>
*
- * @param credentials
+ * NOTE, that the simple credentials are exptected to contain the plain text
+ * password.
+ *
+ * @param credentials An instance of simple credentials.
* @return true if {@link SimpleCredentials#getUserID() UserID} and
* {@link SimpleCredentials#getPassword() Password} match.
* @throws NoSuchAlgorithmException
@@ -126,24 +153,20 @@
throws NoSuchAlgorithmException, UnsupportedEncodingException {
if (getUserID().equalsIgnoreCase(credentials.getUserID())) {
- String toMatch = new String(credentials.getPassword());
- String algr = getAlgorithm(toMatch);
-
- if (algr == null && algorithm != null) {
- // pw to match not crypted -> crypt with algorithm present here.
- return crypt(toMatch, algorithm).equals(cryptedPassword);
- } else if (algr != null && algorithm == null) {
- // crypted pw to match but unknown algorithm here -> crypt this pw
- return crypt(algr, cryptedPassword).equals(toMatch);
- }
-
- // both pw to compare define a algorithm and are crypted
- // -> simple comparison of the 2 password strings.
- return toMatch.equals(cryptedPassword);
+ // crypt the password retrieved from the given simple credentials
+ // and test if it is equal to the cryptedPassword field.
+ return cryptedPassword.equals(crypt(String.valueOf(credentials.getPassword()), algorithm));
}
return false;
}
+ /**
+ * @param pwd Plain text password
+ * @param algorithm The algorithm to be used for the digest.
+ * @return Digest of the given password with leading algorithm information.
+ * @throws NoSuchAlgorithmException
+ * @throws UnsupportedEncodingException
+ */
private static String crypt(String pwd, String algorithm)
throws NoSuchAlgorithmException, UnsupportedEncodingException {
@@ -153,12 +176,30 @@
return password.toString();
}
- private static String getAlgorithm(String password) {
- int end = password.indexOf("}");
- if (password.startsWith("{") && end > 0) {
- return password.substring(1, end);
- } else {
- return null;
+ /**
+ * Extract the algorithm from the given crypted password string. Returns the
+ * algorithm or <code>null</code> if the given string doesn't have a
+ * leading <code>{algorith}</code> such as created by {@link #crypt(String, String)
+ * or if the extracted string doesn't represent an available algorithm.
+ *
+ * @param cryptedPwd
+ * @return The algorithm or <code>null</code> if the given string doesn't have a
+ * leading <code>{algorith}</code> such as created by {@link #crypt(String, String)
+ * or if the extracted string isn't an available algorithm.
+ */
+ private static String extractAlgorithm(String cryptedPwd) {
+ int end = cryptedPwd.indexOf("}");
+ if (cryptedPwd.startsWith("{") && end > 0) {
+ String algorithm = cryptedPwd.substring(1, end);
+ try {
+ MessageDigest.getInstance(algorithm);
+ return algorithm;
+ } catch (NoSuchAlgorithmException e) {
+ log.debug("Invalid algorithm detected " + algorithm);
+ }
}
+
+ // not starting with {} or invalid algorithm
+ return null;
}
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/AuthorizableImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/AuthorizableImpl.java?rev=918412&r1=918411&r2=918412&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/AuthorizableImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/AuthorizableImpl.java Wed Mar 3 11:13:27 2010
@@ -155,7 +155,8 @@
checkProtectedProperty(name);
try {
// check if the property has already been created as multi valued
- // property before -> in this case remove in order to avoid valueformatex.
+ // property before -> in this case remove in order to avoid
+ // ValueFormatException.
if (node.hasProperty(name)) {
Property p = node.getProperty(name);
if (p.isMultiple()) {
@@ -188,7 +189,8 @@
checkProtectedProperty(name);
try {
// check if the property has already been created as single valued
- // property before -> in this case remove in order to avoid valueformatex.
+ // property before -> in this case remove in order to avoid
+ // ValueFormatException.
if (node.hasProperty(name)) {
Property p = node.getProperty(name);
if (!p.isMultiple()) {
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java?rev=918412&r1=918411&r2=918412&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java Wed Mar 3 11:13:27 2010
@@ -131,6 +131,7 @@
/**
* @see org.apache.jackrabbit.core.security.authorization.AccessControlProvider#init(Session, Map)
*/
+ @Override
public void init(Session systemSession, Map configuration) throws RepositoryException {
super.init(systemSession, configuration);
if (systemSession instanceof SessionImpl) {
@@ -321,6 +322,7 @@
/**
* @see AbstractCompiledPermissions#buildResult(Path)
*/
+ @Override
protected Result buildResult(Path path) throws RepositoryException {
NodeImpl userNode = null;
try {
@@ -375,7 +377,8 @@
}
} else {
// rep:User node or some other custom node below an existing user.
- // as the auth-folder doesn't allow other residual child nodes.
+ // as the authorizable folder doesn't allow other residual
+ // child nodes.
boolean editingOwnUser = node.isSame(userNode);
if (editingOwnUser) {
// user can only read && write his own props
@@ -426,6 +429,7 @@
/**
* @see CompiledPermissions#close()
*/
+ @Override
public void close() {
try {
observationMgr.removeEventListener(this);
@@ -438,6 +442,7 @@
/**
* @see CompiledPermissions#grants(Path, int)
*/
+ @Override
public boolean grants(Path absPath, int permissions) throws RepositoryException {
if (permissions == Permission.READ) {
// read is always granted
@@ -450,6 +455,7 @@
/**
* @see CompiledPermissions#canReadAll()
*/
+ @Override
public boolean canReadAll() throws RepositoryException {
return true;
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java?rev=918412&r1=918411&r2=918412&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java Wed Mar 3 11:13:27 2010
@@ -44,15 +44,15 @@
//--------------------------------------------------------------------------
/**
- *
+ * Creates a hash of the specified password if it is found to be plain text.
+ *
* @param password
* @return
* @throws RepositoryException
*/
static String buildPasswordValue(String password) throws RepositoryException {
try {
- CryptedSimpleCredentials creds = new CryptedSimpleCredentials("_", password);
- return creds.getPassword();
+ return new CryptedSimpleCredentials("_", password).getPassword();
} catch (NoSuchAlgorithmException e) {
throw new RepositoryException(e);
} catch (UnsupportedEncodingException e) {
@@ -122,9 +122,6 @@
* @see User#changePassword(String)
*/
public void changePassword(String password) throws RepositoryException {
- if (password == null) {
- throw new IllegalArgumentException("The password may never be null.");
- }
Value v = getSession().getValueFactory().createValue(buildPasswordValue(password));
userManager.setProtectedProperty(getNode(), P_PASSWORD, v);
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java?rev=918412&r1=918411&r2=918412&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java Wed Mar 3 11:13:27 2010
@@ -244,7 +244,7 @@
* @param adminId The user ID of the administrator.
* @throws RepositoryException If an error occurs.
*/
- public UserManagerImpl(SessionImpl session, String adminId) throws RepositoryException {
+ public UserManagerImpl(SessionImpl session, String adminId) {
this(session, adminId, null);
}
@@ -267,7 +267,7 @@
* @param config The configuration parameters.
* @throws RepositoryException If an error occurs.
*/
- public UserManagerImpl(SessionImpl session, String adminId, Properties config) throws RepositoryException {
+ public UserManagerImpl(SessionImpl session, String adminId, Properties config) {
this.session = session;
this.adminId = adminId;
@@ -657,7 +657,7 @@
if (n == null) {
// no user -> look for group.
// NOTE: JR < 2.0 always returned groupIDs that didn't contain any
- // illegal JCR chars. Since Group.getID() now unescapes the node
+ // illegal JCR chars. Since Group.getID() 'unescapes' the node
// name additional escaping is required.
Name nodeName = session.getQName(Text.escapeIllegalJcrChars(id));
n = (NodeImpl) authResolver.findNode(nodeName, NT_REP_GROUP);
@@ -668,7 +668,7 @@
return getAuthorizable(n);
}
- private Value getValue(String strValue) throws RepositoryException {
+ private Value getValue(String strValue) {
return session.getValueFactory().createValue(strValue);
}
@@ -757,9 +757,7 @@
* process.</li>
* </ul>
*
- * @param adminId
- * @param pw
- * @return
+ * @return The admin user.
* @throws RepositoryException
*/
private User createAdmin() throws RepositoryException {
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/AbstractUserTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/AbstractUserTest.java?rev=918412&r1=918411&r2=918412&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/AbstractUserTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/AbstractUserTest.java Wed Mar 3 11:13:27 2010
@@ -115,6 +115,10 @@
}
}
+ protected String buildPassword(String uid) {
+ return buildPassword(uid, false);
+ }
+
protected String buildPassword(Principal p) {
return buildPassword(p.getName(), false);
}
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/UserManagerCreateUserTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/UserManagerCreateUserTest.java?rev=918412&r1=918411&r2=918412&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/UserManagerCreateUserTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/UserManagerCreateUserTest.java Wed Mar 3 11:13:27 2010
@@ -32,7 +32,7 @@
private static Logger log = LoggerFactory.getLogger(UserManagerCreateUserTest.class);
- private List<Authorizable> createdUsers = new ArrayList();
+ private List<Authorizable> createdUsers = new ArrayList<Authorizable>();
@Override
protected void tearDown() throws Exception {
@@ -64,7 +64,7 @@
public void testCreateUser() throws RepositoryException, NotExecutableException {
Principal p = getTestPrincipal();
String uid = p.getName();
- User user = createUser(uid, buildPassword(uid, false));
+ User user = createUser(uid, buildPassword(uid));
createdUsers.add(user);
assertNotNull(user.getID());
@@ -74,7 +74,7 @@
public void testCreateUserWithPath() throws RepositoryException, NotExecutableException {
Principal p = getTestPrincipal();
String uid = p.getName();
- User user = createUser(uid, buildPassword(uid, true), p, "/any/path/to/the/new/user");
+ User user = createUser(uid, buildPassword(uid), p, "/any/path/to/the/new/user");
createdUsers.add(user);
assertNotNull(user.getID());
@@ -84,7 +84,7 @@
public void testCreateUserWithPath2() throws RepositoryException, NotExecutableException {
Principal p = getTestPrincipal();
String uid = p.getName();
- User user = createUser(uid, buildPassword(uid, true), p, "any/path");
+ User user = createUser(uid, buildPassword(uid), p, "any/path");
createdUsers.add(user);
assertNotNull(user.getID());
@@ -94,7 +94,7 @@
public void testCreateUserWithDifferentPrincipalName() throws RepositoryException, NotExecutableException {
Principal p = getTestPrincipal();
String uid = getTestPrincipal().getName();
- User user = createUser(uid, buildPassword(uid, true), p, "/any/path/to/the/new/user");
+ User user = createUser(uid, buildPassword(uid), p, "/any/path/to/the/new/user");
createdUsers.add(user);
assertNotNull(user.getID());
@@ -173,7 +173,7 @@
try {
Principal p = getTestPrincipal();
String uid = p.getName();
- User user = createUser(uid, buildPassword(uid, true), null, "/a/b/c");
+ User user = createUser(uid, buildPassword(uid), null, "/a/b/c");
createdUsers.add(user);
fail("A User cannot be built with 'null' Principal");
@@ -186,7 +186,7 @@
try {
Principal p = getTestPrincipal("");
String uid = p.getName();
- User user = createUser(uid, buildPassword(uid, true), p, "/a/b/c");
+ User user = createUser(uid, buildPassword(uid), p, "/a/b/c");
createdUsers.add(user);
fail("A User cannot be built with ''-named Principal");
@@ -196,7 +196,7 @@
try {
Principal p = getTestPrincipal(null);
String uid = p.getName();
- User user = createUser(uid, buildPassword(uid, true), p, "/a/b/c");
+ User user = createUser(uid, buildPassword(uid), p, "/a/b/c");
createdUsers.add(user);
fail("A User cannot be built with ''-named Principal");
@@ -207,11 +207,11 @@
public void testCreateTwiceWithSameUserID() throws RepositoryException, NotExecutableException {
String uid = getTestPrincipal().getName();
- User user = createUser(uid, buildPassword(uid, false));
+ User user = createUser(uid, buildPassword(uid));
createdUsers.add(user);
try {
- User user2 = createUser(uid, buildPassword("anyPW", true));
+ User user2 = createUser(uid, buildPassword("anyPW"));
createdUsers.add(user2);
fail("Creating 2 users with the same UserID should throw AuthorizableExistsException.");
@@ -223,12 +223,12 @@
public void testCreateTwiceWithSamePrincipal() throws RepositoryException, NotExecutableException {
Principal p = getTestPrincipal();
String uid = p.getName();
- User user = createUser(uid, buildPassword(uid, true), p, "a/b/c");
+ User user = createUser(uid, buildPassword(uid), p, "a/b/c");
createdUsers.add(user);
try {
uid = getTestPrincipal().getName();
- User user2 = createUser(uid, buildPassword(uid, false), p, null);
+ User user2 = createUser(uid, buildPassword(uid), p, null);
createdUsers.add(user2);
fail("Creating 2 users with the same Principal should throw AuthorizableExistsException.");
@@ -241,7 +241,7 @@
Principal p = getTestPrincipal();
String uid = p.getName();
- User user = createUser(uid, buildPassword(uid, false));
+ User user = createUser(uid, buildPassword(uid));
createdUsers.add(user);
assertNotNull(userMgr.getAuthorizable(user.getID()));
@@ -264,7 +264,7 @@
Principal p = getTestPrincipal();
String uid = p.getName();
- User user = userMgr.createUser(uid, buildPassword(uid, false));
+ User user = userMgr.createUser(uid, buildPassword(uid));
superuser.refresh(false);
if (!autosave) {
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentialsTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentialsTest.java?rev=918412&r1=918411&r2=918412&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentialsTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentialsTest.java Wed Mar 3 11:13:27 2010
@@ -16,51 +16,125 @@
*/
package org.apache.jackrabbit.core.security.authentication;
-import org.apache.jackrabbit.api.JackrabbitSession;
-import org.apache.jackrabbit.api.security.user.User;
-import org.apache.jackrabbit.api.security.user.UserManager;
-import org.apache.jackrabbit.test.AbstractJCRTest;
-import org.apache.jackrabbit.test.NotExecutableException;
-
-import javax.jcr.Credentials;
import javax.jcr.SimpleCredentials;
+import java.security.NoSuchAlgorithmException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+import org.apache.jackrabbit.util.Text;
/**
* <code>CryptedSimpleCredentialsTest</code>...
*/
-public class CryptedSimpleCredentialsTest extends AbstractJCRTest {
+public class CryptedSimpleCredentialsTest extends TestCase {
- private String userID;
- private CryptedSimpleCredentials creds;
+ private final String userID = "anyUserID";
+ private final String pw = "somePw";
+
+ private SimpleCredentials sCreds;
+ private List<CryptedSimpleCredentials> cCreds = new ArrayList<CryptedSimpleCredentials>();
@Override
protected void setUp() throws Exception {
super.setUp();
- userID = superuser.getUserID();
- if (superuser instanceof JackrabbitSession) {
- UserManager umg = ((JackrabbitSession) superuser).getUserManager();
- User u = (User) umg.getAuthorizable(userID);
- Credentials crd = u.getCredentials();
- if (crd instanceof SimpleCredentials) {
- creds = new CryptedSimpleCredentials((SimpleCredentials) crd);
- } else {
- throw new NotExecutableException();
- }
- } else {
- throw new NotExecutableException();
+ sCreds = new SimpleCredentials(userID, pw.toCharArray());
+ // build crypted credentials from the simple credentials
+ CryptedSimpleCredentials cc = new CryptedSimpleCredentials(sCreds);
+ cCreds.add(cc);
+ // build from uid/pw
+ cCreds.add(new CryptedSimpleCredentials(userID, pw));
+ // build from uid and crypted pw
+ cCreds.add(new CryptedSimpleCredentials(userID, cc.getPassword()));
+ }
+
+ public void testSimpleMatch() throws NoSuchAlgorithmException, UnsupportedEncodingException {
+ for (CryptedSimpleCredentials cc : cCreds) {
+ assertTrue(cc.matches(sCreds));
}
}
public void testUserIDMatchesCaseInsensitive() throws Exception {
String uid = userID.toUpperCase();
- assertTrue(creds.matches(new SimpleCredentials(uid, creds.getPassword().toCharArray())));
+ for (CryptedSimpleCredentials cc : cCreds) {
+ assertTrue(cc.matches(new SimpleCredentials(uid, pw.toCharArray())));
+ }
uid = userID.toLowerCase();
- assertTrue(creds.matches(new SimpleCredentials(uid, creds.getPassword().toCharArray())));
+ for (CryptedSimpleCredentials cc : cCreds) {
+ assertTrue(cc.matches(new SimpleCredentials(uid, pw.toCharArray())));
+ }
}
public void testGetUserID() {
- assertEquals(userID, creds.getUserID());
+ for (CryptedSimpleCredentials cc : cCreds) {
+ assertEquals(userID, cc.getUserID());
+ }
+ }
+
+ public void testGetPassword() throws NoSuchAlgorithmException, UnsupportedEncodingException {
+ CryptedSimpleCredentials prev = null;
+ for (CryptedSimpleCredentials cc : cCreds) {
+ assertFalse(pw.equals(cc.getPassword()));
+ if (prev != null) {
+ assertEquals(prev.getPassword(), cc.getPassword());
+ }
+ prev = cc;
+ }
+
+ // build crypted credentials from the uid and the crypted pw contained
+ // in simple credentials -> simple-c-password must be treated plain-text
+ SimpleCredentials sc = new SimpleCredentials(userID, prev.getPassword().toCharArray());
+ CryptedSimpleCredentials diff = new CryptedSimpleCredentials(sc);
+
+ assertFalse(prev.getPassword().equals(diff.getPassword()));
+ assertFalse(String.valueOf(sc.getPassword()).equals(diff.getPassword()));
+ }
+
+ public void testGetAlgorithm() {
+ CryptedSimpleCredentials prev = null;
+ for (CryptedSimpleCredentials cc : cCreds) {
+ assertNotNull(cc.getAlgorithm());
+ if (prev != null) {
+ assertEquals(prev.getAlgorithm(), cc.getAlgorithm());
+ }
+ prev = cc;
+ }
+ }
+
+ public void testPasswordMatch() throws NoSuchAlgorithmException, UnsupportedEncodingException {
+ // simple credentials containing the crypted pw must not match.
+ SimpleCredentials sc = new SimpleCredentials(userID, cCreds.get(0).getPassword().toCharArray());
+ for (CryptedSimpleCredentials cc : cCreds) {
+ assertFalse(cc.matches(sc));
+ }
+
+ // simple credentials containing different pw must not match.
+ SimpleCredentials sc2 = new SimpleCredentials(userID, "otherPw".toCharArray());
+ for (CryptedSimpleCredentials cc : cCreds) {
+ assertFalse(cc.matches(sc2));
+ }
+
+ // simple credentials with pw in digested form must not match.
+ SimpleCredentials sc3 = new SimpleCredentials(userID, "{unknown}somePw".toCharArray());
+ for (CryptedSimpleCredentials cc : cCreds) {
+ assertFalse(cc.matches(sc3));
+ }
+
+ // simple credentials with pw with different digest must not match
+ SimpleCredentials sc4 = new SimpleCredentials(userID, ("{md5}"+Text.digest("md5", pw.getBytes("UTF-8"))).toCharArray());
+ for (CryptedSimpleCredentials cc : cCreds) {
+ assertFalse(cc.matches(sc4));
+ }
+ }
+
+ public void testUserIdMatch() throws NoSuchAlgorithmException, UnsupportedEncodingException {
+ // simple credentials containing a different uid must not match
+ SimpleCredentials sc = new SimpleCredentials("another", pw.toCharArray());
+ for (CryptedSimpleCredentials cc : cCreds) {
+ assertFalse(cc.matches(sc));
+ }
}
}
\ No newline at end of file
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/AuthorizableImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/AuthorizableImplTest.java?rev=918412&r1=918411&r2=918412&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/AuthorizableImplTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/AuthorizableImplTest.java Wed Mar 3 11:13:27 2010
@@ -46,9 +46,10 @@
*/
public class AuthorizableImplTest extends AbstractUserTest {
- private List<String> protectedUserProps = new ArrayList();
- private List<String> protectedGroupProps = new ArrayList();
+ private List<String> protectedUserProps = new ArrayList<String>();
+ private List<String> protectedGroupProps = new ArrayList<String>();
+ @Override
protected void setUp() throws Exception {
super.setUp();
@@ -313,7 +314,7 @@
assertEquals(user, user2);
assertEquals(user.hashCode(), user2.hashCode());
- Set<Authorizable> s = new HashSet();
+ Set<Authorizable> s = new HashSet<Authorizable>();
s.add(user);
assertFalse(s.add(user2));
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImplTest.java?rev=918412&r1=918411&r2=918412&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImplTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImplTest.java Wed Mar 3 11:13:27 2010
@@ -20,11 +20,11 @@
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.core.security.SecurityConstants;
import org.apache.jackrabbit.core.security.authentication.CryptedSimpleCredentials;
import org.apache.jackrabbit.test.NotExecutableException;
+import org.apache.jackrabbit.util.Text;
import org.apache.jackrabbit.value.StringValue;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import javax.jcr.Credentials;
import javax.jcr.RepositoryException;
@@ -34,19 +34,20 @@
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
+import java.util.HashMap;
+import java.util.Map;
/**
* <code>UserImplTest</code>...
*/
public class UserImplTest extends AbstractUserTest {
- private static Logger log = LoggerFactory.getLogger(UserImplTest.class);
-
private String uID;
private Credentials creds;
private Session uSession;
private UserManager uMgr;
+ @Override
protected void setUp() throws Exception {
super.setUp();
@@ -62,6 +63,7 @@
uMgr = getUserManager(uSession);
}
+ @Override
protected void tearDown() throws Exception {
try {
userMgr.getAuthorizable(uID).remove();
@@ -120,23 +122,64 @@
assertNull(u.getProperty(propertyName1));
}
+ public void testCredentials() throws RepositoryException, NoSuchAlgorithmException, UnsupportedEncodingException {
+ User u = (User) userMgr.getAuthorizable(uID);
+
+ Credentials uc = u.getCredentials();
+ assertTrue(uc instanceof CryptedSimpleCredentials);
+ assertTrue(((CryptedSimpleCredentials) uc).matches((SimpleCredentials) creds));
+ }
+
public void testChangePassword() throws RepositoryException, NotExecutableException, NoSuchAlgorithmException, UnsupportedEncodingException {
- String oldPw = getHelper().getProperty("javax.jcr.tck.superuser.pwd");
- if (oldPw == null) {
- // missing property
- throw new NotExecutableException();
+ User u = (User) userMgr.getAuthorizable(uID);
+
+ String sha1Hash = "{" +SecurityConstants.DEFAULT_DIGEST+ "}" + Text.digest(SecurityConstants.DEFAULT_DIGEST, "abc".getBytes());
+ String md5Hash = "{md5}" + Text.digest("md5", "abc".getBytes());
+
+ // valid passwords and the corresponding match
+ Map<String,String> pwds = new HashMap<String, String>();
+ // plain text passwords
+ pwds.put("abc", "abc");
+ pwds.put("{a}password", "{a}password");
+ // passwords already in hashed format.
+ pwds.put(sha1Hash, "abc");
+ pwds.put(md5Hash, "abc");
+
+ for (String pw : pwds.keySet()) {
+ u.changePassword(pw);
+
+ String plain = pwds.get(pw);
+ SimpleCredentials sc = new SimpleCredentials(u.getID(), plain.toCharArray());
+ CryptedSimpleCredentials cc = (CryptedSimpleCredentials) u.getCredentials();
+
+ assertTrue(cc.matches(sc));
}
- User user = getTestUser(superuser);
- try {
- user.changePassword("pw");
- save(superuser);
+ // valid passwords, non-matching plain text
+ Map<String, String>noMatch = new HashMap<String, String>();
+ noMatch.put("{"+SecurityConstants.DEFAULT_DIGEST+"}", "");
+ noMatch.put("{"+SecurityConstants.DEFAULT_DIGEST+"}", "{"+SecurityConstants.DEFAULT_DIGEST+"}");
+ noMatch.put("{"+SecurityConstants.DEFAULT_DIGEST+"}any", "any");
+ noMatch.put("{"+SecurityConstants.DEFAULT_DIGEST+"}any", "{"+SecurityConstants.DEFAULT_DIGEST+"}any");
+ noMatch.put(sha1Hash, sha1Hash);
+ noMatch.put(md5Hash, md5Hash);
+
+ for (String pw : noMatch.keySet()) {
+ u.changePassword(pw);
+
+ String plain = noMatch.get(pw);
+ SimpleCredentials sc = new SimpleCredentials(u.getID(), plain.toCharArray());
+ CryptedSimpleCredentials cc = (CryptedSimpleCredentials) u.getCredentials();
- SimpleCredentials creds = new SimpleCredentials(user.getID(), "pw".toCharArray());
- assertTrue(((CryptedSimpleCredentials) user.getCredentials()).matches(creds));
- } finally {
- user.changePassword(oldPw);
- save(superuser);
+ assertFalse(cc.matches(sc));
+ }
+
+ // invalid pw string
+ try {
+ u.changePassword(null);
+ fail("invalid pw null");
+ } catch (Exception e) {
+ // success
}
}
}
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserManagerImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserManagerImplTest.java?rev=918412&r1=918411&r2=918412&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserManagerImplTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserManagerImplTest.java Wed Mar 3 11:13:27 2010
@@ -45,6 +45,7 @@
private String pPrincipalName;
+ @Override
protected void setUp() throws Exception {
super.setUp();
if (!(userMgr instanceof UserManagerImpl)) {
@@ -107,7 +108,7 @@
public void testCreateUserIdDifferentFromPrincipalName() throws RepositoryException, NotExecutableException {
Principal p = getTestPrincipal();
String uid = getTestUserId(p);
- String pw = buildPassword(uid, true);
+ String pw = buildPassword(uid);
User u = null;
Session uSession = null;
@@ -142,7 +143,7 @@
User u = null;
Group gr = null;
try {
- u = userMgr.createUser(uid, buildPassword(uid, true), p, null);
+ u = userMgr.createUser(uid, buildPassword(uid), p, null);
save(superuser);
gr = userMgr.createGroup(new TestPrincipal(uid));
save(superuser);
@@ -177,7 +178,7 @@
// the result must contain 1 authorizable
assertTrue(users.hasNext());
- Authorizable first = (Authorizable) users.next();
+ Authorizable first = users.next();
assertEquals(first.getID(), val);
// since id is unique -> there should be no more users in
@@ -221,7 +222,7 @@
try {
Principal p = getTestPrincipal();
String uid = "UID" + p.getName();
- u = userMgr.createUser(uid, buildPassword(uid, false), p, null);
+ u = userMgr.createUser(uid, buildPassword(uid), p, null);
save(superuser);
boolean found = false;
@@ -246,7 +247,7 @@
it = userMgr.findAuthorizables(pPrincipalName, null, UserManager.SEARCH_TYPE_GROUP);
while (it.hasNext()) {
- if (((Authorizable) it.next()).getPrincipal().getName().equals(p.getName())) {
+ if (it.next().getPrincipal().getName().equals(p.getName())) {
fail("Searching for Groups should never find a user");
}
}
@@ -285,7 +286,7 @@
it = userMgr.findAuthorizables(pPrincipalName, null, UserManager.SEARCH_TYPE_USER);
while (it.hasNext()) {
- if (((Authorizable) it.next()).getPrincipal().getName().equals(p.getName())) {
+ if (it.next().getPrincipal().getName().equals(p.getName())) {
fail("Searching for Users should never find a group");
}
}
@@ -313,7 +314,7 @@
public void testNewUserCanLogin() throws RepositoryException, NotExecutableException {
String uid = getTestPrincipal().getName();
- String pw = buildPassword(uid, false);
+ String pw = buildPassword(uid);
User u = null;
Session s = null;
@@ -476,13 +477,13 @@
String usersPath = ((UserManagerImpl) userMgr).getUsersPath();
- List<String> invalid = new ArrayList();
+ List<String> invalid = new ArrayList<String>();
invalid.add("../../path");
invalid.add(usersPath + "/../test");
for (String path : invalid) {
try {
- User user = userMgr.createUser(uid, buildPassword(uid, true), p, path);
+ User user = userMgr.createUser(uid, buildPassword(uid), p, path);
save(superuser);
fail("intermediate path may not point outside of the user tree.");
@@ -495,4 +496,4 @@
}
}
}
-}
\ No newline at end of file
+}