This is an automated email from the ASF dual-hosted git repository.
martin_s pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/archiva-redback-core.git
The following commit(s) were added to refs/heads/master by this push:
new 87b089a Adding new v2 REST services
87b089a is described below
commit 87b089a695eb44c85fb4722f5705c0ba967bb365
Author: Martin Stockhammer <[email protected]>
AuthorDate: Tue Jul 7 22:34:31 2020 +0200
Adding new v2 REST services
---
pom.xml | 5 +
.../redback/rest/api/model/LoginRequest.java | 2 +-
.../redback/rest/api/model/PagedResult.java | 17 ++-
.../redback/rest/api/model/PaginationInfo.java | 4 +-
.../archiva/redback/rest/api/model/Token.java | 126 +++++++++++++++++++++
.../model/{PaginationInfo.java => UserLogin.java} | 48 ++++----
.../redback/rest/api/services/LoginService.java | 10 +-
...oginService.java => AuthenticationService.java} | 28 +++--
.../redback/rest/api/services/v2/GroupService.java | 7 +-
.../redback-rest/redback-rest-services/pom.xml | 4 +
.../services/DefaultLdapGroupMappingService.java | 2 +
.../redback/rest/services/DefaultLoginService.java | 6 +-
.../interceptors/JacksonJsonConfigurator.java | 7 ++
.../DefaultAuthenticationService.java} | 60 ++++++----
.../rest/services/v2/DefaultGroupService.java | 11 +-
.../src/main/resources/META-INF/spring-context.xml | 11 +-
.../rest/services/AbstractRestServicesTest.java | 22 ++++
.../services/v2/AuthenticationServiceTest.java | 112 ++++++++++++++++++
.../redback/rest/services/v2/GroupServiceTest.java | 4 +-
19 files changed, 400 insertions(+), 86 deletions(-)
diff --git a/pom.xml b/pom.xml
index a12e8af..205e9fa 100644
--- a/pom.xml
+++ b/pom.xml
@@ -525,6 +525,11 @@
<version>${jackson.version}</version>
</dependency>
<dependency>
+ <groupId>com.fasterxml.jackson.datatype</groupId>
+ <artifactId>jackson-datatype-jsr310</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
+ <dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
diff --git
a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/LoginRequest.java
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/LoginRequest.java
index ae7b0d1..825ec88 100644
---
a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/LoginRequest.java
+++
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/LoginRequest.java
@@ -70,7 +70,7 @@ public class LoginRequest
final StringBuilder sb = new StringBuilder();
sb.append( "LoginRequest" );
sb.append( "{username='" ).append( username ).append( '\'' );
- sb.append( ", password='" ).append( password ).append( '\'' );
+ sb.append( ", password='" ).append( "*********" ).append( '\'' );
sb.append( '}' );
return sb.toString();
}
diff --git
a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/PagedResult.java
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/PagedResult.java
index c0af729..3168110 100644
---
a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/PagedResult.java
+++
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/PagedResult.java
@@ -22,37 +22,34 @@ import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
/**
+ * A Paged result puts the data into an envelope
* @author Martin Stockhammer <[email protected]>
*/
@XmlRootElement(name="pagedResult")
public class PagedResult<T>
{
PaginationInfo pagination;
- List<T> data;
+ T data;
public PagedResult() {
}
- public PagedResult( long totalCount, long offset, long limit, List<T> data
) {
+ public PagedResult( long totalCount, long offset, long limit, T data ) {
this.data = data;
this.pagination = new PaginationInfo( totalCount, offset, limit );
}
- public static final <T> PagedResult<T> ofAllElements(long offset, long
limit, List<T> elements) {
- return new PagedResult( elements.size( ), offset, limit,
elements.subList( (int)offset, (int)offset + (int)limit ) );
+ public static final <T> PagedResult<T> of(long totalSize, long offset,
long limit, T element) {
+ return new PagedResult( totalSize, offset, limit, element);
}
- public static final <T> PagedResult<T> ofSegment(long totalSize, long
offset, long limit, List<T> elements) {
- return new PagedResult( totalSize, offset, limit, elements);
- }
-
- public List<T> getData( )
+ public T getData( )
{
return data;
}
- public void setData( List<T> data )
+ public void setData( T data )
{
this.data = data;
}
diff --git
a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/PaginationInfo.java
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/PaginationInfo.java
index 073ea18..9d5dab5 100644
---
a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/PaginationInfo.java
+++
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/PaginationInfo.java
@@ -22,6 +22,9 @@ import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
+ *
+ * Informational attributes for pagination.
+ *
* @author Martin Stockhammer <[email protected]>
*/
@XmlRootElement(name="pagination")
@@ -42,7 +45,6 @@ public class PaginationInfo
this.limit = limit;
}
- @XmlElement(name="total_count")
public long getTotalCount( )
{
return totalCount;
diff --git
a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/Token.java
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/Token.java
new file mode 100644
index 0000000..2baaa43
--- /dev/null
+++
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/Token.java
@@ -0,0 +1,126 @@
+package org.apache.archiva.redback.rest.api.model;
+
+/*
+ * 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.archiva.redback.keys.AuthenticationKey;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import java.time.Instant;
+import java.util.Date;
+
+/**
+ * Represents a authentication token.
+ * @author Martin Stockhammer <[email protected]>
+ * @since 3.0
+ */
+@XmlRootElement( name = "token" )
+public class Token
+{
+ String key;
+ Instant created;
+ Instant expires;
+ String principal;
+ String purpose;
+
+ public Token( )
+ {
+ }
+
+ public static Token of( AuthenticationKey key ) {
+ Token token = new Token( );
+ token.setKey( key.getKey() );
+ token.setCreated( key.getDateCreated().toInstant() );
+ token.setExpires( key.getDateExpires().toInstant() );
+ token.setPrincipal( key.getForPrincipal() );
+ token.setPurpose( key.getPurpose() );
+ return token;
+ }
+
+ public static Token of( String key, Date created, Date expires, String
principal, String purpose)
+ {
+ Token token = new Token( );
+ token.setKey( key );
+ token.setCreated( created.toInstant( ) );
+ token.setExpires( expires.toInstant( ) );
+ token.setPrincipal( principal );
+ token.setPrincipal( purpose );
+ return token;
+ }
+
+ public static Token of( String key, Instant created, Instant expires,
String principal, String purpose )
+ {
+ Token token = new Token( );
+ token.setKey( key );
+ token.setCreated( created );
+ token.setExpires( expires );
+ token.setPrincipal( principal );
+ token.setPrincipal( purpose );
+ return token;
+ }
+
+ public String getKey( )
+ {
+ return key;
+ }
+
+ public void setKey( String key )
+ {
+ this.key = key;
+ }
+
+ public Instant getCreated( )
+ {
+ return created;
+ }
+
+ public void setCreated( Instant created )
+ {
+ this.created = created;
+ }
+
+ public Instant getExpires( )
+ {
+ return expires;
+ }
+
+ public void setExpires( Instant expires )
+ {
+ this.expires = expires;
+ }
+
+ public String getPrincipal( )
+ {
+ return principal;
+ }
+
+ public void setPrincipal( String principal )
+ {
+ this.principal = principal;
+ }
+
+ public String getPurpose( )
+ {
+ return purpose;
+ }
+
+ public void setPurpose( String purpose )
+ {
+ this.purpose = purpose;
+ }
+}
diff --git
a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/PaginationInfo.java
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/UserLogin.java
similarity index 50%
copy from
redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/PaginationInfo.java
copy to
redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/UserLogin.java
index 073ea18..ffae37a 100644
---
a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/PaginationInfo.java
+++
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/UserLogin.java
@@ -18,58 +18,54 @@ package org.apache.archiva.redback.rest.api.model;
* under the License.
*/
-import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
+import java.util.Base64;
/**
* @author Martin Stockhammer <[email protected]>
*/
-@XmlRootElement(name="pagination")
-public class PaginationInfo
+@XmlRootElement(name="userLogin")
+public class UserLogin extends User
{
- long totalCount;
- long offset;
- long limit;
- public PaginationInfo() {
+ String authToken;
+ String base64AuthToken;
- }
-
- public PaginationInfo( long totalCount, long offset, long limit )
+ public UserLogin( )
{
- this.totalCount = totalCount;
- this.offset = offset;
- this.limit = limit;
}
- @XmlElement(name="total_count")
- public long getTotalCount( )
+ public UserLogin( String username, String fullName, String email, boolean
validated, boolean locked, String authToken )
{
- return totalCount;
+ super( username, fullName, email, validated, locked );
+ this.authToken = authToken;
+ this.base64AuthToken = Base64.getEncoder( ).encodeToString(
authToken.getBytes( ) );
}
- public void setTotalCount( long totalCount )
+ public UserLogin( org.apache.archiva.redback.users.User user, String
authToken )
{
- this.totalCount = totalCount;
+ super( user );
+ this.authToken = authToken;
+ this.base64AuthToken = Base64.getEncoder( ).encodeToString(
authToken.getBytes( ) );
}
- public long getOffset( )
+ public String getAuthToken( )
{
- return offset;
+ return authToken;
}
- public void setOffset( long offset )
+ public void setAuthToken( String authToken )
{
- this.offset = offset;
+ this.authToken = authToken;
}
- public long getLimit( )
+ public String getBase64AuthToken( )
{
- return limit;
+ return base64AuthToken;
}
- public void setLimit( long limit )
+ public void setBase64AuthToken( String base64AuthToken )
{
- this.limit = limit;
+ this.base64AuthToken = base64AuthToken;
}
}
diff --git
a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/LoginService.java
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/LoginService.java
index 1ff1dcd..6f8b448 100644
---
a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/LoginService.java
+++
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/LoginService.java
@@ -19,6 +19,7 @@ package org.apache.archiva.redback.rest.api.services;
* under the License.
*/
+import io.swagger.v3.oas.annotations.Operation;
import org.apache.archiva.redback.authorization.RedbackAuthorization;
import org.apache.archiva.redback.keys.AuthenticationKey;
import org.apache.archiva.redback.rest.api.model.ActionStatus;
@@ -34,20 +35,23 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
+@Deprecated
@Path( "/loginService/" )
public interface LoginService
{
+ @Operation( deprecated = true )
@Path( "addAuthenticationKey" )
@GET
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML,
MediaType.TEXT_PLAIN } )
@RedbackAuthorization( noRestriction = true )
- AuthenticationKeyResult addAuthenticationKey( @QueryParam( "providerKey" )
String providedKey,
+ String addAuthenticationKey( @QueryParam( "providerKey" ) String
providedKey,
@QueryParam( "principal" )
String principal, @QueryParam( "purpose" ) String purpose,
@QueryParam(
"expirationMinutes" ) int expirationMinutes )
throws RedbackServiceException;
+ @Operation( deprecated = true )
@Path( "ping" )
@GET
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML,
MediaType.TEXT_PLAIN } )
@@ -56,6 +60,7 @@ public interface LoginService
throws RedbackServiceException;
+ @Operation( deprecated = true )
@Path( "pingWithAutz" )
@GET
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML,
MediaType.TEXT_PLAIN } )
@@ -67,6 +72,7 @@ public interface LoginService
* check username/password and create a http session.
* So no more need of reuse username/password for all ajaxRequest
*/
+ @Operation( deprecated = true )
@Path( "logIn" )
@POST
@RedbackAuthorization( noRestriction = true, noPermission = true )
@@ -78,6 +84,7 @@ public interface LoginService
* simply check if current user has an http session opened with authz
passed and return user data
* @since 1.4
*/
+ @Operation( deprecated = true )
@Path( "isLogged" )
@GET
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
@@ -89,6 +96,7 @@ public interface LoginService
* clear user http session
* @since 1.4
*/
+ @Operation( deprecated = true )
@Path( "logout" )
@GET
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML,
MediaType.TEXT_PLAIN } )
diff --git
a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/LoginService.java
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/AuthenticationService.java
similarity index 74%
rename from
redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/LoginService.java
rename to
redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/AuthenticationService.java
index ad77713..c518be4 100644
---
a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/LoginService.java
+++
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/AuthenticationService.java
@@ -24,7 +24,9 @@ import org.apache.archiva.redback.rest.api.model.ActionStatus;
import org.apache.archiva.redback.rest.api.model.AuthenticationKeyResult;
import org.apache.archiva.redback.rest.api.model.LoginRequest;
import org.apache.archiva.redback.rest.api.model.PingResult;
+import org.apache.archiva.redback.rest.api.model.Token;
import org.apache.archiva.redback.rest.api.model.User;
+import org.apache.archiva.redback.rest.api.model.UserLogin;
import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
import javax.ws.rs.GET;
@@ -34,23 +36,27 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
+/**
+ * Version 2 of authentication service
+ */
@Path( "/auth" )
-public interface LoginService
+public interface AuthenticationService
{
@Path( "requestkey" )
@GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML,
MediaType.TEXT_PLAIN } )
+ @Produces( { MediaType.APPLICATION_JSON } )
@RedbackAuthorization( noRestriction = true )
- AuthenticationKeyResult addAuthenticationKey( @QueryParam( "providerKey" )
String providedKey,
- @QueryParam( "principal" )
String principal, @QueryParam( "purpose" ) String purpose,
- @QueryParam(
"expirationMinutes" ) int expirationMinutes )
+ Token requestOnetimeToken( @QueryParam( "providerKey" ) String providedKey,
+ @QueryParam( "principal" ) String principal,
+ @QueryParam( "purpose" ) String purpose,
+ @QueryParam( "expirationSeconds" ) int
expirationSeconds )
throws RedbackServiceException;
@Path( "ping" )
@GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML,
MediaType.TEXT_PLAIN } )
+ @Produces( { MediaType.APPLICATION_JSON } )
@RedbackAuthorization( noRestriction = true )
PingResult ping()
throws RedbackServiceException;
@@ -58,7 +64,7 @@ public interface LoginService
@Path( "ping/authenticated" )
@GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML,
MediaType.TEXT_PLAIN } )
+ @Produces( { MediaType.APPLICATION_JSON } )
@RedbackAuthorization( noRestriction = false, noPermission = true )
PingResult pingWithAutz()
throws RedbackServiceException;
@@ -70,8 +76,8 @@ public interface LoginService
@Path( "authenticate" )
@POST
@RedbackAuthorization( noRestriction = true, noPermission = true )
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML,
MediaType.TEXT_PLAIN } )
- User logIn( LoginRequest loginRequest )
+ @Produces( { MediaType.APPLICATION_JSON } )
+ UserLogin logIn( LoginRequest loginRequest )
throws RedbackServiceException;
/**
@@ -80,7 +86,7 @@ public interface LoginService
*/
@Path( "isAuthenticated" )
@GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
+ @Produces( { MediaType.APPLICATION_JSON } )
@RedbackAuthorization( noRestriction = true )
User isLogged()
throws RedbackServiceException;
@@ -91,7 +97,7 @@ public interface LoginService
*/
@Path( "logout" )
@GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML,
MediaType.TEXT_PLAIN } )
+ @Produces( { MediaType.APPLICATION_JSON } )
@RedbackAuthorization( noRestriction = true, noPermission = true )
ActionStatus logout()
throws RedbackServiceException;
diff --git
a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/GroupService.java
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/GroupService.java
index 5274986..ed754ab 100644
---
a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/GroupService.java
+++
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/GroupService.java
@@ -53,6 +53,7 @@ import java.util.List;
public interface GroupService
{
+
@Path( "" )
@GET
@Produces( {MediaType.APPLICATION_JSON} )
@@ -62,8 +63,8 @@ public interface GroupService
@ApiResponse( description = "List of group objects. The number of
returned results depend on the pagination parameters offset and limit." )
}
)
- PagedResult<Group> getGroups( @QueryParam( "offset" ) @DefaultValue( "0" )
Long offset,
- @QueryParam( "limit" ) @DefaultValue( value
= Long.MAX_VALUE+"" ) Long limit)
+ PagedResult<List<Group>> getGroups( @QueryParam( "offset" ) @DefaultValue(
"0" ) Integer offset,
+ @QueryParam( "limit" ) @DefaultValue( value
= Integer.MAX_VALUE+"" ) Integer limit)
throws RedbackServiceException;
@@ -87,7 +88,7 @@ public interface GroupService
@RedbackAuthorization( permissions =
RedbackRoleConstants.CONFIGURATION_EDIT_OPERATION )
@Operation( summary = "Adds a group mapping",
responses = {
- @ApiResponse( description = "The status of the add action" ),
+ @ApiResponse( responseCode = "201", description = "The status of
the add action" ),
@ApiResponse( responseCode = "405", description = "Invalid input" )
}
)
diff --git a/redback-integrations/redback-rest/redback-rest-services/pom.xml
b/redback-integrations/redback-rest/redback-rest-services/pom.xml
index d668224..ee4a0b8 100644
--- a/redback-integrations/redback-rest/redback-rest-services/pom.xml
+++ b/redback-integrations/redback-rest/redback-rest-services/pom.xml
@@ -146,6 +146,10 @@
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
+ <groupId>com.fasterxml.jackson.datatype</groupId>
+ <artifactId>jackson-datatype-jsr310</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<scope>test</scope>
diff --git
a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/DefaultLdapGroupMappingService.java
b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/DefaultLdapGroupMappingService.java
index ff554b3..b544b32 100644
---
a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/DefaultLdapGroupMappingService.java
+++
b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/DefaultLdapGroupMappingService.java
@@ -46,9 +46,11 @@ import java.util.Map;
import java.util.stream.Collectors;
/**
+ * @deprecated Use new API version {@link
org.apache.archiva.redback.rest.services.v2.DefaultGroupService}
* @author Olivier Lamy
* @since 2.1
*/
+@Deprecated
@Service("ldapGroupMappingService#rest")
public class DefaultLdapGroupMappingService
implements LdapGroupMappingService
diff --git
a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/DefaultLoginService.java
b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/DefaultLoginService.java
index 170635b..a3f5055 100644
---
a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/DefaultLoginService.java
+++
b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/DefaultLoginService.java
@@ -61,9 +61,11 @@ import java.util.List;
import java.util.TimeZone;
/**
+ * @deprecated You should use new REST API version {@link
org.apache.archiva.redback.rest.api.services.v2.AuthenticationService}
* @author Olivier Lamy
* @since 1.3
*/
+@Deprecated
@Service( "loginService#rest" )
public class DefaultLoginService
implements LoginService
@@ -90,7 +92,7 @@ public class DefaultLoginService
}
- public AuthenticationKeyResult addAuthenticationKey( String providedKey,
String principal, String purpose, int expirationMinutes )
+ public String addAuthenticationKey( String providedKey, String principal,
String purpose, int expirationMinutes )
throws RedbackServiceException
{
KeyManager keyManager = securitySystem.getKeyManager();
@@ -121,7 +123,7 @@ public class DefaultLoginService
keyManager.addKey( key );
- return new AuthenticationKeyResult( key.getKey( ) );
+ return key.getKey( );
}
public PingResult ping()
diff --git
a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/JacksonJsonConfigurator.java
b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/JacksonJsonConfigurator.java
index da24a70..04c0c88 100644
---
a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/JacksonJsonConfigurator.java
+++
b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/JacksonJsonConfigurator.java
@@ -21,6 +21,8 @@ package org.apache.archiva.redback.rest.services.interceptors;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
import org.eclipse.jetty.util.annotation.Name;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -28,6 +30,7 @@ import org.springframework.stereotype.Service;
import javax.inject.Inject;
import javax.inject.Named;
+import java.text.SimpleDateFormat;
/**
* to setup some ObjectMapper configuration
@@ -46,6 +49,10 @@ public class JacksonJsonConfigurator
{
log.info( "configure jackson ObjectMapper" );
objectMapper.disable(
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES );
+ objectMapper.setAnnotationIntrospector( new
JaxbAnnotationIntrospector( objectMapper.getTypeFactory() ) );
+ objectMapper.registerModule( new JavaTimeModule( ) );
+ objectMapper.setDateFormat( new SimpleDateFormat(
"yyyyMMdd'T'HHmmss.SSSZ" ) );
+
xmlMapper.disable( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES );
}
diff --git
a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/DefaultLoginService.java
b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultAuthenticationService.java
similarity index 83%
copy from
redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/DefaultLoginService.java
copy to
redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultAuthenticationService.java
index 170635b..1c93361 100644
---
a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/DefaultLoginService.java
+++
b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultAuthenticationService.java
@@ -1,4 +1,4 @@
-package org.apache.archiva.redback.rest.services;
+package org.apache.archiva.redback.rest.services.v2;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -33,13 +33,14 @@ import
org.apache.archiva.redback.keys.memory.MemoryKeyManager;
import org.apache.archiva.redback.policy.AccountLockedException;
import org.apache.archiva.redback.policy.MustChangePasswordException;
import org.apache.archiva.redback.rest.api.model.ActionStatus;
-import org.apache.archiva.redback.rest.api.model.AuthenticationKeyResult;
import org.apache.archiva.redback.rest.api.model.ErrorMessage;
import org.apache.archiva.redback.rest.api.model.LoginRequest;
import org.apache.archiva.redback.rest.api.model.PingResult;
+import org.apache.archiva.redback.rest.api.model.Token;
import org.apache.archiva.redback.rest.api.model.User;
-import org.apache.archiva.redback.rest.api.services.LoginService;
+import org.apache.archiva.redback.rest.api.model.UserLogin;
import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
+import org.apache.archiva.redback.rest.api.services.v2.AuthenticationService;
import org.apache.archiva.redback.system.SecuritySession;
import org.apache.archiva.redback.system.SecuritySystem;
import org.apache.archiva.redback.users.UserManagerException;
@@ -54,22 +55,30 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.temporal.TemporalAmount;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
+import java.util.Date;
import java.util.List;
import java.util.TimeZone;
/**
+ *
+ * Authentication service provides REST methods for authentication and
verification.
+ *
* @author Olivier Lamy
- * @since 1.3
+ * @author Martin Stockhammer
+ * @since 3.0
*/
-@Service( "loginService#rest" )
-public class DefaultLoginService
- implements LoginService
+@Service( "v2.authenticationService#rest" )
+public class DefaultAuthenticationService
+ implements AuthenticationService
{
- private Logger log = LoggerFactory.getLogger( getClass() );
+ private static final Logger log = LoggerFactory.getLogger(
DefaultAuthenticationService.class );
private SecuritySystem securitySystem;
@@ -82,15 +91,16 @@ public class DefaultLoginService
long tokenLifetime = 1000*3600*3;
@Inject
- public DefaultLoginService( SecuritySystem securitySystem,
- @Named( "httpAuthenticator#basic" )
HttpAuthenticator httpAuthenticator )
+ public DefaultAuthenticationService( SecuritySystem securitySystem,
+ @Named( "httpAuthenticator#basic" )
HttpAuthenticator httpAuthenticator )
{
this.securitySystem = securitySystem;
this.httpAuthenticator = httpAuthenticator;
}
- public AuthenticationKeyResult addAuthenticationKey( String providedKey,
String principal, String purpose, int expirationMinutes )
+ @Override
+ public Token requestOnetimeToken( String providedKey, String principal,
String purpose, int expirationSeconds )
throws RedbackServiceException
{
KeyManager keyManager = securitySystem.getKeyManager();
@@ -109,34 +119,34 @@ public class DefaultLoginService
key.setForPrincipal( principal );
key.setPurpose( purpose );
- Calendar now = getNowGMT();
- key.setDateCreated( now.getTime() );
+ Instant now = Instant.now( );
+ key.setDateCreated( Date.from( now ) );
- if ( expirationMinutes >= 0 )
+ if ( expirationSeconds >= 0 )
{
- Calendar expiration = getNowGMT();
- expiration.add( Calendar.MINUTE, expirationMinutes );
- key.setDateExpires( expiration.getTime() );
+ Duration expireDuration = Duration.ofSeconds( expirationSeconds );
+ key.setDateExpires( Date.from( now.plus( expireDuration ) ) );
}
-
keyManager.addKey( key );
-
- return new AuthenticationKeyResult( key.getKey( ) );
+ return Token.of( key );
}
+ @Override
public PingResult ping()
throws RedbackServiceException
{
return new PingResult( true);
}
+ @Override
public PingResult pingWithAutz()
throws RedbackServiceException
{
return new PingResult( true );
}
- public User logIn( LoginRequest loginRequest )
+ @Override
+ public UserLogin logIn( LoginRequest loginRequest )
throws RedbackServiceException
{
String userName = loginRequest.getUsername(), password =
loginRequest.getPassword();
@@ -156,7 +166,7 @@ public class DefaultLoginService
log.info( "user {} not validated", user.getUsername() );
return null;
}
- User restUser = buildRestUser( user );
+ UserLogin restUser = buildRestUser( user );
restUser.setReadOnly( securitySystem.userManagerReadOnly() );
// validationToken only set during login
try {
@@ -214,6 +224,7 @@ public class DefaultLoginService
}
+ @Override
public User isLogged()
throws RedbackServiceException
{
@@ -223,6 +234,7 @@ public class DefaultLoginService
return isLogged && securitySession.getUser() != null ? buildRestUser(
securitySession.getUser() ) : null;
}
+ @Override
public ActionStatus logout()
throws RedbackServiceException
{
@@ -239,9 +251,9 @@ public class DefaultLoginService
return Calendar.getInstance( TimeZone.getTimeZone( "GMT" ) );
}
- private User buildRestUser( org.apache.archiva.redback.users.User user )
+ private UserLogin buildRestUser( org.apache.archiva.redback.users.User
user )
{
- User restUser = new User();
+ UserLogin restUser = new UserLogin();
restUser.setEmail( user.getEmail() );
restUser.setUsername( user.getUsername() );
restUser.setPasswordChangeRequired( user.isPasswordChangeRequired() );
diff --git
a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultGroupService.java
b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultGroupService.java
index ae1bce0..3821416 100644
---
a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultGroupService.java
+++
b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultGroupService.java
@@ -40,6 +40,9 @@ import javax.inject.Inject;
import javax.inject.Named;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -60,6 +63,9 @@ public class DefaultGroupService
{
private final Logger log = LoggerFactory.getLogger( getClass() );
+ @Context //injected response proxy supporting multiple threads
+ private HttpServletResponse response;
+
@Inject
@Named(value = "ldapRoleMapper#default")
private LdapRoleMapper ldapRoleMapper;
@@ -82,7 +88,7 @@ public class DefaultGroupService
}
@Override
- public PagedResult<Group> getGroups( Long offset, Long limit ) throws
RedbackServiceException
+ public PagedResult<List<Group>> getGroups( Integer offset, Integer limit )
throws RedbackServiceException
{
LdapConnection ldapConnection = null;
@@ -93,7 +99,7 @@ public class DefaultGroupService
ldapConnection = ldapConnectionFactory.getConnection();
context = ldapConnection.getDirContext();
List<LdapGroup> groups = ldapRoleMapper.getAllGroupObjects(
context );
- return PagedResult.ofSegment( groups.size( ), offset, limit,
groups.stream( ).skip( offset ).limit( limit ).map(
DefaultGroupService::getGroupFromLdap ).collect( Collectors.toList( ) ) );
+ return PagedResult.of( groups.size( ), offset, limit,
groups.stream( ).skip( offset ).limit( limit ).map(
DefaultGroupService::getGroupFromLdap ).collect( Collectors.toList( ) ) );
}
catch ( LdapException | MappingException e )
{
@@ -138,6 +144,7 @@ public class DefaultGroupService
{
ldapRoleMapperConfiguration.addLdapMapping(
ldapGroupMapping.getGroup(),
new ArrayList<>(
ldapGroupMapping.getRoleNames() ) );
+ response.setStatus( Response.Status.CREATED.getStatusCode() );
}
catch ( MappingException e )
{
diff --git
a/redback-integrations/redback-rest/redback-rest-services/src/main/resources/META-INF/spring-context.xml
b/redback-integrations/redback-rest/redback-rest-services/src/main/resources/META-INF/spring-context.xml
index 356f704..d54a4c3 100644
---
a/redback-integrations/redback-rest/redback-rest-services/src/main/resources/META-INF/spring-context.xml
+++
b/redback-integrations/redback-rest/redback-rest-services/src/main/resources/META-INF/spring-context.xml
@@ -49,6 +49,11 @@
<bean id="redbackJacksonJsonMapper"
class="com.fasterxml.jackson.databind.ObjectMapper" >
<property name="annotationIntrospector"
ref="jacksonAnnotationIntrospector"/>
+ <property name="dateFormat">
+ <bean class="java.text.SimpleDateFormat">
+ <constructor-arg type="java.lang.String"
value="yyyyMMdd'T'HHmmss.SSSZ"/>
+ </bean>
+ </property>
</bean>
<bean id="redbackJacksonXMLMapper"
class="com.fasterxml.jackson.dataformat.xml.XmlMapper" >
<property name="annotationIntrospector"
ref="jacksonAnnotationIntrospector"/>
@@ -58,7 +63,7 @@
- <jaxrs:server id="redbackServices" address="/redbackServices">
+ <jaxrs:server name="redbackServices" address="/redbackServices">
<jaxrs:serviceBeans>
<ref bean="userService#rest"/>
@@ -81,10 +86,10 @@
</jaxrs:providers>
</jaxrs:server>
- <jaxrs:server address="/redback/v2">
+ <jaxrs:server address="/v2/redback">
<jaxrs:serviceBeans>
<ref bean="userService#rest"/>
- <ref bean="loginService#rest"/>
+ <ref bean="v2.authenticationService#rest"/>
<ref bean="roleManagementService#rest"/>
<ref bean="utilServices#rest"/>
<ref bean="passwordService#rest"/>
diff --git
a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/AbstractRestServicesTest.java
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/AbstractRestServicesTest.java
index 972de2e..fd3d892 100644
---
a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/AbstractRestServicesTest.java
+++
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/AbstractRestServicesTest.java
@@ -27,6 +27,7 @@ import
org.apache.archiva.redback.rest.api.services.LdapGroupMappingService;
import org.apache.archiva.redback.rest.api.services.LoginService;
import org.apache.archiva.redback.rest.api.services.RoleManagementService;
import org.apache.archiva.redback.rest.api.services.UserService;
+import org.apache.archiva.redback.rest.api.services.v2.AuthenticationService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.apache.cxf.common.util.Base64Utility;
@@ -257,6 +258,27 @@ public abstract class AbstractRestServicesTest
return service;
}
+ protected AuthenticationService getLoginServiceV2( String authzHeader )
+ {
+ AuthenticationService service =
+ JAXRSClientFactory.create( "http://localhost:" + getServerPort() +
"/" + getRestServicesPath() + "/v2/redback/",
+ AuthenticationService.class, Collections.singletonList( new
JacksonJaxbJsonProvider() ) );
+
+ // 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;
+ }
+
protected LdapGroupMappingService getLdapGroupMappingService( String
authzHeader )
{
diff --git
a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/AuthenticationServiceTest.java
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/AuthenticationServiceTest.java
new file mode 100644
index 0000000..cf7f5a2
--- /dev/null
+++
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/AuthenticationServiceTest.java
@@ -0,0 +1,112 @@
+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
org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
+import org.apache.archiva.redback.rest.api.model.LoginRequest;
+import org.apache.archiva.redback.rest.api.model.User;
+import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
+import org.apache.archiva.redback.rest.api.services.UserService;
+import org.apache.archiva.redback.rest.services.AbstractRestServicesTest;
+import org.apache.archiva.redback.rest.services.FakeCreateAdminService;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * @author Olivier Lamy
+ */
+@RunWith( SpringJUnit4ClassRunner.class )
+@ContextConfiguration(
+ locations = { "classpath:/spring-context.xml" } )
+public class AuthenticationServiceTest
+ extends AbstractRestServicesTest
+{
+ @Test
+ public void loginAdmin()
+ throws Exception
+ {
+ assertNotNull( getLoginService( null ).logIn( new LoginRequest(
RedbackRoleConstants.ADMINISTRATOR_ACCOUNT_NAME,
+
FakeCreateAdminService.ADMIN_TEST_PWD ) ) );
+ }
+
+ @Test
+ public void createUserThenLog()
+ throws Exception
+ {
+ try
+ {
+
+ // START SNIPPET: create-user
+ User user = new User( "toto", "toto the king", "[email protected]",
false, false );
+ user.setPassword( "foo123" );
+ user.setPermanent( false );
+ user.setPasswordChangeRequired( false );
+ user.setLocked( false );
+ user.setValidated( true );
+ UserService userService = getUserService( authorizationHeader );
+ userService.createUser( user );
+ // END SNIPPET: create-user
+ user = userService.getUser( "toto" );
+ assertNotNull( user );
+ assertEquals( "toto the king", user.getFullName() );
+ assertEquals( "[email protected]", user.getEmail() );
+ getLoginServiceV2( encode( "toto", "foo123" ) ).pingWithAutz();
+ }
+ finally
+ {
+ getUserService( authorizationHeader ).deleteUser( "toto" );
+ getUserService( authorizationHeader ).removeFromCache( "toto" );
+ assertNull( getUserService( authorizationHeader ).getUser( "toto"
) );
+ }
+ }
+
+ @Test
+ public void simpleLogin() throws RedbackServiceException
+ {
+ try
+ {
+
+ // START SNIPPET: create-user
+ User user = new User( "toto", "toto the king", "[email protected]",
false, false );
+ user.setPassword( "foo123" );
+ user.setPermanent( false );
+ user.setPasswordChangeRequired( false );
+ user.setLocked( false );
+ user.setValidated( true );
+ UserService userService = getUserService( authorizationHeader );
+ userService.createUser( user );
+ // END SNIPPET: create-user
+ LoginRequest request = new LoginRequest( "toto", "foo123" );
+ User result = getLoginServiceV2( "" ).logIn( request );
+ assertNotNull( result );
+ assertEquals( "toto", result.getUsername( ) );
+
+ }
+ finally
+ {
+ getUserService( authorizationHeader ).deleteUser( "toto" );
+ getUserService( authorizationHeader ).removeFromCache( "toto" );
+ assertNull( getUserService( authorizationHeader ).getUser( "toto"
) );
+ }
+
+ }
+
+}
diff --git
a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/GroupServiceTest.java
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/GroupServiceTest.java
index a54144f..7fcdc18 100644
---
a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/GroupServiceTest.java
+++
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/GroupServiceTest.java
@@ -73,7 +73,7 @@ public class GroupServiceTest
protected GroupService getGroupService( String authzHeader )
{
GroupService service =
- JAXRSClientFactory.create( "http://localhost:" + getServerPort() +
"/" + getRestServicesPath() + "/redback/v2/",
+ JAXRSClientFactory.create( "http://localhost:" + getServerPort() +
"/" + getRestServicesPath() + "/v2/redback/",
GroupService.class,
Collections.singletonList( new JacksonJaxbJsonProvider() ) );
@@ -193,7 +193,7 @@ public class GroupServiceTest
{
GroupService service = getGroupService( authorizationHeader );
- List<String> allGroups = service.getGroups( Long.valueOf( 0 ),
Long.valueOf( Long.MAX_VALUE ) ).getData().stream( ).map( group ->
group.getName( ) ).collect( Collectors.toList( ) );
+ List<String> allGroups = service.getGroups( Integer.valueOf( 0 ),
Integer.valueOf( Integer.MAX_VALUE ) ).getData().stream( ).map( group ->
group.getName( ) ).collect( Collectors.toList( ) );
assertThat( allGroups ).isNotNull().isNotEmpty().hasSize( 3
).containsAll( groups );
}