DomainGroupRepositoryImpl.java
/*
* Copyright 2019 the original author or authors.
*
* Licensed 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.bremersee.dccon.repository;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
import lombok.extern.slf4j.Slf4j;
import org.bremersee.data.ldaptive.LdaptiveEntryMapper;
import org.bremersee.data.ldaptive.LdaptiveTemplate;
import org.bremersee.dccon.config.DomainControllerProperties;
import org.bremersee.dccon.model.DomainGroup;
import org.bremersee.dccon.repository.cli.CommandExecutor;
import org.bremersee.dccon.repository.cli.CommandExecutorResponse;
import org.bremersee.dccon.repository.cli.CommandExecutorResponseValidator;
import org.bremersee.dccon.repository.ldap.DomainGroupLdapConstants;
import org.bremersee.dccon.repository.ldap.DomainGroupLdapMapper;
import org.bremersee.exception.ServiceException;
import org.ldaptive.SearchFilter;
import org.ldaptive.SearchRequest;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
/**
* The domain group repository.
*
* @author Christian Bremer
*/
@Profile("ldap")
@Component("domainGroupRepository")
@Slf4j
public class DomainGroupRepositoryImpl extends AbstractRepository implements DomainGroupRepository {
private LdaptiveEntryMapper<DomainGroup> domainGroupLdapMapper;
/**
* Instantiates a new domain group repository.
*
* @param properties the properties
* @param ldapTemplateProvider the ldap template provider
*/
public DomainGroupRepositoryImpl(
final DomainControllerProperties properties,
final ObjectProvider<LdaptiveTemplate> ldapTemplateProvider) {
super(properties, ldapTemplateProvider.getIfAvailable());
domainGroupLdapMapper = new DomainGroupLdapMapper(properties);
}
/**
* Sets domain group ldap mapper.
*
* @param domainGroupLdapMapper the domain group ldap mapper
*/
@SuppressWarnings("unused")
public void setDomainGroupLdapMapper(
final LdaptiveEntryMapper<DomainGroup> domainGroupLdapMapper) {
if (domainGroupLdapMapper != null) {
this.domainGroupLdapMapper = domainGroupLdapMapper;
}
}
@Override
public Stream<DomainGroup> findAll(final String query) {
final SearchRequest searchRequest = new SearchRequest(
getProperties().getGroupBaseDn(),
new SearchFilter(getProperties().getGroupFindAllFilter()));
searchRequest.setSearchScope(getProperties().getGroupFindAllSearchScope());
searchRequest.setBinaryAttributes(DomainGroupLdapConstants.BINARY_ATTRIBUTES);
if (query == null || query.trim().length() == 0) {
return getLdapTemplate().findAll(searchRequest, domainGroupLdapMapper);
} else {
return getLdapTemplate().findAll(searchRequest, domainGroupLdapMapper)
.filter(domainGroup -> isQueryResult(domainGroup, query.trim().toLowerCase()));
}
}
/**
* Is query result boolean.
*
* @param domainGroup the domain group
* @param query the query
* @return the boolean
*/
static boolean isQueryResult(final DomainGroup domainGroup, final String query) {
return query != null && query.length() > 2 && domainGroup != null
&& (contains(domainGroup.getName(), query)
|| contains(domainGroup.getDescription(), query)
|| contains(domainGroup.getMembers(), query));
}
@Override
public Optional<DomainGroup> findOne(final String groupName) {
final SearchFilter searchFilter = new SearchFilter(getProperties().getGroupFindOneFilter());
searchFilter.setParameter(0, groupName);
final SearchRequest searchRequest = new SearchRequest(
getProperties().getGroupBaseDn(),
searchFilter);
searchRequest.setSearchScope(getProperties().getGroupFindOneSearchScope());
searchRequest.setBinaryAttributes(DomainGroupLdapConstants.BINARY_ATTRIBUTES);
return getLdapTemplate().findOne(searchRequest, domainGroupLdapMapper);
}
@Override
public boolean exists(final String groupName) {
return getLdapTemplate()
.exists(DomainGroup.builder().name(groupName).build(), domainGroupLdapMapper);
}
@Override
public DomainGroup save(final DomainGroup domainGroup) {
if (!exists(domainGroup.getName())) {
doAdd(domainGroup);
}
return getLdapTemplate().save(domainGroup, domainGroupLdapMapper);
}
/**
* Add group.
*
* @param domainGroup the domain group
*/
void doAdd(final DomainGroup domainGroup) {
kinit();
final List<String> commands = new ArrayList<>();
sudo(commands);
commands.add(getProperties().getSambaToolBinary());
commands.add("group");
commands.add("add");
commands.add(domainGroup.getName());
auth(commands);
CommandExecutor.exec(
commands,
null,
getProperties().getSambaToolExecDir(),
(CommandExecutorResponseValidator) response -> {
if (!exists(domainGroup.getName())) {
throw ServiceException.internalServerError("msg=[Saving group failed.] groupName=["
+ domainGroup.getName() + "] "
+ CommandExecutorResponse.toExceptionMessage(response),
"org.bremersee:dc-con-app:7729c3c7-aeff-49f2-9243-dd5aee4b023a");
}
});
}
@Override
public boolean delete(final String groupName) {
if (exists(groupName)) {
doDelete(groupName);
return true;
}
return false;
}
/**
* Delete group.
*
* @param groupName the group name
*/
void doDelete(final String groupName) {
kinit();
final List<String> commands = new ArrayList<>();
sudo(commands);
commands.add(getProperties().getSambaToolBinary());
commands.add("group");
commands.add("delete");
commands.add(groupName);
auth(commands);
CommandExecutor.exec(
commands,
null,
getProperties().getSambaToolExecDir(),
(CommandExecutorResponseValidator) response -> {
if (exists(groupName)) {
throw ServiceException.internalServerError(
"msg=[Deleting group failed.] groupName=[" + groupName + "] "
+ CommandExecutorResponse.toExceptionMessage(response),
"org.bremersee:dc-con-app:28f610a5-1679-47d9-8f90-2a4d75882d52");
}
});
}
}