/**
* 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.usersync.impl;
import java.util.ArrayList;
import java.util.List;
import org.openengsb.core.api.context.ContextHolder;
import org.openengsb.core.api.model.QueryRequest;
import org.openengsb.core.api.security.AuthenticationContext;
import org.openengsb.core.ekb.api.EKBCommit;
import org.openengsb.core.ekb.api.PersistInterface;
import org.openengsb.core.ekb.api.QueryInterface;
import org.openengsb.core.usersync.DataSynchronizer;
import org.openengsb.core.usersync.exception.SynchronizationException;
import org.openengsb.domain.userprojects.model.Assignment;
import org.openengsb.domain.userprojects.model.Permission;
import org.openengsb.domain.userprojects.model.Project;
import org.openengsb.domain.userprojects.model.Role;
import org.openengsb.domain.userprojects.model.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
/**
* This service implementation stores the given user-data into the EKB via the {@link PersistInterface}.
*/
public class EkbDataSynchronizer implements DataSynchronizer {
private static final Logger LOGGER = LoggerFactory.getLogger(UserManagerDataSynchronizer.class);
private String currentContext;
private AuthenticationContext authenticationContext;
private PersistInterface persistService;
private QueryInterface queryService;
@Override
public void checkinUsers(List<User> users) {
EKBCommit commit = getEKBCommit();
preparePersistenceAccess();
for (User user : users) {
List<User> result = queryService.query(User.class, QueryRequest.query("username", user.getUsername()));
if (result.size() == 0) {
LOGGER.info("Create User " + user.getUsername());
commit.addInsert(user);
} else if (result.size() == 1) {
LOGGER.info("Update User " + user.getUsername());
commit.addUpdate(user);
} else {
LOGGER.warn("Error: Duplicate users in EngSB");
commit.addUpdate(user);
}
}
persistService.commit(commit);
revokePersistenceAccess();
}
@Override
public void deleteUsers(List<User> users) {
EKBCommit commit = getEKBCommit();
preparePersistenceAccess();
for (User user : users) {
List<User> result = queryService.query(User.class, QueryRequest.query("username", user.getUsername()));
if (result.size() == 0) {
LOGGER.warn("User {1} does not exist.", user.getUsername());
} else {
commit.addDelete(user);
}
}
persistService.commit(commit);
revokePersistenceAccess();
}
@Override
public void deleteUsersByName(List<String> userNames) {
List<User> users = new ArrayList<>();
for (String userName : userNames) {
users.add(new User(userName));
}
deleteUsers(users);
}
@Override
public void checkinProjects(List<Project> projects) {
EKBCommit commit = getEKBCommit();
preparePersistenceAccess();
for (Project project : projects) {
List<Project> result = queryService.query(Project.class, QueryRequest.query("name", project.getName()));
if (result.size() == 0) {
commit.addInsert(project);
} else {
commit.addUpdate(project);
}
}
persistService.commit(commit);
revokePersistenceAccess();
}
@Override
public void deleteProjects(List<Project> projects) {
EKBCommit commit = getEKBCommit();
preparePersistenceAccess();
for (Project project : projects) {
List<Project> result = queryService.query(Project.class, QueryRequest.query("name", project.getName()));
if (result.size() == 0) {
LOGGER.warn("Project {1} does not exist.", project.getName());
} else {
commit.addDelete(project);
}
deleteAllAssignmentsForProject(project);
}
persistService.commit(commit);
revokePersistenceAccess();
}
@Override
public void deleteProjectsByName(List<String> projectNames) {
List<Project> projects = Lists.newArrayList();
for (String projectName : projectNames) {
projects.add(new Project(projectName));
}
deleteProjects(projects);
}
@Override
public void checkinRoles(List<Role> roles) {
EKBCommit commit = getEKBCommit();
preparePersistenceAccess();
for (Role role : roles) {
List<Role> result = queryService.query(Role.class, QueryRequest.query("name", role.getName()));
if (result.size() == 0) {
commit.addInsert(role);
} else {
// Merge old and new role to avoid loss of permission information
for (String oldRole : result.get(0).getRoles()) {
if (!role.getRoles().contains(oldRole)) {
role.getRoles().add(oldRole);
}
}
for (Permission permission : result.get(0).getPermissions()) {
if (!role.getPermissions().contains(permission)) {
role.getPermissions().add(permission);
}
}
commit.addUpdate(role);
}
}
persistService.commit(commit);
revokePersistenceAccess();
}
@Override
public void deleteRoles(List<Role> roles) {
EKBCommit commit = getEKBCommit();
preparePersistenceAccess();
for (Role role : roles) {
List<Role> result = queryService.query(Role.class, QueryRequest.query("name", role.getName()));
if (result.size() == 0) {
LOGGER.warn("User {1} does not exist.", role.getName());
} else {
commit.addDelete(role);
}
}
persistService.commit(commit);
revokePersistenceAccess();
}
@Override
public void deleteRolesByName(List<String> roleNames) {
List<Role> roles = Lists.newArrayList();
for (String roleName : roleNames) {
roles.add(new Role(roleName));
}
deleteRoles(roles);
}
@Override
public void checkinAssignments(List<Assignment> assignments) {
EKBCommit commit = getEKBCommit();
preparePersistenceAccess();
for (Assignment assignment : assignments) {
QueryRequest request = QueryRequest.create();
request.addParameter("userName", assignment.getUserName());
request.addParameter("projectName", assignment.getProjectName());
List<Assignment> result = queryService.query(Assignment.class, request);
if (result.size() == 0) {
commit.addInsert(assignment);
} else {
// Merge old and new role to avoid loss of permission information
for (String oldRole : result.get(0).getRoles()) {
if (!assignment.getRoles().contains(oldRole)) {
assignment.getRoles().add(oldRole);
}
}
for (Permission permission : result.get(0).getPermissions()) {
if (!assignment.getPermissions().contains(permission)) {
assignment.getPermissions().add(permission);
}
}
commit.addUpdate(assignment);
}
}
persistService.commit(commit);
revokePersistenceAccess();
}
@Override
public void deleteAssignment(String userName, String project) {
Assignment queryObj = new Assignment();
queryObj.setUserName(userName);
queryObj.setProjectName(project);
List<Assignment> assignments = queryForAssignments(queryObj);
if (assignments.isEmpty()) {
LOGGER.warn("Assignment {1}:{2} does not exist.", userName, project);
}
deleteAssignments(assignments);
}
@Override
public void deleteAssignments(List<Assignment> assignments) {
EKBCommit commit = getEKBCommit();
preparePersistenceAccess();
for (Assignment assignment : assignments) {
List<Role> result = queryService.query(Role.class, QueryRequest.query("uuid", assignment.getUuid()));
if (result.size() == 0) {
LOGGER.warn("User {1} does not exist.", assignment.getUuid());
} else {
commit.addDelete(assignment);
}
}
persistService.commit(commit);
revokePersistenceAccess();
}
@Override
public void deleteAllAssignmentsForProject(String projectName) {
Assignment queryObj = new Assignment();
queryObj.setProjectName(projectName);
List<Assignment> assignments = queryForAssignments(queryObj);
deleteAssignmentsFromPersistence(assignments);
}
@Override
public void deleteAllAssignmentsForProject(Project project) {
Assignment queryObj = new Assignment();
queryObj.setProjectName(project.getName());
List<Assignment> assignments = queryForAssignments(queryObj);
deleteAssignmentsFromPersistence(assignments);
}
@Override
public void deleteAllAssignmentsForUser(String userName) {
Assignment queryObj = new Assignment();
queryObj.setUserName(userName);
List<Assignment> assignments = queryForAssignments(queryObj);
deleteAssignmentsFromPersistence(assignments);
}
@Override
public void deleteAllAssignmentsForUser(User user) {
Assignment queryObj = new Assignment();
queryObj.setUserName(user.getUsername());
List<Assignment> assignments = queryForAssignments(queryObj);
deleteAssignmentsFromPersistence(assignments);
}
public void setPersistService(PersistInterface persistService) {
this.persistService = persistService;
}
public void setQueryService(QueryInterface queryService) {
this.queryService = queryService;
}
public void setAuthenticationContext(AuthenticationContext authenticationContext) {
this.authenticationContext = authenticationContext;
}
private void deleteAssignmentsFromPersistence(List<Assignment> assignments) {
preparePersistenceAccess();
EKBCommit commit = getEKBCommit();
for (Assignment assignment : assignments) {
List<Role> result = queryService.query(Role.class, QueryRequest.query("uuid", assignment.getUuid()));
if (result.size() == 0) {
LOGGER.warn("User {1} does not exist.", assignment.getUuid());
} else {
commit.addDelete(assignment);
}
}
persistService.commit(commit);
revokePersistenceAccess();
}
private List<Assignment> queryForAssignments(Assignment assignment) {
QueryRequest request = QueryRequest.create();
if (assignment.getUserName() != null && !assignment.getUserName().equals("")) {
request.addParameter("userName", assignment.getUserName());
}
if (assignment.getProjectName() != null && !assignment.getProjectName().equals("")) {
request.addParameter("projectName", assignment.getProjectName());
}
preparePersistenceAccess();
List<Assignment> result = queryService.query(Assignment.class, request);
revokePersistenceAccess();
return result;
}
private EKBCommit getEKBCommit() {
EKBCommit result = new EKBCommit();
result.setDomainId("userprojects");
result.setConnectorId("upload");
result.setInstanceId("upload");
return result;
}
private void preparePersistenceAccess() {
if (authenticationContext.getAuthenticatedPrincipal() == null
|| !(authenticationContext.getAuthenticatedPrincipal() instanceof String)) {
throw new SynchronizationException("A user with DB access must be logged in.");
}
currentContext = ContextHolder.get().getCurrentContextId();
ContextHolder.get().setCurrentContextId("up-context");
}
private void revokePersistenceAccess() {
ContextHolder.get().setCurrentContextId(currentContext);
}
}