Adding additional REST V2 tests
This commit is contained in:
parent
fa2b8ca7d4
commit
e24e545900
|
@ -239,7 +239,8 @@ public class DefaultLdapRoleMapper
|
||||||
|
|
||||||
searchControls.setDerefLinkFlag( true );
|
searchControls.setDerefLinkFlag( true );
|
||||||
searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
|
searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
|
||||||
searchControls.setReturningAttributes( new String[]{ this.getLdapDnAttribute(), "objectClass", groupNameAttribute} );
|
searchControls.setReturningAttributes( new String[]{ this.getLdapDnAttribute(), "objectClass", groupNameAttribute,
|
||||||
|
ldapGroupMemberAttribute} );
|
||||||
|
|
||||||
String filter = "objectClass=" + getLdapGroupClass( );
|
String filter = "objectClass=" + getLdapGroupClass( );
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@ package org.apache.archiva.redback.rest.api.model;
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -27,6 +29,7 @@ import java.util.List;
|
||||||
* @author Martin Stockhammer <martin_s@apache.org>
|
* @author Martin Stockhammer <martin_s@apache.org>
|
||||||
*/
|
*/
|
||||||
@XmlRootElement(name="group")
|
@XmlRootElement(name="group")
|
||||||
|
@Schema(name="Group", description = "Group object")
|
||||||
public class Group implements Serializable
|
public class Group implements Serializable
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = -1842878251787304632L;
|
private static final long serialVersionUID = -1842878251787304632L;
|
||||||
|
@ -44,6 +47,7 @@ public class Group implements Serializable
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Schema(description = "The name of the group")
|
||||||
public String getName( )
|
public String getName( )
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
|
@ -54,6 +58,7 @@ public class Group implements Serializable
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Schema(description = "The unique name of the group. Depends on the backend repository, e.g. the LDAP DN.")
|
||||||
public String getUniqueName( )
|
public String getUniqueName( )
|
||||||
{
|
{
|
||||||
return uniqueName;
|
return uniqueName;
|
||||||
|
@ -64,6 +69,7 @@ public class Group implements Serializable
|
||||||
this.uniqueName = uniqueName;
|
this.uniqueName = uniqueName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Schema( description = "The group description, if available" )
|
||||||
public String getDescription( )
|
public String getDescription( )
|
||||||
{
|
{
|
||||||
return description;
|
return description;
|
||||||
|
@ -74,6 +80,7 @@ public class Group implements Serializable
|
||||||
this.description = description;
|
this.description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Schema(description = "The list of members. The format of the member strings depends on the backend repository, e.g. for LDAP these may be the member DNs")
|
||||||
public List<String> getMemberList( )
|
public List<String> getMemberList( )
|
||||||
{
|
{
|
||||||
return memberList;
|
return memberList;
|
||||||
|
|
|
@ -18,6 +18,8 @@ package org.apache.archiva.redback.rest.api.model;
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -26,6 +28,7 @@ import java.util.List;
|
||||||
* @author Martin Stockhammer <martin_s@apache.org>
|
* @author Martin Stockhammer <martin_s@apache.org>
|
||||||
*/
|
*/
|
||||||
@XmlRootElement(name="pagedResult")
|
@XmlRootElement(name="pagedResult")
|
||||||
|
@Schema(name = "PagedResult", description = "Contains paged data. Pages are defined by limit and offset.")
|
||||||
public class PagedResult<T>
|
public class PagedResult<T>
|
||||||
{
|
{
|
||||||
PaginationInfo pagination;
|
PaginationInfo pagination;
|
||||||
|
@ -44,6 +47,7 @@ public class PagedResult<T>
|
||||||
return new PagedResult( totalSize, offset, limit, element);
|
return new PagedResult( totalSize, offset, limit, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Schema(description = "This is the payload of the paged data. The type of data depends on the REST method. ")
|
||||||
public T getData( )
|
public T getData( )
|
||||||
{
|
{
|
||||||
return data;
|
return data;
|
||||||
|
@ -54,6 +58,7 @@ public class PagedResult<T>
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Schema(description = "The pagination information")
|
||||||
public PaginationInfo getPagination( )
|
public PaginationInfo getPagination( )
|
||||||
{
|
{
|
||||||
return pagination;
|
return pagination;
|
||||||
|
|
|
@ -18,6 +18,8 @@ package org.apache.archiva.redback.rest.api.model;
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
@ -28,6 +30,7 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||||
* @author Martin Stockhammer <martin_s@apache.org>
|
* @author Martin Stockhammer <martin_s@apache.org>
|
||||||
*/
|
*/
|
||||||
@XmlRootElement(name="pagination")
|
@XmlRootElement(name="pagination")
|
||||||
|
@Schema(name="PaginationInfo", description = "Contains paging information (limit, offset, totalCount)")
|
||||||
public class PaginationInfo
|
public class PaginationInfo
|
||||||
{
|
{
|
||||||
long totalCount;
|
long totalCount;
|
||||||
|
@ -45,6 +48,7 @@ public class PaginationInfo
|
||||||
this.limit = limit;
|
this.limit = limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Schema(description = "The total number of data available.")
|
||||||
public long getTotalCount( )
|
public long getTotalCount( )
|
||||||
{
|
{
|
||||||
return totalCount;
|
return totalCount;
|
||||||
|
@ -55,6 +59,7 @@ public class PaginationInfo
|
||||||
this.totalCount = totalCount;
|
this.totalCount = totalCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Schema(description = "The offset of the first element of the returned dataset.")
|
||||||
public long getOffset( )
|
public long getOffset( )
|
||||||
{
|
{
|
||||||
return offset;
|
return offset;
|
||||||
|
@ -65,6 +70,7 @@ public class PaginationInfo
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Schema(description = "The maximum number of elements returned per page.")
|
||||||
public long getLimit( )
|
public long getLimit( )
|
||||||
{
|
{
|
||||||
return limit;
|
return limit;
|
||||||
|
|
|
@ -22,6 +22,8 @@ import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
|
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
|
import io.swagger.v3.oas.annotations.security.SecurityRequirements;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityScheme;
|
import io.swagger.v3.oas.annotations.security.SecurityScheme;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import org.apache.archiva.redback.authorization.RedbackAuthorization;
|
import org.apache.archiva.redback.authorization.RedbackAuthorization;
|
||||||
|
@ -54,9 +56,11 @@ import java.util.List;
|
||||||
@SecurityScheme( scheme = "BearerAuth", type = SecuritySchemeType.HTTP )
|
@SecurityScheme( scheme = "BearerAuth", type = SecuritySchemeType.HTTP )
|
||||||
@Tag(name = "v2")
|
@Tag(name = "v2")
|
||||||
@Tag(name = "v2/Groups")
|
@Tag(name = "v2/Groups")
|
||||||
|
@SecurityRequirement(name = "BearerAuth")
|
||||||
public interface GroupService
|
public interface GroupService
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public static final String DEFAULT_PAGE_LIMIT = "1000";
|
||||||
|
|
||||||
@Path( "" )
|
@Path( "" )
|
||||||
@GET
|
@GET
|
||||||
|
@ -67,8 +71,8 @@ public interface GroupService
|
||||||
@ApiResponse( description = "List of group objects. The number of returned results depend on the pagination parameters offset and limit." )
|
@ApiResponse( description = "List of group objects. The number of returned results depend on the pagination parameters offset and limit." )
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
PagedResult<List<Group>> getGroups( @QueryParam( "offset" ) @DefaultValue( "0" ) Integer offset,
|
PagedResult<List<Group>> getGroups( @QueryParam( "offset" ) @DefaultValue( "0" ) Long offset,
|
||||||
@QueryParam( "limit" ) @DefaultValue( value = Integer.MAX_VALUE+"" ) Integer limit)
|
@QueryParam( "limit" ) @DefaultValue( value = DEFAULT_PAGE_LIMIT ) Long limit)
|
||||||
throws RedbackServiceException;
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,7 +142,7 @@ public interface GroupService
|
||||||
@Consumes( {MediaType.APPLICATION_JSON} )
|
@Consumes( {MediaType.APPLICATION_JSON} )
|
||||||
@Produces( {MediaType.APPLICATION_JSON} )
|
@Produces( {MediaType.APPLICATION_JSON} )
|
||||||
@RedbackAuthorization( permissions = RedbackRoleConstants.CONFIGURATION_EDIT_OPERATION )
|
@RedbackAuthorization( permissions = RedbackRoleConstants.CONFIGURATION_EDIT_OPERATION )
|
||||||
@Operation( summary = "Updates a multiple group mappings",
|
@Operation( summary = "Updates multiple group mappings",
|
||||||
responses = {
|
responses = {
|
||||||
@ApiResponse( description = "The status of the update action" ),
|
@ApiResponse( description = "The status of the update action" ),
|
||||||
@ApiResponse( responseCode = "405", description = "Invalid input" )
|
@ApiResponse( responseCode = "405", description = "Invalid input" )
|
||||||
|
|
|
@ -18,8 +18,11 @@ package org.apache.archiva.redback.rest.services.interceptors;
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.core.json.JsonWriteFeature;
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
|
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
|
||||||
|
@ -50,6 +53,7 @@ public class JacksonJsonConfigurator
|
||||||
log.info( "configure jackson ObjectMapper" );
|
log.info( "configure jackson ObjectMapper" );
|
||||||
objectMapper.disable( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES );
|
objectMapper.disable( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES );
|
||||||
objectMapper.enable( DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL );
|
objectMapper.enable( DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL );
|
||||||
|
objectMapper.enable( DeserializationFeature.USE_LONG_FOR_INTS );
|
||||||
objectMapper.setAnnotationIntrospector( new JaxbAnnotationIntrospector( objectMapper.getTypeFactory() ) );
|
objectMapper.setAnnotationIntrospector( new JaxbAnnotationIntrospector( objectMapper.getTypeFactory() ) );
|
||||||
objectMapper.findAndRegisterModules( );
|
objectMapper.findAndRegisterModules( );
|
||||||
objectMapper.registerModule( new JavaTimeModule( ) );
|
objectMapper.registerModule( new JavaTimeModule( ) );
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class DefaultGroupService
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PagedResult<List<Group>> getGroups( Integer offset, Integer limit ) throws RedbackServiceException
|
public PagedResult<List<Group>> getGroups( Long offset, Long limit ) throws RedbackServiceException
|
||||||
{
|
{
|
||||||
LdapConnection ldapConnection = null;
|
LdapConnection ldapConnection = null;
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,10 @@ public class BaseSetup
|
||||||
public static final String SYSPROP_SERVER_PORT = "archiva.rest.server.port";
|
public static final String SYSPROP_SERVER_PORT = "archiva.rest.server.port";
|
||||||
public static final String SYSPROP_SERVER_BASE_URI = "archiva.rest.server.baseuri";
|
public static final String SYSPROP_SERVER_BASE_URI = "archiva.rest.server.baseuri";
|
||||||
public static final String SYSPROP_SERVER_ADMIN_PWD = "rest.admin.pwd";
|
public static final String SYSPROP_SERVER_ADMIN_PWD = "rest.admin.pwd";
|
||||||
|
public static final String SYSPROP_LDAP_URL = "archiva.rest.ldap.url";
|
||||||
|
public static final String SYSPROP_LDAP_BASEDN = "archiva.rest.ldap.baseDn";
|
||||||
|
public static final String SYSPROP_LDAP_BINDDN = "archiva.rest.ldap.bindDn";
|
||||||
|
public static final String SYSPROP_LDAP_BINPWD = "archiva.rest.ldap.bindPwd";
|
||||||
|
|
||||||
public static String DEFAULT_ADMIN_PWD = "Ackd245aer9sdfan";
|
public static String DEFAULT_ADMIN_PWD = "Ackd245aer9sdfan";
|
||||||
|
|
||||||
|
@ -49,4 +53,25 @@ public class BaseSetup
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean startServer()
|
||||||
|
{
|
||||||
|
return !"no".equals( System.getProperty( SYSPROP_START_SERVER, "yes" ).toLowerCase( ) );
|
||||||
|
}
|
||||||
|
public static String getServerPort()
|
||||||
|
{
|
||||||
|
return System.getProperty( SYSPROP_SERVER_PORT, "" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getBaseUri() {
|
||||||
|
return System.getProperty( SYSPROP_SERVER_BASE_URI, "http://localhost" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LdapInfo getLdapInfo() {
|
||||||
|
String url = System.getProperty( SYSPROP_LDAP_URL, "" );
|
||||||
|
String baseDn = System.getProperty( SYSPROP_LDAP_BASEDN, "" );
|
||||||
|
String bindDn = System.getProperty( SYSPROP_LDAP_BINDDN, "" );
|
||||||
|
String bindPwd = System.getProperty( SYSPROP_LDAP_BINPWD, "" );
|
||||||
|
|
||||||
|
return new LdapInfo( url, baseDn, bindDn, bindPwd );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
package org.apache.archiva.redback.rest.services;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Martin Stockhammer <martin_s@apache.org>
|
||||||
|
*/
|
||||||
|
public class LdapInfo
|
||||||
|
{
|
||||||
|
String URL;
|
||||||
|
String baseDN;
|
||||||
|
String bindDN;
|
||||||
|
String bindPassword;
|
||||||
|
boolean remote;
|
||||||
|
|
||||||
|
public LdapInfo( )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public LdapInfo( String URL, String baseDN, String bindDN, String bindPassword )
|
||||||
|
{
|
||||||
|
this.URL = URL;
|
||||||
|
this.baseDN = baseDN;
|
||||||
|
this.bindDN = bindDN;
|
||||||
|
this.bindPassword = bindPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getURL( )
|
||||||
|
{
|
||||||
|
return URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setURL( String URL )
|
||||||
|
{
|
||||||
|
this.URL = URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBaseDN( )
|
||||||
|
{
|
||||||
|
return baseDN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBaseDN( String baseDN )
|
||||||
|
{
|
||||||
|
this.baseDN = baseDN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBindDN( )
|
||||||
|
{
|
||||||
|
return bindDN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBindDN( String bindDN )
|
||||||
|
{
|
||||||
|
this.bindDN = bindDN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBindPassword( )
|
||||||
|
{
|
||||||
|
return bindPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBindPassword( String bindPassword )
|
||||||
|
{
|
||||||
|
this.bindPassword = bindPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRemote() {
|
||||||
|
return StringUtils.isNotEmpty( URL ) && StringUtils.isNotEmpty( baseDN ) && StringUtils.isNotEmpty( bindDN );
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,8 +18,10 @@ package org.apache.archiva.redback.rest.services.v2;
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ser.Serializers;
|
||||||
import io.restassured.RestAssured;
|
import io.restassured.RestAssured;
|
||||||
import io.restassured.builder.RequestSpecBuilder;
|
import io.restassured.builder.RequestSpecBuilder;
|
||||||
|
import io.restassured.response.Response;
|
||||||
import io.restassured.specification.RequestSpecification;
|
import io.restassured.specification.RequestSpecification;
|
||||||
import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
|
import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
|
||||||
import org.apache.archiva.redback.rest.services.BaseSetup;
|
import org.apache.archiva.redback.rest.services.BaseSetup;
|
||||||
|
@ -43,11 +45,13 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.web.context.ContextLoaderListener;
|
import org.springframework.web.context.ContextLoaderListener;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import static io.restassured.RestAssured.baseURI;
|
import static io.restassured.RestAssured.*;
|
||||||
import static io.restassured.RestAssured.port;
|
import static io.restassured.http.ContentType.JSON;
|
||||||
import static org.apache.archiva.redback.rest.services.BaseSetup.*;
|
import static org.apache.archiva.redback.rest.services.BaseSetup.*;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
@ -58,6 +62,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
* @author Martin Stockhammer <martin_s@apache.org>
|
* @author Martin Stockhammer <martin_s@apache.org>
|
||||||
*/
|
*/
|
||||||
@Tag( "rest-native" )
|
@Tag( "rest-native" )
|
||||||
|
@Tag( "rest-v2" )
|
||||||
public abstract class AbstractNativeRestServices
|
public abstract class AbstractNativeRestServices
|
||||||
{
|
{
|
||||||
public static final int STOPPED = 0;
|
public static final int STOPPED = 0;
|
||||||
|
@ -65,6 +70,9 @@ public abstract class AbstractNativeRestServices
|
||||||
public static final int STARTING = 2;
|
public static final int STARTING = 2;
|
||||||
public static final int STARTED = 3;
|
public static final int STARTED = 3;
|
||||||
public static final int ERROR = 4;
|
public static final int ERROR = 4;
|
||||||
|
private final boolean startServer;
|
||||||
|
private final String serverPort;
|
||||||
|
private final String baseUri;
|
||||||
|
|
||||||
private RequestSpecification requestSpec;
|
private RequestSpecification requestSpec;
|
||||||
protected Logger log = LoggerFactory.getLogger( getClass( ) );
|
protected Logger log = LoggerFactory.getLogger( getClass( ) );
|
||||||
|
@ -75,10 +83,24 @@ public abstract class AbstractNativeRestServices
|
||||||
private UserManager userManager;
|
private UserManager userManager;
|
||||||
private RoleManager roleManager;
|
private RoleManager roleManager;
|
||||||
|
|
||||||
|
private final boolean remoteService;
|
||||||
|
|
||||||
|
private String adminToken;
|
||||||
|
private String adminRefreshToken;
|
||||||
|
|
||||||
|
|
||||||
public AbstractNativeRestServices( )
|
public AbstractNativeRestServices( )
|
||||||
{
|
{
|
||||||
|
this.startServer = BaseSetup.startServer( );
|
||||||
|
this.serverPort = BaseSetup.getServerPort( );
|
||||||
|
this.baseUri = BaseSetup.getBaseUri( );
|
||||||
|
|
||||||
|
if ( startServer )
|
||||||
|
{
|
||||||
|
this.remoteService = false;
|
||||||
|
} else {
|
||||||
|
this.remoteService = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract String getServicePath( );
|
protected abstract String getServicePath( );
|
||||||
|
@ -208,7 +230,7 @@ public abstract class AbstractNativeRestServices
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
um.updateUser( adminUser, false);
|
um.updateUser( adminUser, false );
|
||||||
}
|
}
|
||||||
getRoleManager( ).assignRole( "system-administrator", adminUser.getUsername( ) );
|
getRoleManager( ).assignRole( "system-administrator", adminUser.getUsername( ) );
|
||||||
}
|
}
|
||||||
|
@ -284,11 +306,7 @@ public abstract class AbstractNativeRestServices
|
||||||
|
|
||||||
protected void setupNative( ) throws Exception
|
protected void setupNative( ) throws Exception
|
||||||
{
|
{
|
||||||
String startServer = System.getProperty( SYSPROP_START_SERVER, "yes" ).toLowerCase( );
|
if ( this.startServer )
|
||||||
String serverPort = System.getProperty( SYSPROP_SERVER_PORT, "" );
|
|
||||||
String baseUri = System.getProperty( SYSPROP_SERVER_BASE_URI, "http://localhost" );
|
|
||||||
|
|
||||||
if ( !"no".equals( startServer ) )
|
|
||||||
{
|
{
|
||||||
startServer( );
|
startServer( );
|
||||||
}
|
}
|
||||||
|
@ -310,24 +328,75 @@ public abstract class AbstractNativeRestServices
|
||||||
RestAssured.baseURI = "http://localhost";
|
RestAssured.baseURI = "http://localhost";
|
||||||
}
|
}
|
||||||
String basePath = getBasePath( );
|
String basePath = getBasePath( );
|
||||||
this.requestSpec = getRequestSpecBuilder().build( );
|
this.requestSpec = getRequestSpecBuilder( ).build( );
|
||||||
RestAssured.basePath = basePath;
|
RestAssured.basePath = basePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected RequestSpecBuilder getRequestSpecBuilder() {
|
protected RequestSpecBuilder getRequestSpecBuilder( )
|
||||||
return new RequestSpecBuilder().setBaseUri( baseURI )
|
{
|
||||||
|
return new RequestSpecBuilder( ).setBaseUri( baseURI )
|
||||||
.setPort( port )
|
.setPort( port )
|
||||||
.setBasePath( getBasePath() )
|
.setBasePath( getBasePath( ) )
|
||||||
.addHeader( "Origin", RestAssured.baseURI + ":" + RestAssured.port );
|
.addHeader( "Origin", RestAssured.baseURI + ":" + RestAssured.port );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected RequestSpecification getRequestSpec(String bearerToken) {
|
protected RequestSpecBuilder getAuthRequestSpecBuilder( )
|
||||||
return getRequestSpecBuilder( ).addHeader( "Authorization", "Bearer " + bearerToken ).build();
|
{
|
||||||
|
return new RequestSpecBuilder( ).setBaseUri( baseURI )
|
||||||
|
.setPort( port )
|
||||||
|
.setBasePath( new StringBuilder( )
|
||||||
|
.append( getContextRoot( ) )
|
||||||
|
.append( getServiceBasePath( ) ).append("/auth").toString() )
|
||||||
|
.addHeader( "Origin", RestAssured.baseURI + ":" + RestAssured.port );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RequestSpecification getRequestSpec( String bearerToken )
|
||||||
|
{
|
||||||
|
return getRequestSpecBuilder( ).addHeader( "Authorization", "Bearer " + bearerToken ).build( );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void shutdownNative( ) throws Exception
|
protected void shutdownNative( ) throws Exception
|
||||||
{
|
{
|
||||||
stopServer( );
|
if (startServer)
|
||||||
|
{
|
||||||
|
stopServer( );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected org.apache.archiva.redback.rest.api.model.User addRemoteUser(String userid, String password, String fullName, String mail) {
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initAdminToken() {
|
||||||
|
Map<String, Object> jsonAsMap = new HashMap<>();
|
||||||
|
jsonAsMap.put( "grant_type", "authorization_code" );
|
||||||
|
jsonAsMap.put("user_id", getAdminUser());
|
||||||
|
jsonAsMap.put("password", getAdminPwd() );
|
||||||
|
Response result = given( ).spec( getAuthRequestSpecBuilder().build() )
|
||||||
|
.contentType( JSON )
|
||||||
|
.body( jsonAsMap )
|
||||||
|
.when( ).post( "/authenticate").then( ).statusCode( 200 )
|
||||||
|
.extract( ).response( );
|
||||||
|
this.adminToken = result.body( ).jsonPath( ).getString( "access_token" );
|
||||||
|
this.adminRefreshToken = result.body( ).jsonPath( ).getString( "refresh_token" );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getAdminToken() {
|
||||||
|
if (this.adminToken == null) {
|
||||||
|
initAdminToken();
|
||||||
|
}
|
||||||
|
return this.adminToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getAdminRefreshToken() {
|
||||||
|
if (this.adminRefreshToken == null) {
|
||||||
|
initAdminToken();
|
||||||
|
}
|
||||||
|
return this.adminRefreshToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRemoteService() {
|
||||||
|
return this.remoteService;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ import org.eclipse.jetty.server.ServerConnector;
|
||||||
import org.eclipse.jetty.server.session.SessionHandler;
|
import org.eclipse.jetty.server.session.SessionHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
import org.junit.jupiter.api.Tag;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -70,6 +71,8 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
*/
|
*/
|
||||||
@ExtendWith( SpringExtension.class )
|
@ExtendWith( SpringExtension.class )
|
||||||
@ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath*:/spring-context.xml" } )
|
@ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath*:/spring-context.xml" } )
|
||||||
|
@Tag("rest-local")
|
||||||
|
@Tag("rest-v2")
|
||||||
public abstract class AbstractRestServicesTestV2
|
public abstract class AbstractRestServicesTestV2
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -234,6 +237,12 @@ public abstract class AbstractRestServicesTestV2
|
||||||
return "Basic " + Base64Utility.encode( ( uid + ":" + password ).getBytes() );
|
return "Basic " + Base64Utility.encode( ( uid + ":" + password ).getBytes() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getUserAuthzHeader(String user) {
|
||||||
|
assertNotNull( getJwtAuthenticator());
|
||||||
|
Token token = getJwtAuthenticator().generateToken( user );
|
||||||
|
return "Bearer " + token.getData( );
|
||||||
|
}
|
||||||
|
|
||||||
public String getAdminAuthzHeader()
|
public String getAdminAuthzHeader()
|
||||||
{
|
{
|
||||||
assertNotNull( getJwtAuthenticator());
|
assertNotNull( getJwtAuthenticator());
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Tag;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.TestInstance;
|
import org.junit.jupiter.api.TestInstance;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
@ -60,6 +61,7 @@ import static org.junit.Assert.*;
|
||||||
@ContextConfiguration(
|
@ContextConfiguration(
|
||||||
locations = {"classpath:/ldap-spring-test.xml"} )
|
locations = {"classpath:/ldap-spring-test.xml"} )
|
||||||
@TestInstance( TestInstance.Lifecycle.PER_CLASS )
|
@TestInstance( TestInstance.Lifecycle.PER_CLASS )
|
||||||
|
@Tag("rest-local")
|
||||||
public class GroupServiceTest
|
public class GroupServiceTest
|
||||||
extends AbstractRestServicesTestV2
|
extends AbstractRestServicesTestV2
|
||||||
{
|
{
|
||||||
|
@ -294,7 +296,7 @@ public class GroupServiceTest
|
||||||
{
|
{
|
||||||
GroupService service = getGroupService( authorizationHeader );
|
GroupService service = getGroupService( authorizationHeader );
|
||||||
|
|
||||||
List<String> allGroups = service.getGroups( Integer.valueOf( 0 ), Integer.valueOf( Integer.MAX_VALUE ) ).getData( ).stream( ).map( group -> group.getName( ) ).collect( Collectors.toList( ) );
|
List<String> allGroups = service.getGroups( Long.valueOf( 0 ), Long.valueOf( Long.MAX_VALUE ) ).getData( ).stream( ).map( group -> group.getName( ) ).collect( Collectors.toList( ) );
|
||||||
|
|
||||||
assertNotNull( allGroups );
|
assertNotNull( allGroups );
|
||||||
assertEquals( 3, allGroups.size( ) );
|
assertEquals( 3, allGroups.size( ) );
|
||||||
|
|
|
@ -18,11 +18,7 @@ package org.apache.archiva.redback.rest.services.v2;
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import io.restassured.RestAssured;
|
|
||||||
import io.restassured.builder.RequestSpecBuilder;
|
|
||||||
import io.restassured.response.Response;
|
import io.restassured.response.Response;
|
||||||
import io.restassured.specification.RequestSpecification;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.junit.jupiter.api.AfterAll;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Tag;
|
import org.junit.jupiter.api.Tag;
|
||||||
|
@ -37,13 +33,12 @@ import java.time.OffsetDateTime;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static io.restassured.RestAssured.*;
|
import static io.restassured.RestAssured.given;
|
||||||
import static io.restassured.http.ContentType.JSON;
|
import static io.restassured.http.ContentType.JSON;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.notNullValue;
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.springframework.core.annotation.MergedAnnotations.from;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Martin Stockhammer <martin_s@apache.org>
|
* @author Martin Stockhammer <martin_s@apache.org>
|
||||||
|
|
|
@ -0,0 +1,366 @@
|
||||||
|
package org.apache.archiva.redback.rest.services.v2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import io.restassured.http.ContentType;
|
||||||
|
import io.restassured.response.Response;
|
||||||
|
import org.apache.archiva.components.apacheds.ApacheDs;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.Group;
|
||||||
|
import org.apache.archiva.redback.rest.services.BaseSetup;
|
||||||
|
import org.apache.archiva.redback.rest.services.LdapInfo;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Tag;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestInstance;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.naming.Context;
|
||||||
|
import javax.naming.NameNotFoundException;
|
||||||
|
import javax.naming.NamingException;
|
||||||
|
import javax.naming.directory.Attributes;
|
||||||
|
import javax.naming.directory.BasicAttribute;
|
||||||
|
import javax.naming.directory.BasicAttributes;
|
||||||
|
import javax.naming.directory.DirContext;
|
||||||
|
import javax.naming.directory.InitialDirContext;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static io.restassured.RestAssured.given;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Martin Stockhammer <martin_s@apache.org>
|
||||||
|
*/
|
||||||
|
@ExtendWith( SpringExtension.class )
|
||||||
|
@ContextConfiguration(
|
||||||
|
locations = {"classpath:/ldap-spring-test.xml"} )
|
||||||
|
@TestInstance( TestInstance.Lifecycle.PER_CLASS )
|
||||||
|
@Tag("rest-native")
|
||||||
|
public class NativeGroupServiceTest extends AbstractNativeRestServices
|
||||||
|
{
|
||||||
|
protected String peopleSuffix;
|
||||||
|
protected String groupSuffix;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Named( value = "apacheDS#test" )
|
||||||
|
private ApacheDs apacheDs;
|
||||||
|
|
||||||
|
private InitialDirContext adminContext;
|
||||||
|
private LdapInfo ldapInfo;
|
||||||
|
|
||||||
|
private List<String> groups =
|
||||||
|
Arrays.asList( "Archiva System Administrator", "Internal Repo Manager", "Internal Repo Observer", "Test Group 1", "Test Group 2", "Test Group 3" );
|
||||||
|
|
||||||
|
public InitialDirContext getAdminContext() throws NamingException
|
||||||
|
{
|
||||||
|
if (this.ldapInfo.isRemote()) {
|
||||||
|
Hashtable<String, String> environment = new Hashtable<>( );
|
||||||
|
|
||||||
|
environment.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||||
|
environment.put(Context.PROVIDER_URL, ldapInfo.getURL());
|
||||||
|
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||||
|
environment.put(Context.SECURITY_PRINCIPAL, ldapInfo.getBindDN());
|
||||||
|
environment.put(Context.SECURITY_CREDENTIALS, ldapInfo.getBindPassword());
|
||||||
|
environment.put("com.sun.jndi.ldap.connect.pool", "true");
|
||||||
|
return new InitialDirContext(environment);
|
||||||
|
} else {
|
||||||
|
return apacheDs.getAdminContext( );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getTestGroupList() {
|
||||||
|
return this.groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getServicePath( )
|
||||||
|
{
|
||||||
|
return "/groups";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getSpringConfigLocation( )
|
||||||
|
{
|
||||||
|
return "classpath*:spring-context.xml,classpath*:META-INF/spring-context.xml,classpath:/ldap-spring-test.xml";
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
void setup( ) throws Exception
|
||||||
|
{
|
||||||
|
setupNative( );
|
||||||
|
this.ldapInfo = BaseSetup.getLdapInfo( );
|
||||||
|
if (!ldapInfo.isRemote()) {
|
||||||
|
peopleSuffix = "ou=People,dc=archiva,dc=apache,dc=org";
|
||||||
|
log.info( "DN Suffix: {}", peopleSuffix );
|
||||||
|
if ( apacheDs.isStopped( ) )
|
||||||
|
{
|
||||||
|
groupSuffix = apacheDs.addSimplePartition( "test", new String[]{"archiva", "apache", "org"} ).getSuffix( );
|
||||||
|
|
||||||
|
log.info( "groupSuffix: {}", groupSuffix );
|
||||||
|
apacheDs.startServer( );
|
||||||
|
if ( !exists( apacheDs.getAdminContext( ), peopleSuffix ) )
|
||||||
|
{
|
||||||
|
BasicAttribute objectClass = new BasicAttribute( "objectClass" );
|
||||||
|
objectClass.add( "top" );
|
||||||
|
objectClass.add( "organizationalUnit" );
|
||||||
|
|
||||||
|
Attributes attributes = new BasicAttributes( true );
|
||||||
|
attributes.put( objectClass );
|
||||||
|
attributes.put( "organizationalUnitName", "foo" );
|
||||||
|
|
||||||
|
apacheDs.getAdminContext( ).createSubcontext( peopleSuffix, attributes );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.peopleSuffix = "ou=People," + ldapInfo.getBaseDN( );
|
||||||
|
this.groupSuffix = ldapInfo.getBaseDN( );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
void shutdown( ) throws Exception
|
||||||
|
{
|
||||||
|
shutdownNative();
|
||||||
|
if (!this.ldapInfo.isRemote())
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
InitialDirContext context = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
context = getAdminContext( );
|
||||||
|
context.unbind( this.peopleSuffix );
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ( context != null ) context.close( );
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
log.error( "Error during context close {}", e.getMessage( ) );
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
apacheDs.stopServer( );
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
log.error( "Could not stop apacheds {}", e.getMessage( ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
log.error( "Could not stop ldap {}", e.getMessage( ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getAdminContext().close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void initLdap( ) throws Exception
|
||||||
|
{
|
||||||
|
removeAllGroups( );
|
||||||
|
createGroups( );
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void cleanupLdap( ) throws NamingException
|
||||||
|
{
|
||||||
|
removeAllGroups( );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean exists( DirContext context, String dn )
|
||||||
|
{
|
||||||
|
Object result = null;
|
||||||
|
try {
|
||||||
|
result = context.lookup( dn );
|
||||||
|
}
|
||||||
|
catch ( NameNotFoundException e ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch ( NamingException e )
|
||||||
|
{
|
||||||
|
log.error( "Unknown error during lookup: {}", e.getMessage( ) );
|
||||||
|
}
|
||||||
|
return result != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeAllGroups( )
|
||||||
|
{
|
||||||
|
InitialDirContext context = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
context = getAdminContext( );
|
||||||
|
for ( String group : getTestGroupList() )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
context.unbind( createGroupDn( group ) );
|
||||||
|
}
|
||||||
|
catch ( NamingException e )
|
||||||
|
{
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch ( NamingException e )
|
||||||
|
{
|
||||||
|
log.error( "Naming exception {}", e.getMessage( ) );
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ( context != null ) context.close( );
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
log.error( "Error during context close {}", e.getMessage( ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createGroupDn( String cn )
|
||||||
|
{
|
||||||
|
return "cn=" + cn + "," + groupSuffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createGroup( DirContext context, String groupName, String dn )
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
if ( !exists( context, dn ) )
|
||||||
|
{
|
||||||
|
Attributes attributes = new BasicAttributes( true );
|
||||||
|
BasicAttribute objectClass = new BasicAttribute( "objectClass" );
|
||||||
|
objectClass.add( "top" );
|
||||||
|
objectClass.add( "groupOfUniqueNames" );
|
||||||
|
attributes.put( objectClass );
|
||||||
|
attributes.put( "cn", groupName );
|
||||||
|
BasicAttribute basicAttribute = new BasicAttribute( "uniquemember" );
|
||||||
|
|
||||||
|
basicAttribute.add( "uid=admin," + peopleSuffix );
|
||||||
|
|
||||||
|
attributes.put( basicAttribute );
|
||||||
|
|
||||||
|
context.createSubcontext( dn, attributes );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log.error( "Group {} exists already", dn );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createGroups( )
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
InitialDirContext context = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
context = getAdminContext( );
|
||||||
|
|
||||||
|
for ( String group : getTestGroupList() )
|
||||||
|
{
|
||||||
|
createGroup( context, group, createGroupDn( group ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if ( context != null )
|
||||||
|
{
|
||||||
|
context.close( );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getGroups() {
|
||||||
|
String token = getAdminToken( );
|
||||||
|
Response response = given( ).spec( getRequestSpec( token ) ).contentType( ContentType.JSON ).when( )
|
||||||
|
.get( ).then( ).statusCode( 200 ).extract( ).response( );
|
||||||
|
assertNotNull( response );
|
||||||
|
List<Group> data = response.body( ).jsonPath( ).getList( "data", Group.class );
|
||||||
|
assertNotNull( data );
|
||||||
|
assertEquals( Integer.valueOf( 0 ), response.body( ).jsonPath( ).get( "pagination.offset" ) );
|
||||||
|
assertEquals( Integer.valueOf( 1000 ), response.body( ).jsonPath( ).get( "pagination.limit" ) );
|
||||||
|
assertEquals( Integer.valueOf( 6 ), response.body( ).jsonPath( ).get( "pagination.totalCount" ) );
|
||||||
|
assertEquals( 6, data.size( ) );
|
||||||
|
String[] values = data.stream( ).map( ldapInfo -> ldapInfo.getName( ) ).sorted( ).collect( Collectors.toList( ) ).toArray( new String[0] );
|
||||||
|
assertArrayEquals( getTestGroupList( ).toArray( new String[0] ), values );
|
||||||
|
assertEquals( "uid=admin," + this.peopleSuffix, data.get( 0 ).getMemberList( ).get( 0 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getGroupsWithLimit() {
|
||||||
|
String token = getAdminToken( );
|
||||||
|
HashMap<String, Object> params = new HashMap<>( );
|
||||||
|
params.put( "limit", Long.valueOf( 3 ) );
|
||||||
|
Response response = given( ).spec( getRequestSpec( token ) ).contentType( ContentType.JSON )
|
||||||
|
.param( "limit", Long.valueOf( 3 ) )
|
||||||
|
.when( )
|
||||||
|
.get( ).then( ).statusCode( 200 ).extract( ).response( );
|
||||||
|
assertNotNull( response );
|
||||||
|
List<Group> data = response.body( ).jsonPath( ).getList( "data", Group.class );
|
||||||
|
assertNotNull( data );
|
||||||
|
assertEquals( Integer.valueOf( 0 ), response.body( ).jsonPath( ).get( "pagination.offset" ) );
|
||||||
|
assertEquals( Integer.valueOf( 3 ), response.body( ).jsonPath( ).get( "pagination.limit" ) );
|
||||||
|
assertEquals( Integer.valueOf( 6 ), response.body( ).jsonPath( ).get( "pagination.totalCount" ) );
|
||||||
|
assertEquals( 3, data.size( ) );
|
||||||
|
String[] values = data.stream( ).map( ldapInfo -> ldapInfo.getName( ) ).sorted( ).collect( Collectors.toList( ) ).toArray( new String[0] );
|
||||||
|
assertArrayEquals( getTestGroupList( ).subList( 0, 3 ).toArray( new String[0] ), values );
|
||||||
|
assertEquals( "uid=admin," + this.peopleSuffix, data.get( 0 ).getMemberList( ).get( 0 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getGroupsWithOffset() {
|
||||||
|
String token = getAdminToken( );
|
||||||
|
Response response = given( ).spec( getRequestSpec( token ) ).contentType( ContentType.JSON )
|
||||||
|
.param( "offset", Long.valueOf( 2 ) )
|
||||||
|
.when( )
|
||||||
|
.get( ).then( ).statusCode( 200 ).extract( ).response( );
|
||||||
|
System.out.println( response.print( ) );
|
||||||
|
assertNotNull( response );
|
||||||
|
List<Group> data = response.body( ).jsonPath( ).getList( "data", Group.class );
|
||||||
|
assertNotNull( data );
|
||||||
|
assertEquals( Integer.valueOf( 2 ), response.body( ).jsonPath( ).get( "pagination.offset" ) );
|
||||||
|
assertEquals( Integer.valueOf( 1000 ), response.body( ).jsonPath( ).get( "pagination.limit" ) );
|
||||||
|
assertEquals( Integer.valueOf( 6 ), response.body( ).jsonPath( ).get( "pagination.totalCount" ) );
|
||||||
|
assertEquals( 4, data.size( ) );
|
||||||
|
String[] values = data.stream( ).map( ldapInfo -> ldapInfo.getName( ) ).sorted( ).collect( Collectors.toList( ) ).toArray( new String[0] );
|
||||||
|
assertArrayEquals( getTestGroupList( ).subList( 2, getTestGroupList().size() ).toArray( new String[0] ), values );
|
||||||
|
assertEquals( "uid=admin," + this.peopleSuffix, data.get( 0 ).getMemberList( ).get( 0 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,528 @@
|
||||||
|
package org.apache.archiva.redback.rest.services.v2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.Operation;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.Permission;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.RequestTokenRequest;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.ResetPasswordRequest;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.TokenResponse;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.User;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.UserRegistrationRequest;
|
||||||
|
import org.apache.archiva.redback.rest.api.services.UserService;
|
||||||
|
import org.apache.archiva.redback.rest.services.FakeCreateAdminService;
|
||||||
|
import org.apache.archiva.redback.rest.services.mock.EmailMessage;
|
||||||
|
import org.apache.archiva.redback.rest.services.mock.MockJavaMailSender;
|
||||||
|
import org.apache.archiva.redback.rest.services.mock.ServicesAssert;
|
||||||
|
import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
|
||||||
|
import org.apache.cxf.jaxrs.client.WebClient;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestInstance;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.ws.rs.ForbiddenException;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Olivier Lamy
|
||||||
|
*/
|
||||||
|
@ExtendWith( SpringExtension.class )
|
||||||
|
@ContextConfiguration(
|
||||||
|
locations = {"classpath:/spring-context.xml"} )
|
||||||
|
@TestInstance( TestInstance.Lifecycle.PER_CLASS )
|
||||||
|
public class UserServiceTest
|
||||||
|
extends AbstractRestServicesTestV2
|
||||||
|
{
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
MockJavaMailSender mockJavaMailSender;
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void cleanup() {
|
||||||
|
mockJavaMailSender.getSendedEmails( ).clear( );
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
void setup( ) throws Exception
|
||||||
|
{
|
||||||
|
super.init( );
|
||||||
|
super.startServer( );
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
void shutdown( ) throws Exception
|
||||||
|
{
|
||||||
|
super.stopServer( );
|
||||||
|
super.destroy( );
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserService getUserService( String authzHeader )
|
||||||
|
{
|
||||||
|
UserService service =
|
||||||
|
JAXRSClientFactory.create( "http://localhost:" + getServerPort( ) + "/" + getRestServicesPath( ) + "/v2/redback/",
|
||||||
|
UserService.class, Collections.singletonList( new JacksonJaxbJsonProvider( ) ) );
|
||||||
|
|
||||||
|
// time out for debuging purpose
|
||||||
|
WebClient.getConfig( service ).getHttpConduit( ).getClient( ).setReceiveTimeout( getTimeout( ) );
|
||||||
|
|
||||||
|
if ( authzHeader != null )
|
||||||
|
{
|
||||||
|
WebClient.client( service ).header( "Authorization", authzHeader );
|
||||||
|
}
|
||||||
|
WebClient.client( service ).header( "Referer", "http://localhost:" + getServerPort( ) );
|
||||||
|
WebClient.client( service ).accept( MediaType.APPLICATION_JSON_TYPE );
|
||||||
|
WebClient.client( service ).type( MediaType.APPLICATION_JSON_TYPE );
|
||||||
|
|
||||||
|
return service;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ping( )
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
Boolean res = getUserService( null ).ping( );
|
||||||
|
assertTrue( res );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getUsers( )
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
String adminHeader = getAdminAuthzHeader( );
|
||||||
|
UserService userService = getUserService( adminHeader );
|
||||||
|
List<User> users = userService.getUsers( );
|
||||||
|
assertNotNull( users );
|
||||||
|
assertFalse( users.isEmpty( ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test()
|
||||||
|
@Disabled
|
||||||
|
public void getUsersWithoutAuthz( )
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
UserService userService = getUserService( null );
|
||||||
|
assertThrows( ForbiddenException.class, ( ) -> {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
userService.getUsers( );
|
||||||
|
}
|
||||||
|
catch ( ForbiddenException e )
|
||||||
|
{
|
||||||
|
assertEquals( 403, e.getResponse( ).getStatus( ) );
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getNoPermissionNotAuthz( )
|
||||||
|
{
|
||||||
|
|
||||||
|
UserService userService = getUserService( null );
|
||||||
|
WebClient.client( userService ).header( "Origin", "http://localhost/myrequest" );
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
getFakeCreateAdminService( ).testAuthzWithoutKarmasNeededButAuthz( );
|
||||||
|
}
|
||||||
|
catch ( ForbiddenException e )
|
||||||
|
{
|
||||||
|
assertEquals( 403, e.getResponse( ).getStatus( ) );
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getNoPermissionAuthz( )
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FakeCreateAdminService service = getFakeCreateAdminService( );
|
||||||
|
|
||||||
|
WebClient.client( service ).header( "Authorization", getAdminAuthzHeader( ) );
|
||||||
|
|
||||||
|
assertTrue( service.testAuthzWithoutKarmasNeededButAuthz( ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
catch ( ForbiddenException e )
|
||||||
|
{
|
||||||
|
assertEquals( 403, e.getResponse( ).getStatus( ) );
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Disabled
|
||||||
|
public void register( )
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mockJavaMailSender.getSendedEmails( ).clear( );
|
||||||
|
UserService service = getUserService( getAdminAuthzHeader( ) );
|
||||||
|
User u = new User( );
|
||||||
|
u.setFullName( "the toto" );
|
||||||
|
u.setUsername( "toto" );
|
||||||
|
u.setEmail( "toto@toto.fr" );
|
||||||
|
u.setPassword( "toto123" );
|
||||||
|
u.setConfirmPassword( "toto123" );
|
||||||
|
String key = service.registerUser( new UserRegistrationRequest( u, "http://wine.fr/bordeaux" ) ).getKey( );
|
||||||
|
|
||||||
|
assertNotEquals( "-1", key );
|
||||||
|
|
||||||
|
ServicesAssert assertService =
|
||||||
|
JAXRSClientFactory.create( "http://localhost:" + getServerPort( ) + "/" + getRestServicesPath( ) + "/testsService/",
|
||||||
|
ServicesAssert.class,
|
||||||
|
Collections.singletonList( new JacksonJaxbJsonProvider( ) ) );
|
||||||
|
|
||||||
|
List<EmailMessage> emailMessages = assertService.getEmailMessageSended( );
|
||||||
|
assertEquals( 1, emailMessages.size( ) );
|
||||||
|
assertEquals( "toto@toto.fr", emailMessages.get( 0 ).getTos( ).get( 0 ) );
|
||||||
|
|
||||||
|
assertEquals( "Welcome", emailMessages.get( 0 ).getSubject( ) );
|
||||||
|
String messageContent = emailMessages.get( 0 ).getText( );
|
||||||
|
|
||||||
|
log.info( "messageContent: {}", messageContent );
|
||||||
|
|
||||||
|
assertNotNull( messageContent );
|
||||||
|
assertTrue( messageContent.contains( "Use the following URL to validate your account." ) );
|
||||||
|
assertTrue( messageContent.contains( "http://wine.fr/bordeaux" ) );
|
||||||
|
assertTrue( messageContent.contains( "toto" ) );
|
||||||
|
|
||||||
|
assertTrue( service.validateUserFromKey( key ).isSuccess( ) );
|
||||||
|
|
||||||
|
service = getUserService( getAdminAuthzHeader( ) );
|
||||||
|
|
||||||
|
u = service.getUser( "toto" );
|
||||||
|
|
||||||
|
assertNotNull( u );
|
||||||
|
assertTrue( u.isValidated( ) );
|
||||||
|
assertTrue( u.isPasswordChangeRequired( ) );
|
||||||
|
|
||||||
|
assertTrue( service.validateUserFromKey( key ).isSuccess( ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
log.error( e.getMessage( ), e );
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
deleteUserQuietly( "toto" );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void registerNoUrl( )
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UserService service = getUserService( getAdminAuthzHeader( ) );
|
||||||
|
User u = new User( );
|
||||||
|
u.setFullName( "the toto" );
|
||||||
|
u.setUsername( "toto" );
|
||||||
|
u.setEmail( "toto@toto.fr" );
|
||||||
|
u.setPassword( "toto123" );
|
||||||
|
u.setConfirmPassword( "toto123" );
|
||||||
|
String key = service.registerUser( new UserRegistrationRequest( u, null ) ).getKey( );
|
||||||
|
|
||||||
|
assertNotEquals( "-1", key );
|
||||||
|
|
||||||
|
ServicesAssert assertService =
|
||||||
|
JAXRSClientFactory.create( "http://localhost:" + getServerPort( ) + "/" + getRestServicesPath( ) + "/testsService/",
|
||||||
|
ServicesAssert.class,
|
||||||
|
Collections.singletonList( new JacksonJaxbJsonProvider( ) ) );
|
||||||
|
|
||||||
|
List<EmailMessage> emailMessages = assertService.getEmailMessageSended( );
|
||||||
|
assertEquals( 1, emailMessages.size( ) );
|
||||||
|
assertEquals( "toto@toto.fr", emailMessages.get( 0 ).getTos( ).get( 0 ) );
|
||||||
|
|
||||||
|
assertEquals( "Welcome", emailMessages.get( 0 ).getSubject( ) );
|
||||||
|
String messageContent = emailMessages.get( 0 ).getText( );
|
||||||
|
|
||||||
|
log.info( "messageContent: {}", messageContent );
|
||||||
|
assertNotNull( messageContent );
|
||||||
|
assertTrue( messageContent.contains( "Use the following URL to validate your account." ) );
|
||||||
|
assertTrue( messageContent.contains( "http://localhost:" + getServerPort( ) ) );
|
||||||
|
assertTrue( messageContent.toLowerCase( ).contains( "toto" ) );
|
||||||
|
|
||||||
|
assertTrue( service.validateUserFromKey( key ).isSuccess( ) );
|
||||||
|
|
||||||
|
service = getUserService( getAdminAuthzHeader( ) );
|
||||||
|
|
||||||
|
u = service.getUser( "toto" );
|
||||||
|
|
||||||
|
assertNotNull( u );
|
||||||
|
assertTrue( u.isValidated( ) );
|
||||||
|
assertTrue( u.isPasswordChangeRequired( ) );
|
||||||
|
|
||||||
|
assertTrue( service.validateUserFromKey( key ).isSuccess( ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
log.error( e.getMessage( ), e );
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
deleteUserQuietly( "toto" );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Disabled
|
||||||
|
public void resetPassword( )
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mockJavaMailSender.getSendedEmails().clear();
|
||||||
|
|
||||||
|
UserService service = getUserService( getAdminAuthzHeader( ) );
|
||||||
|
User u = new User( );
|
||||||
|
u.setFullName( "the toto" );
|
||||||
|
u.setUsername( "toto" );
|
||||||
|
u.setEmail( "toto@toto.fr" );
|
||||||
|
u.setPassword( "toto123" );
|
||||||
|
u.setConfirmPassword( "toto123" );
|
||||||
|
String key = service.registerUser( new UserRegistrationRequest( u, "http://wine.fr/bordeaux" ) ).getKey( );
|
||||||
|
|
||||||
|
assertNotEquals( "-1", key );
|
||||||
|
|
||||||
|
ServicesAssert assertService =
|
||||||
|
JAXRSClientFactory.create( "http://localhost:" + getServerPort( ) + "/" + getRestServicesPath( ) + "/testsService/",
|
||||||
|
ServicesAssert.class,
|
||||||
|
Collections.singletonList( new JacksonJaxbJsonProvider( ) ) );
|
||||||
|
|
||||||
|
WebClient.client( assertService ).accept( MediaType.APPLICATION_JSON_TYPE );
|
||||||
|
WebClient.client( assertService ).type( MediaType.APPLICATION_JSON_TYPE );
|
||||||
|
|
||||||
|
List<EmailMessage> emailMessages = assertService.getEmailMessageSended( );
|
||||||
|
assertEquals( 1, emailMessages.size( ) );
|
||||||
|
assertEquals( "toto@toto.fr", emailMessages.get( 0 ).getTos( ).get( 0 ) );
|
||||||
|
|
||||||
|
assertEquals( "Welcome", emailMessages.get( 0 ).getSubject( ) );
|
||||||
|
assertTrue(
|
||||||
|
emailMessages.get( 0 ).getText( ).contains( "Use the following URL to validate your account." ) );
|
||||||
|
|
||||||
|
assertTrue( service.validateUserFromKey( key ).isSuccess( ) );
|
||||||
|
|
||||||
|
service = getUserService( getAdminAuthzHeader( ) );
|
||||||
|
|
||||||
|
u = service.getUser( "toto" );
|
||||||
|
|
||||||
|
assertNotNull( u );
|
||||||
|
assertTrue( u.isValidated( ) );
|
||||||
|
assertTrue( u.isPasswordChangeRequired( ) );
|
||||||
|
|
||||||
|
assertTrue( service.validateUserFromKey( key ).isSuccess( ) );
|
||||||
|
|
||||||
|
assertTrue( service.resetPassword( new ResetPasswordRequest( "toto", "http://foo.fr/bar" ) ).isSuccess( ) );
|
||||||
|
|
||||||
|
emailMessages = assertService.getEmailMessageSended( );
|
||||||
|
assertEquals( 2, emailMessages.size( ) );
|
||||||
|
assertEquals( "toto@toto.fr", emailMessages.get( 1 ).getTos( ).get( 0 ) );
|
||||||
|
|
||||||
|
String messageContent = emailMessages.get( 1 ).getText( );
|
||||||
|
|
||||||
|
assertNotNull( messageContent );
|
||||||
|
assertTrue( messageContent.contains( "Password Reset" ) );
|
||||||
|
assertTrue( messageContent.contains( "Username: toto" ) );
|
||||||
|
assertTrue( messageContent.contains( "http://foo.fr/bar" ) );
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
log.error( e.getMessage( ), e );
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
deleteUserQuietly( "toto" );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteUserQuietly( String userName )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
getUserService( getAdminAuthzHeader( ) ).deleteUser( userName );
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
log.warn( "ignore fail to delete user " + e.getMessage( ), e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getAdminPermissions( )
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
Collection<Permission> permissions = getUserService( getAdminAuthzHeader( ) ).getUserPermissions( "admin" );
|
||||||
|
log.info( "admin permisssions: {}", permissions );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getGuestPermissions( )
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
createGuestIfNeeded( );
|
||||||
|
Collection<Permission> permissions = getUserService( null ).getCurrentUserPermissions( );
|
||||||
|
log.info( "guest permisssions: {}", permissions );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getAdminOperations( )
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
Collection<Operation> operations = getUserService( getAdminAuthzHeader( ) ).getUserOperations( "admin" );
|
||||||
|
log.info( "admin operations: {}", operations );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getGuestOperations( )
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
createGuestIfNeeded( );
|
||||||
|
Collection<Operation> operations = getUserService( null ).getCurrentUserOperations( );
|
||||||
|
log.info( "guest operations: {}", operations );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateMe( )
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
User u = new User( );
|
||||||
|
u.setFullName( "the toto" );
|
||||||
|
u.setUsername( "toto" );
|
||||||
|
u.setEmail( "toto@toto.fr" );
|
||||||
|
u.setPassword( "toto123" );
|
||||||
|
u.setConfirmPassword( "toto123" );
|
||||||
|
u.setValidated( true );
|
||||||
|
getUserService( getAdminAuthzHeader( ) ).createUser( u );
|
||||||
|
|
||||||
|
u.setFullName( "the toto123" );
|
||||||
|
u.setEmail( "toto@titi.fr" );
|
||||||
|
u.setPassword( "toto1234" );
|
||||||
|
u.setPreviousPassword( "toto123" );
|
||||||
|
getUserService( getUserAuthzHeader( "toto" ) ).updateMe( u );
|
||||||
|
|
||||||
|
u = getUserService( getAdminAuthzHeader( ) ).getUser( "toto" );
|
||||||
|
assertEquals( "the toto123", u.getFullName( ) );
|
||||||
|
assertEquals( "toto@titi.fr", u.getEmail( ) );
|
||||||
|
|
||||||
|
u.setFullName( "the toto1234" );
|
||||||
|
u.setEmail( "toto@tititi.fr" );
|
||||||
|
u.setPassword( "toto12345" );
|
||||||
|
u.setPreviousPassword( "toto1234" );
|
||||||
|
getUserService( getUserAuthzHeader( "toto" )) .updateMe( u );
|
||||||
|
|
||||||
|
u = getUserService( getAdminAuthzHeader( ) ).getUser( "toto" );
|
||||||
|
assertEquals( "the toto1234", u.getFullName( ) );
|
||||||
|
assertEquals( "toto@tititi.fr", u.getEmail( ) );
|
||||||
|
|
||||||
|
getUserService( getAdminAuthzHeader( ) ).deleteUser( "toto" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Disabled
|
||||||
|
public void lockUnlockUser( )
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
// START SNIPPET: create-user
|
||||||
|
User user = new User( "toto", "toto the king", "toto@toto.fr", false, false );
|
||||||
|
user.setPassword( "foo123" );
|
||||||
|
user.setPermanent( false );
|
||||||
|
user.setPasswordChangeRequired( false );
|
||||||
|
user.setLocked( false );
|
||||||
|
user.setValidated( true );
|
||||||
|
UserService userService = getUserService( getAdminAuthzHeader( ) );
|
||||||
|
userService.createUser( user );
|
||||||
|
// END SNIPPET: create-user
|
||||||
|
user = userService.getUser( "toto" );
|
||||||
|
assertNotNull( user );
|
||||||
|
assertEquals( "toto the king", user.getFullName( ) );
|
||||||
|
assertEquals( "toto@toto.fr", user.getEmail( ) );
|
||||||
|
TokenResponse result = getLoginServiceV2( null ).logIn( new RequestTokenRequest( "toto", "foo123" ) );
|
||||||
|
getLoginServiceV2( "Bearer " + result.getAccessToken( ) ).pingWithAutz( );
|
||||||
|
|
||||||
|
userService.lockUser( "toto" );
|
||||||
|
|
||||||
|
assertTrue( userService.getUser( "toto" ).isLocked( ) );
|
||||||
|
|
||||||
|
userService.unlockUser( "toto" );
|
||||||
|
|
||||||
|
assertFalse( userService.getUser( "toto" ).isLocked( ) );
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
getUserService( getAdminAuthzHeader( ) ).deleteUser( "toto" );
|
||||||
|
getUserService( getAdminAuthzHeader( ) ).removeFromCache( "toto" );
|
||||||
|
assertNull( getUserService( getAdminAuthzHeader( ) ).getUser( "toto" ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void guestUserCreate( )
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
UserService userService = getUserService( getAdminAuthzHeader( ) );
|
||||||
|
assertNull( userService.getGuestUser( ) );
|
||||||
|
assertNull( userService.createGuestUser( ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void createGuestIfNeeded( )
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
UserService userService = getUserService( getAdminAuthzHeader( ) );
|
||||||
|
if ( userService.getGuestUser( ) == null )
|
||||||
|
{
|
||||||
|
userService.createGuestUser( );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -32,7 +32,7 @@
|
||||||
-->
|
-->
|
||||||
<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
|
<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
|
||||||
|
|
||||||
<jaxrs:server id="testServices" address="/fakeCreateAdminService">
|
<jaxrs:server name="testServices" address="/fakeCreateAdminService">
|
||||||
<jaxrs:serviceBeans>
|
<jaxrs:serviceBeans>
|
||||||
<ref bean="fakeCreateAdminService"/>
|
<ref bean="fakeCreateAdminService"/>
|
||||||
</jaxrs:serviceBeans>
|
</jaxrs:serviceBeans>
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
</jaxrs:server>
|
</jaxrs:server>
|
||||||
|
|
||||||
<jaxrs:server id="services" address="/testsService">
|
<jaxrs:server name="services" address="/testsService">
|
||||||
<jaxrs:serviceBeans>
|
<jaxrs:serviceBeans>
|
||||||
<ref bean="servicesAssert"/>
|
<ref bean="servicesAssert"/>
|
||||||
</jaxrs:serviceBeans>
|
</jaxrs:serviceBeans>
|
||||||
|
|
Loading…
Reference in New Issue