blob: 155084e35628d96222b2ae899bed07652e0d27c1 [file] [log] [blame]
/**
* 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.felix.useradmin.impl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import junit.framework.TestCase;
import org.apache.felix.useradmin.RoleRepositoryStore;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkUtil;
import org.osgi.service.useradmin.Group;
import org.osgi.service.useradmin.Role;
import org.osgi.service.useradmin.User;
/**
* Tests whether using custom roles in the backend work as expected and yield the proper events.
*
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class CustomRoleImplTest extends TestCase
{
static class MyGroupImpl extends MyUserImpl implements Group {
private final Map m_members;
private final Map m_requiredMembers;
public MyGroupImpl(String name) {
super(name, GROUP);
m_members = new HashMap();
m_requiredMembers = new HashMap();
}
public boolean addMember(Role role) {
String name = role.getName();
if (m_requiredMembers.containsKey(name) || m_members.containsKey(name)) {
return false;
}
return m_members.put(name, role) == null;
}
public boolean addRequiredMember(Role role) {
String name = role.getName();
if (m_requiredMembers.containsKey(name) || m_members.containsKey(name)) {
return false;
}
return m_requiredMembers.put(name, role) == null;
}
public Role[] getMembers() {
Role[] result = new Role[m_members.size()];
return (Role[]) m_members.values().toArray(result);
}
public Role[] getRequiredMembers() {
Role[] result = new Role[m_requiredMembers.size()];
return (Role[]) m_requiredMembers.values().toArray(result);
}
public boolean removeMember(Role role) {
String name = role.getName();
if (m_requiredMembers.remove(name) != null) {
return true;
} else if (m_members.remove(name) != null) {
return true;
}
return false;
}
}
static class MyRoleImpl implements Role {
private final String m_name;
private final int m_type;
private final Hashtable m_props;
public MyRoleImpl(String name, int type) {
m_name = name;
m_type = type;
m_props = new Hashtable();
}
public String getName() {
return m_name;
}
public Dictionary getProperties() {
return m_props;
}
public int getType() {
return m_type;
}
}
static class MyRoleRepositoryStore implements RoleRepositoryStore {
private final ConcurrentMap m_entries = new ConcurrentHashMap();
public Role addRole(String roleName, int type) throws IOException {
if (roleName == null) {
throw new IllegalArgumentException("Name cannot be null!");
}
Role role = createRole(roleName, type);
Object result = m_entries.putIfAbsent(roleName, role);
return (result == null) ? role : null;
}
public Role getRoleByName(String roleName) throws Exception {
if (roleName == null) {
throw new IllegalArgumentException("Role name cannot be null!");
}
return (Role) m_entries.get(roleName);
}
public Role[] getRoles(String filterValue) throws Exception {
Collection roles = m_entries.values();
Filter filter = null;
if (filterValue != null) {
filter = FrameworkUtil.createFilter(filterValue);
}
List matchingRoles = new ArrayList();
Iterator rolesIter = roles.iterator();
while (rolesIter.hasNext()) {
Role role = (Role) rolesIter.next();
if ((filter == null) || filter.match(role.getProperties())) {
matchingRoles.add(role);
}
}
Role[] result = new Role[matchingRoles.size()];
return (Role[]) matchingRoles.toArray(result);
}
public Role removeRole(String roleName) throws Exception {
if (roleName == null) {
throw new IllegalArgumentException("Name cannot be null!");
}
Role role = getRoleByName(roleName);
boolean result = m_entries.remove(roleName, role);
return result ? role : null;
}
private Role createRole(String roleName, int type) {
Role role;
if (type == Role.USER) {
role = new MyUserImpl(roleName);
} else if (type == Role.GROUP) {
role = new MyGroupImpl(roleName);
} else {
throw new IllegalArgumentException("Invalid role type!");
}
return role;
}
}
static class MyUserImpl extends MyRoleImpl implements User {
private final Hashtable m_creds;
public MyUserImpl(String name) {
this(name, USER);
}
protected MyUserImpl(String name, int type) {
super(name, type);
m_creds = new Hashtable();
}
public Dictionary getCredentials() {
return m_creds;
}
public boolean hasCredential(String key, Object value) {
if (m_creds.containsKey(key)) {
Object v = m_creds.get(key);
return ((v == value) || ((v != null) && v.equals(value)));
}
return false;
}
}
private CountDownLatch m_latch;
private RoleRepository m_repository;
/**
* Tests that adding a basic member to a group-role yields an event.
*/
public void testAddBasicGroupMemberYieldsEvent() throws Exception {
final Group role = (Group) m_repository.addRole("testGroup", Role.GROUP);
assertNotNull(role);
m_latch = new CountDownLatch(1);
new Thread(new Runnable() {
public void run() {
Role anyone = m_repository.getRoleByName(Role.USER_ANYONE);
assertTrue(role.addMember(anyone));
};
}).start();
assertTrue(m_latch.await(1, TimeUnit.SECONDS));
}
/**
* Tests that adding an existing role does not yield an event.
*/
public void testAddExistingRoleDoesNotYieldEvent() throws Exception {
assertNotNull(m_repository.addRole("testUser", Role.USER));
m_latch = new CountDownLatch(1);
new Thread(new Runnable() {
public void run() {
assertNull(m_repository.addRole("testUser", Role.USER));
};
}).start();
assertFalse(m_latch.await(1, TimeUnit.SECONDS));
}
/**
* Tests that adding a new role yields an event.
*/
public void testAddNewRoleYieldsEvent() throws Exception {
m_latch = new CountDownLatch(1);
new Thread(new Runnable() {
public void run() {
assertNotNull(m_repository.addRole("testUser", Role.USER));
};
}).start();
assertTrue(m_latch.await(1, TimeUnit.SECONDS));
}
/**
* Tests that adding a required member to a group-role yields an event.
*/
public void testAddRequiredGroupMemberYieldsEvent() throws Exception {
final Group role = (Group) m_repository.addRole("testGroup", Role.GROUP);
assertNotNull(role);
m_latch = new CountDownLatch(1);
new Thread(new Runnable() {
public void run() {
Role anyone = m_repository.getRoleByName(Role.USER_ANYONE);
assertTrue(role.addRequiredMember(anyone));
};
}).start();
assertTrue(m_latch.await(100, TimeUnit.SECONDS));
}
/**
* Tests that changing the properties of a user-role yields an event.
*/
public void testAddRolePropertiesYieldsEvent() throws Exception {
final Role role = m_repository.addRole("testUser", Role.USER);
assertNotNull(role);
m_latch = new CountDownLatch(1);
new Thread(new Runnable() {
public void run() {
role.getProperties().put("key", "value");
};
}).start();
assertTrue(m_latch.await(1, TimeUnit.SECONDS));
}
/**
* Tests that changing the credentials of a user-role yields an event.
*/
public void testAddUserCredentialsYieldsEvent() throws Exception {
final User role = (User) m_repository.addRole("testUser", Role.USER);
assertNotNull(role);
m_latch = new CountDownLatch(1);
new Thread(new Runnable() {
public void run() {
role.getCredentials().put("key", "value");
};
}).start();
assertTrue(m_latch.await(1, TimeUnit.SECONDS));
}
/**
* Tests that changing the credentials of a user-role yields an event.
*/
public void testChangePropertiesYieldsEvent() throws Exception {
final Role role = m_repository.addRole("testUser", Role.USER);
role.getProperties().put("key", "value1");
assertNotNull(role);
m_latch = new CountDownLatch(1);
new Thread(new Runnable() {
public void run() {
role.getProperties().put("key", "value2");
};
}).start();
assertTrue(m_latch.await(1, TimeUnit.SECONDS));
}
/**
* Tests that changing the credentials of a user-role yields an event.
*/
public void testChangeUserCredentialsYieldsEvent() throws Exception {
final User role = (User) m_repository.addRole("testUser", Role.USER);
role.getCredentials().put("key", "value1");
assertNotNull(role);
m_latch = new CountDownLatch(1);
new Thread(new Runnable() {
public void run() {
role.getCredentials().put("key", "value2");
};
}).start();
assertTrue(m_latch.await(1, TimeUnit.SECONDS));
}
/**
* Tests that removing an existing role does yield an event.
*/
public void testRemoveExistingRoleYieldsEvent() throws Exception {
assertNotNull(m_repository.addRole("testUser", Role.USER));
m_latch = new CountDownLatch(1);
new Thread(new Runnable() {
public void run() {
assertTrue(m_repository.removeRole("testUser"));
};
}).start();
assertTrue(m_latch.await(1, TimeUnit.SECONDS));
}
/**
* Tests that removing a non-existing role does not yield an event.
*/
public void testRemoveNonExistingRoleDoesNotYieldEvent() throws Exception {
m_latch = new CountDownLatch(1);
new Thread(new Runnable() {
public void run() {
assertFalse(m_repository.removeRole("testUser"));
};
}).start();
assertFalse(m_latch.await(1, TimeUnit.SECONDS));
}
/**
* Tests that changing the properties of a user-role yields an event.
*/
public void testRemoveRolePropertiesYieldsEvent() throws Exception {
final Role role = m_repository.addRole("testUser", Role.USER);
role.getProperties().put("key", "value");
assertNotNull(role);
m_latch = new CountDownLatch(1);
new Thread(new Runnable() {
public void run() {
role.getProperties().remove("key");
};
}).start();
assertTrue(m_latch.await(1, TimeUnit.SECONDS));
}
/**
* Tests that changing the credentials of a user-role yields an event.
*/
public void testRemoveUserCredentialsYieldsEvent() throws Exception {
final User role = (User) m_repository.addRole("testUser", Role.USER);
role.getCredentials().put("key", "value");
assertNotNull(role);
m_latch = new CountDownLatch(1);
new Thread(new Runnable() {
public void run() {
role.getCredentials().remove("key");
};
}).start();
assertTrue(m_latch.await(1, TimeUnit.SECONDS));
}
/**
* Tests that removing a member from a group-role yields an event.
*/
public void testRemovingGroupMemberYieldsEvent() throws Exception {
final Role anyone = m_repository.getRoleByName(Role.USER_ANYONE);
final Group role = (Group) m_repository.addRole("testGroup", Role.GROUP);
assertNotNull(role);
role.addRequiredMember(anyone);
m_latch = new CountDownLatch(1);
new Thread(new Runnable() {
public void run() {
assertTrue(role.removeMember(anyone));
};
}).start();
assertTrue(m_latch.await(100, TimeUnit.SECONDS));
}
/**
* Set up for all test cases.
*/
protected void setUp() throws Exception
{
m_repository = new RoleRepository(new MyRoleRepositoryStore());
m_repository.addRoleChangeListener(new RoleChangeListener() {
public void propertyAdded(Role role, Object key, Object value) {
if (m_latch != null) {
m_latch.countDown();
}
}
public void propertyChanged(Role role, Object key, Object oldValue, Object newValue) {
if (m_latch != null) {
m_latch.countDown();
}
}
public void propertyRemoved(Role role, Object key) {
if (m_latch != null) {
m_latch.countDown();
}
}
public void roleAdded(Role role) {
if (m_latch != null) {
m_latch.countDown();
}
}
public void roleRemoved(Role role) {
if (m_latch != null) {
m_latch.countDown();
}
}
});
}
}