/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* 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.guvnor.structure.backend.organizationalunit;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Event;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import org.guvnor.structure.backend.backcompat.BackwardCompatibleUtil;
import org.guvnor.structure.backend.config.OrgUnit;
import org.guvnor.structure.config.SystemRepositoryChangedEvent;
import org.guvnor.structure.organizationalunit.NewOrganizationalUnitEvent;
import org.guvnor.structure.organizationalunit.OrganizationalUnit;
import org.guvnor.structure.organizationalunit.OrganizationalUnitService;
import org.guvnor.structure.organizationalunit.RemoveOrganizationalUnitEvent;
import org.guvnor.structure.organizationalunit.RepoAddedToOrganizationalUnitEvent;
import org.guvnor.structure.organizationalunit.RepoRemovedFromOrganizationalUnitEvent;
import org.guvnor.structure.organizationalunit.UpdatedOrganizationalUnitEvent;
import org.guvnor.structure.repositories.Repository;
import org.guvnor.structure.repositories.RepositoryEnvironmentUpdatedEvent;
import org.guvnor.structure.server.config.ConfigGroup;
import org.guvnor.structure.server.config.ConfigItem;
import org.guvnor.structure.server.config.ConfigType;
import org.guvnor.structure.server.config.ConfigurationFactory;
import org.guvnor.structure.server.config.ConfigurationService;
import org.guvnor.structure.server.organizationalunit.OrganizationalUnitFactory;
import org.jboss.errai.bus.server.annotations.Service;
import org.uberfire.rpc.SessionInfo;
import org.uberfire.security.authz.AuthorizationManager;
@Service
@ApplicationScoped
public class OrganizationalUnitServiceImpl implements OrganizationalUnitService {
@Inject
private ConfigurationService configurationService;
@Inject
private ConfigurationFactory configurationFactory;
@Inject
private OrganizationalUnitFactory organizationalUnitFactory;
@Inject
private BackwardCompatibleUtil backward;
@Inject
private Event<NewOrganizationalUnitEvent> newOrganizationalUnitEvent;
@Inject
private Event<RemoveOrganizationalUnitEvent> removeOrganizationalUnitEvent;
@Inject
private Event<RepoAddedToOrganizationalUnitEvent> repoAddedToOrgUnitEvent;
@Inject
private Event<RepoRemovedFromOrganizationalUnitEvent> repoRemovedFromOrgUnitEvent;
@Inject
private Event<UpdatedOrganizationalUnitEvent> updatedOrganizationalUnitEvent;
Map<String, OrganizationalUnit> registeredOrganizationalUnits = new HashMap<String, OrganizationalUnit>();
@Inject
private AuthorizationManager authorizationManager;
@Inject
private SessionInfo sessionInfo;
@PostConstruct
public void loadOrganizationalUnits() {
Collection<ConfigGroup> groups = configurationService.getConfiguration( ConfigType.ORGANIZATIONAL_UNIT );
if ( groups != null ) {
for ( ConfigGroup groupConfig : groups ) {
// Make sure existing Organizational Units are correctly initialized with a default group id.
String ouName = groupConfig.getName();
String defaultGroupId = groupConfig.getConfigItemValue( "defaultGroupId" );
if ( defaultGroupId == null || defaultGroupId.trim().isEmpty() ) {
groupConfig.setConfigItem( configurationFactory.newConfigItem( "defaultGroupId", getSanitizedDefaultGroupId( ouName ) ) );
configurationService.updateConfiguration( groupConfig );
}
OrganizationalUnit ou = organizationalUnitFactory.newOrganizationalUnit( groupConfig );
registeredOrganizationalUnits.put( ou.getName(),
ou );
}
}
}
@Override
public OrganizationalUnit getOrganizationalUnit( final String name ) {
return registeredOrganizationalUnits.get( name );
}
@Override
public Collection<OrganizationalUnit> getAllOrganizationalUnits() {
return new ArrayList<>( registeredOrganizationalUnits.values() );
}
@Override
public Collection<OrganizationalUnit> getOrganizationalUnits() {
ArrayList result = new ArrayList<>();
for (OrganizationalUnit ou : registeredOrganizationalUnits.values()) {
if (authorizationManager.authorize(ou, sessionInfo.getIdentity())) {
result.add(ou);
}
}
return result;
}
@Override
public OrganizationalUnit createOrganizationalUnit( final String name,
final String owner,
final String defaultGroupId ) {
OrganizationalUnit newOrganizationalUnit = null;
try {
configurationService.startBatch();
final ConfigGroup groupConfig = configurationFactory.newConfigGroup( ConfigType.ORGANIZATIONAL_UNIT,
name,
"" );
groupConfig.addConfigItem( configurationFactory.newConfigItem( "owner",
owner ) );
String _defaultGroupId = defaultGroupId == null || defaultGroupId.trim().isEmpty() ? getSanitizedDefaultGroupId( name ) : defaultGroupId;
groupConfig.addConfigItem( configurationFactory.newConfigItem( "defaultGroupId",
_defaultGroupId ) );
groupConfig.addConfigItem( configurationFactory.newConfigItem( "repositories",
new ArrayList<String>() ) );
groupConfig.addConfigItem( configurationFactory.newConfigItem( "security:groups",
new ArrayList<String>() ) );
configurationService.addConfiguration( groupConfig );
newOrganizationalUnit = organizationalUnitFactory.newOrganizationalUnit( groupConfig );
registeredOrganizationalUnits.put( newOrganizationalUnit.getName(),
newOrganizationalUnit );
return newOrganizationalUnit;
} finally {
configurationService.endBatch();
if ( newOrganizationalUnit != null ) {
newOrganizationalUnitEvent.fire( new NewOrganizationalUnitEvent( newOrganizationalUnit, getUserInfo( sessionInfo ) ) );
}
}
}
@Override
public OrganizationalUnit createOrganizationalUnit( final String name,
final String owner,
final String defaultGroupId,
final Collection<Repository> repositories ) {
OrganizationalUnit newOrganizationalUnit = null;
try {
configurationService.startBatch();
final ConfigGroup groupConfig = configurationFactory.newConfigGroup( ConfigType.ORGANIZATIONAL_UNIT,
name,
"" );
groupConfig.addConfigItem( configurationFactory.newConfigItem( "owner",
owner ) );
String _defaultGroupId = defaultGroupId == null || defaultGroupId.trim().isEmpty() ? getSanitizedDefaultGroupId( name ) : defaultGroupId;
groupConfig.addConfigItem( configurationFactory.newConfigItem( "defaultGroupId",
_defaultGroupId ) );
groupConfig.addConfigItem( configurationFactory.newConfigItem( "repositories",
getRepositoryAliases( repositories ) ) );
groupConfig.addConfigItem( configurationFactory.newConfigItem( "security:groups",
new ArrayList<String>() ) );
configurationService.addConfiguration( groupConfig );
newOrganizationalUnit = organizationalUnitFactory.newOrganizationalUnit( groupConfig );
registeredOrganizationalUnits.put( newOrganizationalUnit.getName(),
newOrganizationalUnit );
return newOrganizationalUnit;
} finally {
configurationService.endBatch();
if ( newOrganizationalUnit != null ) {
newOrganizationalUnitEvent.fire( new NewOrganizationalUnitEvent( newOrganizationalUnit, getUserInfo( sessionInfo ) ) );
}
}
}
private List<String> getRepositoryAliases( final Collection<Repository> repositories ) {
final List<String> repositoryList = new ArrayList<String>();
for ( Repository repo : repositories ) {
repositoryList.add( repo.getAlias() );
}
return repositoryList;
}
@Override
public OrganizationalUnit updateOrganizationalUnit( final String name,
final String owner,
final String defaultGroupId ) {
final ConfigGroup thisGroupConfig = findGroupConfig( name );
if ( thisGroupConfig != null ) {
OrganizationalUnit updatedOrganizationalUnit = null;
try {
configurationService.startBatch();
thisGroupConfig.setConfigItem( configurationFactory.newConfigItem( "owner",
owner ) );
// As per loadOrganizationalUnits(), all Organizational Units should have the default group id value set
String _defaultGroupId = defaultGroupId == null || defaultGroupId.trim().isEmpty() ?
thisGroupConfig.getConfigItemValue( "defaultGroupId" ) : defaultGroupId;
thisGroupConfig.setConfigItem( configurationFactory.newConfigItem( "defaultGroupId",
_defaultGroupId ) );
configurationService.updateConfiguration( thisGroupConfig );
updatedOrganizationalUnit = organizationalUnitFactory.newOrganizationalUnit( thisGroupConfig );
registeredOrganizationalUnits.put( updatedOrganizationalUnit.getName(),
updatedOrganizationalUnit );
return updatedOrganizationalUnit;
} finally {
configurationService.endBatch();
if ( updatedOrganizationalUnit != null ) {
updatedOrganizationalUnitEvent.fire( new UpdatedOrganizationalUnitEvent( updatedOrganizationalUnit, getUserInfo( sessionInfo ) ) );
}
}
} else {
throw new IllegalArgumentException( "OrganizationalUnit " + name + " not found" );
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void addRepository( final OrganizationalUnit organizationalUnit,
final Repository repository ) {
final ConfigGroup thisGroupConfig = findGroupConfig( organizationalUnit.getName() );
if ( thisGroupConfig != null ) {
try {
configurationService.startBatch();
ConfigItem<List> repositories = thisGroupConfig.getConfigItem( "repositories" );
repositories.getValue().add( repository.getAlias() );
configurationService.updateConfiguration( thisGroupConfig );
final OrganizationalUnit updatedOrganizationalUnit = organizationalUnitFactory.newOrganizationalUnit( thisGroupConfig );
registeredOrganizationalUnits.put( updatedOrganizationalUnit.getName(),
updatedOrganizationalUnit );
} finally {
configurationService.endBatch();
repoAddedToOrgUnitEvent.fire( new RepoAddedToOrganizationalUnitEvent( organizationalUnit, repository, getUserInfo( sessionInfo ) ) );
}
} else {
throw new IllegalArgumentException( "OrganizationalUnit " + organizationalUnit.getName() + " not found" );
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void removeRepository( final OrganizationalUnit organizationalUnit,
final Repository repository ) {
final ConfigGroup thisGroupConfig = findGroupConfig( organizationalUnit.getName() );
if ( thisGroupConfig != null ) {
try {
configurationService.startBatch();
final ConfigItem<List> repositories = thisGroupConfig.getConfigItem( "repositories" );
repositories.getValue().remove( repository.getAlias() );
configurationService.updateConfiguration( thisGroupConfig );
final OrganizationalUnit updatedOrganizationalUnit = organizationalUnitFactory.newOrganizationalUnit( thisGroupConfig );
registeredOrganizationalUnits.put( updatedOrganizationalUnit.getName(),
updatedOrganizationalUnit );
} finally {
configurationService.endBatch();
repoRemovedFromOrgUnitEvent.fire( new RepoRemovedFromOrganizationalUnitEvent( organizationalUnit, repository, getUserInfo( sessionInfo ) ) );
}
} else {
throw new IllegalArgumentException( "OrganizationalUnit " + organizationalUnit.getName() + " not found" );
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void addGroup( final OrganizationalUnit organizationalUnit,
final String group ) {
final ConfigGroup thisGroupConfig = findGroupConfig( organizationalUnit.getName() );
if ( thisGroupConfig != null ) {
OrganizationalUnit updatedOrganizationalUnit = null;
try {
configurationService.startBatch();
final ConfigItem<List> groups = backward.compat( thisGroupConfig ).getConfigItem( "security:groups" );
groups.getValue().add( group );
configurationService.updateConfiguration( thisGroupConfig );
updatedOrganizationalUnit = organizationalUnitFactory.newOrganizationalUnit( thisGroupConfig );
registeredOrganizationalUnits.put( updatedOrganizationalUnit.getName(),
updatedOrganizationalUnit );
} finally {
configurationService.endBatch();
if ( updatedOrganizationalUnit != null ) {
updatedOrganizationalUnitEvent.fire( new UpdatedOrganizationalUnitEvent( updatedOrganizationalUnit, getUserInfo( sessionInfo ) ) );
}
}
} else {
throw new IllegalArgumentException( "OrganizationalUnit " + organizationalUnit.getName() + " not found" );
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void removeGroup( final OrganizationalUnit organizationalUnit,
final String group ) {
final ConfigGroup thisGroupConfig = findGroupConfig( organizationalUnit.getName() );
if ( thisGroupConfig != null ) {
OrganizationalUnit updatedOrganizationalUnit = null;
try {
configurationService.startBatch();
final ConfigItem<List> groups = backward.compat( thisGroupConfig ).getConfigItem( "security:groups" );
groups.getValue().remove( group );
configurationService.updateConfiguration( thisGroupConfig );
updatedOrganizationalUnit = organizationalUnitFactory.newOrganizationalUnit( thisGroupConfig );
registeredOrganizationalUnits.put( updatedOrganizationalUnit.getName(),
updatedOrganizationalUnit );
} finally {
configurationService.endBatch();
if ( updatedOrganizationalUnit != null ) {
updatedOrganizationalUnitEvent.fire( new UpdatedOrganizationalUnitEvent( updatedOrganizationalUnit, getUserInfo( sessionInfo ) ) );
}
}
} else {
throw new IllegalArgumentException( "OrganizationalUnit " + organizationalUnit.getName() + " not found" );
}
}
protected ConfigGroup findGroupConfig( final String name ) {
final Collection<ConfigGroup> groups = configurationService.getConfiguration( ConfigType.ORGANIZATIONAL_UNIT );
if ( groups != null ) {
for ( ConfigGroup groupConfig : groups ) {
if ( groupConfig.getName().equals( name ) ) {
return groupConfig;
}
}
}
return null;
}
@Override
public void removeOrganizationalUnit( String groupName ) {
final ConfigGroup thisGroupConfig = findGroupConfig( groupName );
if ( thisGroupConfig != null ) {
OrganizationalUnit ou = null;
try {
configurationService.startBatch();
configurationService.removeConfiguration( thisGroupConfig );
ou = registeredOrganizationalUnits.remove( groupName );
} finally {
configurationService.endBatch();
if ( ou != null ) {
removeOrganizationalUnitEvent.fire( new RemoveOrganizationalUnitEvent( ou, getUserInfo( sessionInfo ) ) );
}
}
}
}
@Override
public OrganizationalUnit getParentOrganizationalUnit( final Repository repository ) {
for ( OrganizationalUnit organizationalUnit : registeredOrganizationalUnits.values() ) {
if ( organizationalUnit.getRepositories() != null &&
organizationalUnit.getRepositories().contains( repository ) ) {
return organizationalUnit;
}
}
return null;
}
@Override
public String getSanitizedDefaultGroupId( final String proposedGroupId ) {
//Only [A-Za-z0-9_\-.] are valid so strip everything else out
return proposedGroupId != null ? proposedGroupId.replaceAll( "[^A-Za-z0-9_\\-.]", "" ) : proposedGroupId;
}
@Override
public Boolean isValidGroupId( final String proposedGroupId ) {
if ( proposedGroupId != null && !proposedGroupId.trim().isEmpty() ) {
if ( proposedGroupId.length() == getSanitizedDefaultGroupId( proposedGroupId ).length() ) {
return true;
}
}
return false;
}
public void updateRegisteredOU( @Observes @OrgUnit SystemRepositoryChangedEvent changedEvent ) {
registeredOrganizationalUnits.clear();
loadOrganizationalUnits();
}
// refresh org unit in case repository changed otherwise it will have outdated information
public void updateRegisteredOUonRepoChange( @Observes RepositoryEnvironmentUpdatedEvent changedEvent ) {
registeredOrganizationalUnits.clear();
loadOrganizationalUnits();
}
protected String getUserInfo( SessionInfo sessionInfo ) {
try {
return sessionInfo.getIdentity().getIdentifier();
} catch ( final Exception e ) {
return "system";
}
}
}