/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.jackrabbit.core.security.user;
import org.apache.jackrabbit.api.security.user.AbstractUserTest;
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 javax.jcr.Credentials;
import javax.jcr.LoginException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.Value;
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 String uID;
private Credentials creds;
private Session uSession;
private UserManager uMgr;
@Override
protected void setUp() throws Exception {
super.setUp();
Principal p = getTestPrincipal();
String pw = buildPassword(p);
creds = new SimpleCredentials(p.getName(), pw.toCharArray());
User u = userMgr.createUser(p.getName(), pw);
save(superuser);
uID = u.getID();
uSession = getHelper().getRepository().login(creds);
uMgr = getUserManager(uSession);
}
@Override
protected void tearDown() throws Exception {
try {
userMgr.getAuthorizable(uID).remove();
save(superuser);
} finally {
uSession.logout();
}
super.tearDown();
}
public void testUserImplHasCryptedSimplCredentials() throws RepositoryException, NotExecutableException {
User user = getTestUser(superuser);
Credentials creds = user.getCredentials();
assertNotNull(creds);
assertTrue(creds instanceof CryptedSimpleCredentials);
assertEquals(((CryptedSimpleCredentials) creds).getUserID(), user.getID());
}
public void testIsUser() throws RepositoryException {
Authorizable auth = uMgr.getAuthorizable(uID);
assertFalse(auth.isGroup());
}
public void testUserCanModifyItsOwnProperties() throws RepositoryException, NotExecutableException {
User u = (User) uMgr.getAuthorizable(uID);
if (u == null) {
fail("User " +uID+ "hast not been removed and must be visible to the Session created with its credentials.");
}
if (!uSession.hasPermission(((UserImpl) u).getNode().getPath(), "set_property")) {
throw new NotExecutableException("Users should be able to modify their properties -> Check repository config.");
}
// single valued properties
u.setProperty("Email", new StringValue("tu@security.test"));
save(uSession);
assertNotNull(u.getProperty("Email"));
assertEquals("tu@security.test", u.getProperty("Email")[0].getString());
u.removeProperty("Email");
save(uSession);
assertNull(u.getProperty("Email"));
// multivalued properties
u.setProperty(propertyName1, new Value[] {uSession.getValueFactory().createValue("anyValue")});
save(uSession);
assertNotNull(u.getProperty(propertyName1));
u.removeProperty(propertyName1);
save(uSession);
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 {
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 with hash-like char-sequence -> must still be hashed.
pwds.put(sha1Hash, sha1Hash);
pwds.put(md5Hash, md5Hash);
pwds.put("{"+SecurityConstants.DEFAULT_DIGEST+"}any", "{"+SecurityConstants.DEFAULT_DIGEST+"}any");
pwds.put("{"+SecurityConstants.DEFAULT_DIGEST+"}", "{"+SecurityConstants.DEFAULT_DIGEST+"}");
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));
}
// valid passwords, non-matching plain text
Map<String, String>noMatch = new HashMap<String, String>();
noMatch.put("{"+SecurityConstants.DEFAULT_DIGEST+"}", "");
noMatch.put("{"+SecurityConstants.DEFAULT_DIGEST+"}any", "any");
noMatch.put(sha1Hash, "abc");
noMatch.put(md5Hash, "abc");
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();
assertFalse(pw, cc.matches(sc));
}
}
public void testChangePasswordNull() throws RepositoryException {
User u = (User) userMgr.getAuthorizable(uID);
// invalid 'null' pw string
try {
u.changePassword(null);
fail("invalid pw null");
} catch (Exception e) {
// success
}
}
public void testLoginWithCryptedCredentials() throws RepositoryException {
User u = (User) uMgr.getAuthorizable(uID);
Credentials creds = u.getCredentials();
assertTrue(creds instanceof CryptedSimpleCredentials);
try {
Session s = getHelper().getRepository().login(u.getCredentials());
s.logout();
fail("Login using CryptedSimpleCredentials must fail.");
} catch (LoginException e) {
// success
}
}
}