This is an automated email from the ASF dual-hosted git repository.

vorburger pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new a93a6b8  Change /authentication API to pass data in request body 
instead of URL arguments (FINERACT-726)
a93a6b8 is described below

commit a93a6b848732141494b2f0cc11de346623bc23e6
Author: Michael Vorburger <[email protected]>
AuthorDate: Sat Jan 4 13:24:24 2020 +0100

    Change /authentication API to pass data in request body instead of URL 
arguments (FINERACT-726)
---
 .../fineract/integrationtests/common/Utils.java    | 11 +++++--
 .../security/api/AuthenticationApiResource.java    | 35 ++++++++++++++++------
 .../api/SelfAuthenticationApiResource.java         | 12 ++++----
 3 files changed, 40 insertions(+), 18 deletions(-)

diff --git 
a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/Utils.java
 
b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/Utils.java
index cf4ee66..68142e0 100644
--- 
a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/Utils.java
+++ 
b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/Utils.java
@@ -34,6 +34,7 @@ import java.util.Random;
 import java.util.TimeZone;
 
 import com.jayway.restassured.RestAssured;
+import com.jayway.restassured.http.ContentType;
 import com.jayway.restassured.path.json.JsonPath;
 import com.jayway.restassured.response.Response;
 import com.jayway.restassured.specification.RequestSpecification;
