/**
* Licensed to the Austrian Association for Software Tool Integration (AASTI)
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. The AASTI 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.openengsb.core.services.internal.security;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.openengsb.core.api.security.model.Permission;
import org.openengsb.core.api.security.service.PermissionSetNotFoundException;
import org.openengsb.core.api.security.service.UserDataManager;
import org.openengsb.core.api.security.service.UserExistsException;
import org.openengsb.core.api.security.service.UserNotFoundException;
import org.openengsb.core.services.internal.security.model.EntryElement;
import org.openengsb.core.services.internal.security.model.EntryValue;
import org.openengsb.core.services.internal.security.model.PermissionData;
import org.openengsb.core.services.internal.security.model.PermissionSetData;
import org.openengsb.core.services.internal.security.model.UserData;
import org.openengsb.core.services.internal.security.model.UserPermissionSetData;
import org.openengsb.core.util.CollectionUtilsExtended;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
public class UserDataManagerImpl implements UserDataManager {
private static final Logger LOGGER = LoggerFactory.getLogger(UserDataManagerImpl.class);
private EntityManager entityManager;
public UserDataManagerImpl() {
}
@Override
public Collection<String> getUserList() {
synchronized (entityManager) {
TypedQuery<String> query = entityManager.createQuery("SELECT u.username from UserData u", String.class);
return query.getResultList();
}
}
@Override
public void createUser(String username) throws UserExistsException {
UserData newUser = new UserData();
newUser.setUsername(username);
UserPermissionSetData permissionSetData = new UserPermissionSetData(username);
newUser.setPermissionSet(permissionSetData);
synchronized (entityManager) {
entityManager.persist(newUser);
}
}
@Override
public void deleteUser(String username) {
UserData found;
try {
found = doFindUser(username);
} catch (UserNotFoundException e) {
LOGGER.warn("user {} was to be deleted, but not found", username);
return;
}
synchronized (entityManager) {
entityManager.remove(found);
}
}
@Override
public String getUserCredentials(String username, final String key) throws UserNotFoundException {
UserData found = doFindUser(username);
return found.getCredentials().get(key);
}
@Override
public void setUserCredentials(String username, String type, String value) throws UserNotFoundException {
UserData found = doFindUser(username);
found.getCredentials().put(type, value);
synchronized (entityManager) {
entityManager.merge(found);
}
}
@Override
public void removeUserCredentials(String username, String type) throws UserNotFoundException {
UserData found = doFindUser(username);
found.getCredentials().remove(type);
synchronized (entityManager) {
entityManager.merge(found);
}
}
@Override
public List<Object> getUserAttribute(String username, String attributename) throws UserNotFoundException {
UserData user = doFindUser(username);
EntryValue entryValue = user.getAttributes().get(attributename);
if (entryValue == null) {
return null;
}
List<EntryElement> value = entryValue.getValue();
return EntryUtils.convertAllEntryElementsToObject(value);
}
@Override
public void setUserAttribute(String username, String attributename, Object... value) throws UserNotFoundException {
UserData user = doFindUser(username);
EntryValue entryValue = new EntryValue();
entryValue.setKey(attributename);
List<EntryElement> entryElementList = EntryUtils.makeEntryElementList(value);
entryValue.setValue(entryElementList);
user.getAttributes().put(attributename, entryValue);
synchronized (entityManager) {
entityManager.merge(user);
}
}
@Override
public void removeUserAttribute(String username, String attributename) throws UserNotFoundException {
UserData user = doFindUser(username);
EntryValue entryValue = user.getAttributes().get(attributename);
if (entryValue == null) {
// silently fail if attribute is not present
LOGGER.warn("user does not have attribute, " + attributename);
return;
}
user.getAttributes().remove(attributename);
synchronized (entityManager) {
entityManager.merge(user);
}
}
@Override
public Collection<Permission> getPermissionsForUser(String username) throws UserNotFoundException {
UserData user = doFindUser(username);
return getPermissionsFromSetData(user.getPermissionSet());
}
@Override
public Collection<Permission> getAllPermissionsForUser(String username) throws UserNotFoundException {
UserData user = doFindUser(username);
return getAllPermissionsFromSetData(user.getPermissionSet());
}
@Override
public <T extends Permission> Collection<T> getPermissionsForUser(String username, Class<T> type)
throws UserNotFoundException {
// TODO improve performance with proper query.
return CollectionUtilsExtended.filterCollectionByClass(getPermissionsForUser(username), type);
}
@Override
public <T extends Permission> Collection<T> getAllPermissionsForUser(String username, Class<T> type)
throws UserNotFoundException {
// TODO improve performance with proper query.
return CollectionUtilsExtended.filterCollectionByClass(getAllPermissionsForUser(username), type);
}
@Override
public void addPermissionToUser(String username, Permission... permission) throws UserNotFoundException {
UserData user = doFindUser(username);
addPermissionsToSet(user.getPermissionSet(), permission);
}
private static PermissionData convertPermissionToPermissionData(Permission permission) {
PermissionData permissionData = new PermissionData();
String type = permission.getClass().getName();
permissionData.setType(type);
Map<String, EntryValue> entryMap = EntryUtils.convertBeanToEntryMap(permission);
// copy the map, because JPA does not like the transformed map for some reason
entryMap = Maps.newHashMap(entryMap);
permissionData.setAttributes(entryMap);
return permissionData;
}
@Override
public void removePermissionFromUser(String username, final Permission... permission) throws UserNotFoundException {
UserData user = doFindUser(username);
doRemovePermissionsFromSet(user.getPermissionSet(), permission);
}
@Override
public Collection<String> getPermissionSetList() {
synchronized (entityManager) {
TypedQuery<String> query = entityManager.createQuery("SELECT s.id from PermissionSetData s", String.class);
return query.getResultList();
}
}
@Override
public void createPermissionSet(String permissionSet, Permission... permission) {
PermissionSetData data = new PermissionSetData(permissionSet);
if (permission != null) {
Collection<PermissionData> permissions = data.getPermissions();
for (Permission p : permission) {
permissions.add(convertPermissionToPermissionData(p));
}
}
synchronized (entityManager) {
entityManager.persist(data);
}
}
@Override
public Collection<String> getPermissionSetsFromUser(String username) throws UserNotFoundException {
UserData user = doFindUser(username);
Collection<PermissionSetData> permissionSets = user.getPermissionSet().getPermissionSets();
return Collections2.transform(permissionSets, new Function<PermissionSetData, String>() {
@Override
public String apply(PermissionSetData input) {
return input.getName();
}
});
}
@Override
public void addPermissionSetToUser(String username, String... permissionSet) throws UserNotFoundException {
UserData user = doFindUser(username);
doAddPermissionSetToSet(user.getPermissionSet(), permissionSet);
}
@Override
public void removePermissionSetFromUser(String username, String... permissionSet) throws UserNotFoundException {
UserData user = doFindUser(username);
doRemovePermissionSetFromSet(user.getPermissionSet(), permissionSet);
}
@Override
public void addPermissionSetToPermissionSet(String permissionSetParent, String... permissionSet) {
PermissionSetData parent = doFindPermissionSet(permissionSetParent);
doAddPermissionSetToSet(parent, permissionSet);
}
@Override
public Collection<String> getPermissionSetsFromPermissionSet(String permissionSet) throws UserNotFoundException {
PermissionSetData parent = doFindPermissionSet(permissionSet);
return Collections2.transform(parent.getPermissionSets(), new Function<PermissionSetData, String>() {
@Override
public String apply(PermissionSetData input) {
return input.getName();
}
});
}
@Override
public void removePermissionSetFromPermissionSet(String permissionSetParent, String... permissionSet) {
PermissionSetData parent = doFindPermissionSet(permissionSetParent);
doRemovePermissionSetFromSet(parent, permissionSet);
}
@Override
public Collection<Permission> getPermissionsFromPermissionSet(String permissionSet) {
PermissionSetData set = doFindPermissionSet(permissionSet);
return getPermissionsFromSetData(set);
}
@Override
public Collection<Permission> getAllPermissionsFromPermissionSet(String permissionSet) {
PermissionSetData set = doFindPermissionSet(permissionSet);
return getAllPermissionsFromSetData(set);
}
@Override
public void addPermissionToSet(String permissionSet, Permission... permission) {
PermissionSetData set = doFindPermissionSet(permissionSet);
addPermissionsToSet(set, permission);
}
private void addPermissionsToSet(PermissionSetData set, Permission... permission) {
for (Permission p : permission) {
PermissionData data = convertPermissionToPermissionData(p);
set.getPermissions().add(data);
}
synchronized (entityManager) {
entityManager.merge(set);
}
}
@Override
public void removePermissionFromSet(String permissionSet, Permission... permission) {
PermissionSetData set = doFindPermissionSet(permissionSet);
doRemovePermissionsFromSet(set, permission);
}
@Override
public String getPermissionSetAttribute(String permissionSet, String attributename) {
return doFindPermissionSet(permissionSet).getMetadata().get(attributename);
}
@Override
public void setPermissionSetAttribute(String permissionSet, String attributename, String value) {
doFindPermissionSet(permissionSet).getMetadata().put(attributename, value);
}
private void doAddPermissionSetToSet(PermissionSetData parent, String... permissionSet) {
for (String p : permissionSet) {
PermissionSetData child = doFindPermissionSet(p);
parent.getPermissionSets().add(child);
}
synchronized (entityManager) {
entityManager.merge(parent);
}
}
private void doRemovePermissionSetFromSet(PermissionSetData parent, String... permissionSet) {
for (String p : permissionSet) {
PermissionSetData child = doFindPermissionSet(p);
parent.getPermissionSets().remove(child);
}
synchronized (entityManager) {
entityManager.merge(parent);
}
}
private Collection<Permission> getPermissionsFromSetData(PermissionSetData set) {
Collection<PermissionData> data = set.getPermissions();
return EntryUtils.convertAllBeanDataToObjects(data);
}
private Collection<Permission> getAllPermissionsFromSetData(PermissionSetData set) {
Collection<Permission> result = Sets.newHashSet(getPermissionsFromSetData(set));
for (PermissionSetData child : set.getPermissionSets()) {
result.addAll(getAllPermissionsFromPermissionSet(child.getName()));
}
return result;
}
private void doRemovePermissionsFromSet(PermissionSetData set, Permission... permission) {
for (Permission p : permission) {
PermissionData data = convertPermissionToPermissionData(p);
set.getPermissions().remove(data);
}
synchronized (entityManager) {
entityManager.merge(set);
}
}
private UserData doFindUser(String username) throws UserNotFoundException {
synchronized (entityManager) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<UserData> query = cb.createQuery(UserData.class);
Root<UserData> from = query.from(UserData.class);
query.where(cb.equal(from.get("username"), username));
query.select(from);
try {
UserData found = entityManager.createQuery(query).getSingleResult();
return found;
} catch (Exception ex) {
throw new UserNotFoundException("User with name " + username + " not found");
}
}
}
private PermissionSetData doFindPermissionSet(String permissionSet) throws PermissionSetNotFoundException {
synchronized (entityManager) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<PermissionSetData> query = cb.createQuery(PermissionSetData.class);
Root<PermissionSetData> from = query.from(PermissionSetData.class);
query.where(cb.equal(from.get("name"), permissionSet));
query.select(from);
try {
PermissionSetData found = entityManager.createQuery(query).getSingleResult();
return found;
} catch (Exception ex) {
throw new PermissionSetNotFoundException("permissionSet " + permissionSet + " not found");
}
}
}
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
}