Adding REST v2 implementations

This commit is contained in:
Martin Stockhammer 2021-01-04 15:22:36 +01:00
parent 23f3df0ca9
commit 510d21aa09
3 changed files with 384 additions and 6 deletions

View File

@ -18,8 +18,11 @@
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -32,12 +35,16 @@
import org.apache.archiva.rest.api.model.v2.SecurityConfiguration;
import org.apache.archiva.security.common.ArchivaRoleConstants;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@ -58,7 +65,7 @@ public interface SecurityConfigurationService
{
@Path("config")
@GET
@Produces({ MediaType.APPLICATION_JSON })
@Produces({ APPLICATION_JSON })
@RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
@Operation( summary = "Returns the security configuration that is currently active.",
security = {
@ -77,6 +84,28 @@ public interface SecurityConfigurationService
SecurityConfiguration getConfiguration()
throws ArchivaRestServiceException;
@Path("config")
@PUT
@Consumes({ APPLICATION_JSON })
@RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
@Operation( summary = "Updates the security configuration.",
security = {
@SecurityRequirement(
name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
)
},
responses = {
@ApiResponse( responseCode = "200",
description = "If the configuration was updated"
),
@ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to update the configuration",
content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestServiceException.class )) )
}
)
Response updateConfiguration( SecurityConfiguration newConfiguration)
throws ArchivaRestServiceException;
@Path( "config/properties" )
@GET
@Produces( { APPLICATION_JSON } )
@ -109,9 +138,64 @@ PagedResult<PropertyEntry> getConfigurationProperties( @QueryParam("q") @Default
@QueryParam( "orderBy") @DefaultValue( "key" ) List<String> orderBy,
@QueryParam("order") @DefaultValue( "asc" ) String order ) throws ArchivaRestServiceException;
@Path("config/properties/{propertyName}")
@GET
@Produces({ APPLICATION_JSON })
@RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
@Operation( summary = "Returns a single configuration property value.",
security = {
@SecurityRequirement(
name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
)
},
parameters = {
@Parameter(in = ParameterIn.PATH, name="propertyName", description = "The name of the property to update")
},
responses = {
@ApiResponse( responseCode = "200",
description = "If the configuration could be retrieved"
),
@ApiResponse( responseCode = "404", description = "The given property name does not exist",
content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestServiceException.class )) ),
@ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestServiceException.class )) )
}
)
PropertyEntry getConfigurationProperty( @PathParam ( "propertyName" ) String propertyName)
throws ArchivaRestServiceException;
@Path("config/properties/{propertyName}")
@PUT
@Consumes({ APPLICATION_JSON})
@RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
@Operation( summary = "Updates a single property value of the security configuration.",
security = {
@SecurityRequirement(
name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
)
},
requestBody = @RequestBody(required = true, description = "The property value"),
parameters = {
@Parameter(in = ParameterIn.PATH, name="propertyName", description = "The name of the property to update")
},
responses = {
@ApiResponse( responseCode = "200",
description = "If the property value was updated."
),
@ApiResponse( responseCode = "404", description = "The given property name does not exist",
content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestServiceException.class )) ),
@ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestServiceException.class )) )
}
)
Response updateConfigurationProperty( @PathParam ( "propertyName" ) String propertyName, PropertyEntry propertyValue)
throws ArchivaRestServiceException;
@Path("config/ldap")
@GET
@Produces({ MediaType.APPLICATION_JSON })
@Produces({ APPLICATION_JSON })
@RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
@Operation( summary = "Returns the LDAP configuration that is currently active.",
security = {
@ -129,10 +213,30 @@ PagedResult<PropertyEntry> getConfigurationProperties( @QueryParam("q") @Default
)
LdapConfiguration getLdapConfiguration( ) throws ArchivaRestServiceException;
@Path("config/ldap")
@PUT
@Consumes({ APPLICATION_JSON })
@RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
@Operation( summary = "Updates the LDAP configuration that is currently active.",
security = {
@SecurityRequirement(
name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
)
},
requestBody = @RequestBody(required = true, description = "The LDAP configuration"),
responses = {
@ApiResponse( responseCode = "200",
description = "If the configuration was updated"
),
@ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to update the information",
content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestServiceException.class )) )
}
)
Response updateLdapConfiguration( LdapConfiguration configuration ) throws ArchivaRestServiceException;
@Path("config/cache")
@GET
@Produces({ MediaType.APPLICATION_JSON })
@Produces({ APPLICATION_JSON })
@RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
@Operation( summary = "Returns the cache configuration that is currently active.",
security = {
@ -150,9 +254,31 @@ PagedResult<PropertyEntry> getConfigurationProperties( @QueryParam("q") @Default
)
CacheConfiguration getCacheConfiguration( ) throws ArchivaRestServiceException;
@Path("config/cache")
@PUT
@Consumes({ APPLICATION_JSON })
@RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
@Operation( summary = "Updates the LDAP configuration that is currently active.",
security = {
@SecurityRequirement(
name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
)
},
requestBody = @RequestBody(required = true, description = "The LDAP configuration"),
responses = {
@ApiResponse( responseCode = "200",
description = "If the configuration was updated"
),
@ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to update the information",
content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestServiceException.class )) )
}
)
Response updateCacheConfiguration( CacheConfiguration cacheConfiguration ) throws ArchivaRestServiceException;
@Path("user_managers")
@GET
@Produces({ MediaType.APPLICATION_JSON })
@Produces({ APPLICATION_JSON })
@RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
@Operation( summary = "Returns the available user manager implementations.",
security = {
@ -173,7 +299,7 @@ List<BeanInformation> getAvailableUserManagers()
@Path("rbac_managers")
@GET
@Produces({ MediaType.APPLICATION_JSON })
@Produces({ APPLICATION_JSON })
@RedbackAuthorization(permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION)
@Operation( summary = "Returns the available RBAC manager implementations.",
security = {

View File

@ -19,11 +19,18 @@
import org.apache.archiva.admin.model.RepositoryAdminException;
import org.apache.archiva.admin.model.beans.RedbackRuntimeConfiguration;
import org.apache.archiva.admin.model.runtime.RedbackRuntimeConfigurationAdmin;
import org.apache.archiva.components.cache.Cache;
import org.apache.archiva.components.rest.model.PagedResult;
import org.apache.archiva.components.rest.model.PropertyEntry;
import org.apache.archiva.components.rest.util.PagingHelper;
import org.apache.archiva.components.rest.util.QueryHelper;
import org.apache.archiva.redback.authentication.Authenticator;
import org.apache.archiva.redback.common.ldap.connection.LdapConnectionFactory;
import org.apache.archiva.redback.common.ldap.user.LdapUserMapper;
import org.apache.archiva.redback.policy.CookieSettings;
import org.apache.archiva.redback.policy.PasswordRule;
import org.apache.archiva.redback.rbac.RBACManager;
import org.apache.archiva.redback.role.RoleManager;
import org.apache.archiva.redback.users.UserManager;
import org.apache.archiva.rest.api.model.UserManagerImplementationInformation;
import org.apache.archiva.rest.api.model.v2.BeanInformation;
@ -33,6 +40,8 @@
import org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException;
import org.apache.archiva.rest.api.services.v2.ErrorMessage;
import org.apache.archiva.rest.api.services.v2.SecurityConfigurationService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -41,8 +50,11 @@
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
import javax.management.Query;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@ -81,6 +93,29 @@ public class DefaultSecurityConfigurationService implements SecurityConfiguratio
@Inject
private ApplicationContext applicationContext;
@Inject
@Named(value = "userManager#default")
private UserManager userManager;
@Inject
@Named(value = "rbacManager#default")
private RBACManager rbacManager;
@Inject
private RoleManager roleManager;
@Inject
@Named(value = "ldapConnectionFactory#configurable")
private LdapConnectionFactory ldapConnectionFactory;
@Inject
private LdapUserMapper ldapUserMapper;
@Inject
@Named(value = "cache#users")
private Cache usersCache;
@PostConstruct
void init() {
bundle = ResourceBundle.getBundle( "org.apache.archiva.rest.RestBundle" );
@ -103,6 +138,135 @@ public SecurityConfiguration getConfiguration( ) throws ArchivaRestServiceExcept
throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
}
}
private void updateConfig(SecurityConfiguration newConfig, RedbackRuntimeConfiguration rbConfig) {
rbConfig.setUserManagerImpls( newConfig.getActiveUserManagers() );
rbConfig.setRbacManagerImpls( newConfig.getActiveRbacManagers() );
rbConfig.setUseUsersCache( newConfig.isUserCacheEnabled() );
Map<String, String> props = rbConfig.getConfigurationProperties( );
for ( Map.Entry<String,String> newProp : newConfig.getProperties().entrySet() ) {
props.put( newProp.getKey( ), newProp.getValue( ) );
}
}
private void updateConfig(LdapConfiguration newConfig, RedbackRuntimeConfiguration rbConfig) {
org.apache.archiva.admin.model.beans.LdapConfiguration ldapConfig = rbConfig.getLdapConfiguration( );
ldapConfig.setBaseDn( newConfig.getBaseDn( ) );
ldapConfig.setAuthenticationMethod( newConfig.getAuthenticationMethod() );
ldapConfig.setBindAuthenticatorEnabled( newConfig.isBindAuthenticatorEnabled( ) );
ldapConfig.setBindDn( newConfig.getBindDn() );
ldapConfig.setSsl( newConfig.isSslEnabled( ) );
ldapConfig.setBaseGroupsDn( newConfig.getGroupsBaseDn() );
ldapConfig.setHostName( newConfig.getHostName() );
ldapConfig.setPort( newConfig.getPort() );
ldapConfig.setPassword( newConfig.getBindPassword() );
ldapConfig.setUseRoleNameAsGroup( newConfig.isUseRoleNameAsGroup() );
ldapConfig.setWritable( newConfig.isWritable( ) );
Map<String, String> props = ldapConfig.getExtraProperties( );
for ( Map.Entry<String,String> newProp : newConfig.getProperties().entrySet() ) {
props.put( newProp.getKey( ), newProp.getValue( ) );
}
}
private void updateConfig(CacheConfiguration newConfig, RedbackRuntimeConfiguration rbConfig) {
org.apache.archiva.admin.model.beans.CacheConfiguration cacheConfig = rbConfig.getUsersCacheConfiguration( );
cacheConfig.setMaxElementsInMemory( newConfig.getMaxEntriesInMemory());
cacheConfig.setMaxElementsOnDisk( newConfig.getMaxEntriesOnDisk() );
cacheConfig.setTimeToLiveSeconds( newConfig.getTimeToLiveSeconds() );
cacheConfig.setTimeToIdleSeconds( newConfig.getTimeToIdleSeconds() );
}
@Override
public Response updateConfiguration( SecurityConfiguration newConfiguration ) throws ArchivaRestServiceException
{
try
{
RedbackRuntimeConfiguration conf = redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
boolean userManagerChanged = !CollectionUtils.isEqualCollection( newConfiguration.getActiveUserManagers( ), conf.getUserManagerImpls() );
boolean rbacManagerChanged = !CollectionUtils.isEqualCollection( newConfiguration.getActiveRbacManagers( ), conf.getRbacManagerImpls( ) );
boolean ldapConfigured = false;
for (String um : newConfiguration.getActiveUserManagers()) {
if (um.contains("ldap")) {
ldapConfigured=true;
}
}
if (!ldapConfigured) {
for (String rbm : newConfiguration.getActiveRbacManagers()) {
if (rbm.contains("ldap")) {
ldapConfigured = true;
}
}
}
updateConfig( newConfiguration, conf);
redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( conf );
if ( userManagerChanged )
{
log.info( "user managerImpls changed to {} so reload it",
newConfiguration.getActiveUserManagers() );
userManager.initialize();
}
if ( rbacManagerChanged )
{
log.info( "rbac manager changed to {} so reload it",
newConfiguration.getActiveRbacManagers() );
rbacManager.initialize();
roleManager.initialize();
}
if (ldapConfigured) {
try {
ldapConnectionFactory.initialize();
} catch (Exception e) {
log.error( "Could not initialize LDAP connection factory: {}", e.getMessage( ) );
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_CF_INIT_FAILED, e.getMessage() ) );
}
}
Collection<PasswordRule> passwordRules = applicationContext.getBeansOfType( PasswordRule.class ).values();
for ( PasswordRule passwordRule : passwordRules )
{
passwordRule.initialize();
}
Collection<CookieSettings> cookieSettingsList =
applicationContext.getBeansOfType( CookieSettings.class ).values();
for ( CookieSettings cookieSettings : cookieSettingsList )
{
cookieSettings.initialize();
}
Collection<Authenticator> authenticators =
applicationContext.getBeansOfType( Authenticator.class ).values();
for ( Authenticator authenticator : authenticators )
{
try {
log.debug("Initializing authenticatior "+authenticator.getId());
authenticator.initialize();
} catch (Exception e) {
log.error("Initialization of authenticator failed "+authenticator.getId(),e);
}
}
if (ldapConfigured) {
try {
ldapUserMapper.initialize();
} catch (Exception e) {
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_USER_MAPPER_INIT_FAILED, e.getMessage( ) ) );
}
}
}
catch ( RepositoryAdminException e )
{
throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
}
return Response.ok( ).build();
}
@Override
public PagedResult<PropertyEntry> getConfigurationProperties( String searchTerm, Integer offset, Integer limit, List<String> orderBy, String order ) throws ArchivaRestServiceException
@ -133,6 +297,48 @@ public PagedResult<PropertyEntry> getConfigurationProperties( String searchTerm,
}
}
@Override
public PropertyEntry getConfigurationProperty( String propertyName ) throws ArchivaRestServiceException
{
try
{
RedbackRuntimeConfiguration conf = redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
if (conf.getConfigurationProperties().containsKey( propertyName )) {
String value = conf.getConfigurationProperties( ).get( propertyName );
return new PropertyEntry( propertyName, value );
} else {
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.PROPERTY_NOT_FOUND ), 404 );
}
}
catch ( RepositoryAdminException e )
{
throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
}
}
@Override
public Response updateConfigurationProperty( String propertyName, PropertyEntry propertyValue ) throws ArchivaRestServiceException
{
try
{
RedbackRuntimeConfiguration conf = redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
if (conf.getConfigurationProperties().containsKey( propertyName )) {
conf.getConfigurationProperties( ).put( propertyName, propertyValue.getValue( ) );
redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( conf );
return Response.ok( ).build( );
} else {
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.PROPERTY_NOT_FOUND ), 404 );
}
}
catch ( RepositoryAdminException e )
{
throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
}
}
@Override
public LdapConfiguration getLdapConfiguration( ) throws ArchivaRestServiceException
{
@ -152,6 +358,29 @@ public LdapConfiguration getLdapConfiguration( ) throws ArchivaRestServiceExcept
}
@Override
public Response updateLdapConfiguration( LdapConfiguration configuration ) throws ArchivaRestServiceException
{
try
{
RedbackRuntimeConfiguration redbackRuntimeConfiguration =
redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
updateConfig( configuration, redbackRuntimeConfiguration );
redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( redbackRuntimeConfiguration );
return Response.ok( ).build( );
}
catch ( RepositoryAdminException e )
{
throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
}
}
@Override
public CacheConfiguration getCacheConfiguration( ) throws ArchivaRestServiceException
{
@ -171,6 +400,25 @@ public CacheConfiguration getCacheConfiguration( ) throws ArchivaRestServiceExce
}
@Override
public Response updateCacheConfiguration( CacheConfiguration cacheConfiguration ) throws ArchivaRestServiceException
{
try
{
RedbackRuntimeConfiguration redbackRuntimeConfiguration =
redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
updateConfig( cacheConfiguration, redbackRuntimeConfiguration );
redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( redbackRuntimeConfiguration );
return Response.ok( ).build( );
}
catch ( RepositoryAdminException e )
{
throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
}
}
@Override
public List<BeanInformation> getAvailableUserManagers( ) throws ArchivaRestServiceException
{

View File

@ -21,6 +21,10 @@
*/
public interface ErrorKeys
{
public static final String REPOSITORY_ADMIN_ERROR = "a.repositoryadmin.error";
String REPOSITORY_ADMIN_ERROR = "archiva.repositoryadmin.error";
String LDAP_CF_INIT_FAILED = "archiva.ldap.cf.init.failed";
String LDAP_USER_MAPPER_INIT_FAILED = "archiva.ldap.usermapper.init.failed";
String PROPERTY_NOT_FOUND = "archiva.property.not.found";
}