@@ -62,7 +63,7 @@ public class Utils {
     public static final String TENANT_TIME_ZONE = "Asia/Kolkata";
 
     private static final String HEALTH_URL = 
"/fineract-provider/actuator/health";
-    private static final String LOGIN_URL  = 
"/fineract-provider/api/v1/authentication?username=mifos&password=password&" + 
TENANT_IDENTIFIER;
+    private static final String LOGIN_URL  = 
"/fineract-provider/api/v1/authentication?" + TENANT_IDENTIFIER;
 
     public static void initializeRESTAssured() {
         RestAssured.baseURI = "https://localhost";;
@@ -116,9 +117,13 @@ public class Utils {
         try {
             logger.info("Logging in, for integration test...");
             
System.out.println("-----------------------------------LOGIN-----------------------------------------");
-            final String json = RestAssured.post(LOGIN_URL).asString();
+            String json = RestAssured.given().contentType(ContentType.JSON)
+                .body("{\"username\":\"mifos\", \"password\":\"password\"}")
+                .expect().log().ifError().when().post(LOGIN_URL).asString();
             assertThat("Failed to login into fineract platform", 
StringUtils.isBlank(json), is(false));
-            return JsonPath.with(json).get("base64EncodedAuthenticationKey");
+            String key = 
JsonPath.with(json).get("base64EncodedAuthenticationKey");
+            assertThat("Failed to obtain key: " + json, 
StringUtils.isBlank(key), is(false));
+            return key;
         } catch (final Exception e) {
             if (e instanceof HttpHostConnectException) {
                 final HttpHostConnectException hh = (HttpHostConnectException) 
e;
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/AuthenticationApiResource.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/AuthenticationApiResource.java
index c99a4fd..7ddf2f8 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/AuthenticationApiResource.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/api/AuthenticationApiResource.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Set;
 
+import javax.ws.rs.Consumes;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
@@ -48,15 +49,22 @@ import org.springframework.security.core.Authentication;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.stereotype.Component;
 
+import com.google.gson.Gson;
+
 import com.sun.jersey.core.util.Base64;
 
-@Path("/authentication")
 @Component
-@Profile("basicauth")
 @Scope("singleton")
+@Profile("basicauth")
+@Path("/authentication")
 @Api(value = "Authentication HTTP Basic", description = "An API capability 
that allows client applications to verify authentication details using HTTP 
Basic Authentication.")
 public class AuthenticationApiResource {
 
+    public static class AuthenticateRequest {
+        public String username;
+        public String password;
+    }
+
     private final DaoAuthenticationProvider customAuthenticationProvider;
     private final ToApiJsonSerializer<AuthenticatedUserData> 
apiJsonSerializerService;
     private final SpringSecurityPlatformSecurityContext 
springSecurityPlatformSecurityContext;
@@ -74,16 +82,25 @@ public class AuthenticationApiResource {
     }
 
     @POST
+    @Consumes({ MediaType.APPLICATION_JSON })
     @Produces({ MediaType.APPLICATION_JSON })
     @ApiOperation(value = "Verify authentication", notes = "Authenticates the 
credentials provided and returns the set roles and permissions allowed.")
     @ApiResponses({@ApiResponse(code = 200, message = "", response = 
AuthenticationApiResourceSwagger.PostAuthenticationResponse.class), 
@ApiResponse(code = 400, message = "Unauthenticated. Please login")})
-    public String authenticate(@QueryParam("username") @ApiParam(value = 
"username") final String username, @QueryParam("password") @ApiParam(value = 
"password") final String password) {
+    public String authenticate(final String apiRequestBodyAsJson) {
+        // TODO FINERACT-819: sort out Jersey so JSON conversion does not have 
to be done explicitly via GSON here, but implicit by arg
+        AuthenticateRequest request = new 
Gson().fromJson(apiRequestBodyAsJson, AuthenticateRequest.class);
+        if (request == null) {
+            throw new IllegalArgumentException("Invalid JSON in BODY (no 
longer URL param; see FINERACT-726) of POST to /authentication: " + 
apiRequestBodyAsJson);
+        }
+        if (request.username == null || request.password == null) {
+            throw new IllegalArgumentException("Username or Password is null 
in JSON (see FINERACT-726) of POST to /authentication: " + apiRequestBodyAsJson 
+ "; username=" + request.username + ", password=" + request.password);
+        }
 
-        final Authentication authentication = new 
UsernamePasswordAuthenticationToken(username, password);
+        final Authentication authentication = new 
UsernamePasswordAuthenticationToken(request.username, request.password);
         final Authentication authenticationCheck = 
this.customAuthenticationProvider.authenticate(authentication);
 
         final Collection<String> permissions = new ArrayList<>();
-        AuthenticatedUserData authenticatedUserData = new 
AuthenticatedUserData(username, permissions);
+        AuthenticatedUserData authenticatedUserData = new 
AuthenticatedUserData(request.username, permissions);
 
         if (authenticationCheck.isAuthenticated()) {
             final Collection<GrantedAuthority> authorities = new 
ArrayList<>(authenticationCheck.getAuthorities());
@@ -91,7 +108,7 @@ public class AuthenticationApiResource {
                 permissions.add(grantedAuthority.getAuthority());
             }
 
-            final byte[] base64EncodedAuthenticationKey = 
Base64.encode(username + ":" + password);
+            final byte[] base64EncodedAuthenticationKey = 
Base64.encode(request.username + ":" + request.password);
 
             final AppUser principal = (AppUser) 
authenticationCheck.getPrincipal();
             final Collection<RoleData> roles = new ArrayList<>();
@@ -111,11 +128,11 @@ public class AuthenticationApiResource {
             boolean isTwoFactorRequired = 
twoFactorUtils.isTwoFactorAuthEnabled() && !
                     
principal.hasSpecificPermissionTo(TwoFactorConstants.BYPASS_TWO_FACTOR_PERMISSION);
             if 
(this.springSecurityPlatformSecurityContext.doesPasswordHasToBeRenewed(principal))
 {
-                authenticatedUserData = new AuthenticatedUserData(username, 
principal.getId(),
+                authenticatedUserData = new 
AuthenticatedUserData(request.username, principal.getId(),
                         new String(base64EncodedAuthenticationKey), 
isTwoFactorRequired);
             } else {
 
-                authenticatedUserData = new AuthenticatedUserData(username, 
officeId, officeName, staffId, staffDisplayName,
+                authenticatedUserData = new 
AuthenticatedUserData(request.username, officeId, officeName, staffId, 
staffDisplayName,
                         organisationalRole, roles, permissions, 
principal.getId(),
                         new String(base64EncodedAuthenticationKey), 
isTwoFactorRequired);
             }
@@ -124,4 +141,4 @@ public class AuthenticationApiResource {
 
         return this.apiJsonSerializerService.serialize(authenticatedUserData);
     }
-}
\ No newline at end of file
+}
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/security/api/SelfAuthenticationApiResource.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/security/api/SelfAuthenticationApiResource.java
index b5b6671..d1bd98a 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/security/api/SelfAuthenticationApiResource.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/security/api/SelfAuthenticationApiResource.java
@@ -25,16 +25,17 @@ import org.springframework.context.annotation.Profile;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
 
+import javax.ws.rs.Consumes;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 
-@Path("/self/authentication")
 @Component
-@Profile("basicauth")
 @Scope("singleton")
+@Profile("basicauth")
+@Path("/self/authentication")
 @Api(value = "Self Authentication", description = "")
 public class SelfAuthenticationApiResource {
 
@@ -47,12 +48,11 @@ public class SelfAuthenticationApiResource {
        }
 
        @POST
+       @Consumes({ MediaType.APPLICATION_JSON })
        @Produces({ MediaType.APPLICATION_JSON })
        @ApiOperation(value = "Verify authentication", httpMethod = "POST", 
notes = "Authenticates the credentials provided and returns the set roles and 
permissions allowed.\n\n" + "Please visit this link for more info - 
https://demo.openmf.org/api-docs/apiLive.htm#selfbasicauth";)
        @ApiResponses({@ApiResponse(code = 200, message = "OK", response = 
SelfAuthenticationApiResourceSwagger.PostSelfAuthenticationResponse.class)})
-       public String authenticate(@QueryParam("username") @ApiParam(value = 
"username") final String username,
-                       @QueryParam("password") @ApiParam(value = "password") 
final String password) {
-               return this.authenticationApiResource.authenticate(username, 
password);
+       public String authenticate(final String apiRequestBodyAsJson) {
+               return 
this.authenticationApiResource.authenticate(apiRequestBodyAsJson);
        }
-
 }

Reply via email to