package org.carlspring.strongbox.controllers.users;

import org.carlspring.strongbox.config.IntegrationTest;
import org.carlspring.strongbox.forms.users.PasswordEncodeForm;
import org.carlspring.strongbox.rest.common.RestAssuredBaseTest;

import javax.inject.Inject;

import io.restassured.module.mockmvc.response.ValidatableMockMvcResponse;
import org.hamcrest.CoreMatchers;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.test.context.support.WithAnonymousUser;
import org.springframework.security.test.context.support.WithUserDetails;
import org.springframework.transaction.annotation.Transactional;
import static io.restassured.module.mockmvc.RestAssuredMockMvc.given;

/**
 * @author Przemyslaw Fusik
 */
@IntegrationTest
@Transactional
public class PasswordEncoderControllerTest
        extends RestAssuredBaseTest
{

    @Inject
    PasswordEncoder passwordEncoder;

    @Override
    @BeforeEach
    public void init()
            throws Exception
    {
        super.init();
        setContextBaseUrl(getContextBaseUrl() + "/api/users/encrypt/password");
    }

    @ParameterizedTest
    @WithUserDetails("admin")
    @ValueSource(strings = { MediaType.APPLICATION_JSON_VALUE,
                             MediaType.TEXT_PLAIN_VALUE })
    public void shouldEncodeProperly(String acceptedHeader)
    {
        final PasswordEncodeForm form = new PasswordEncodeForm("password");

        ValidatableMockMvcResponse response = given().contentType(MediaType.APPLICATION_JSON_VALUE)
                                                     .accept(acceptedHeader)
                                                     .body(form)
                                                     .post(getContextBaseUrl())
                                                     .peek()
                                                     .then()
                                                     .statusCode(HttpStatus.OK.value());


        if (acceptedHeader.equals(MediaType.APPLICATION_JSON_VALUE))
        {
            response.body("password", CoreMatchers.not(form.getPassword()));
        }
        else
        {
            response.body(CoreMatchers.not(form.getPassword()));
        }
    }

    @Test
    @WithAnonymousUser
    public void shouldRequireAuthenticationAccess()
    {
        final PasswordEncodeForm form = new PasswordEncodeForm("password");

        given().contentType(MediaType.APPLICATION_JSON_VALUE)
               .accept(MediaType.APPLICATION_JSON_VALUE)
               .body(form)
               .when()
               .post(getContextBaseUrl())
               .peek()
               .then()
               .body("error", CoreMatchers.containsString("Full authentication is required"))
               .statusCode(HttpStatus.UNAUTHORIZED.value());
    }


    @Test
    @WithUserDetails("deployer")
    public void shouldAllowOnlyAdminAccess()
    {
        final PasswordEncodeForm form = new PasswordEncodeForm("password");

        given().contentType(MediaType.APPLICATION_JSON_VALUE)
               .accept(MediaType.APPLICATION_JSON_VALUE)
               .body(form)
               .when()
               .post(getContextBaseUrl())
               .peek()
               .then()
               .body("error", CoreMatchers.containsString("forbidden"))
               .statusCode(HttpStatus.FORBIDDEN.value());
    }

}

@@ -581,65 +581,201 @@
 ork.
-http.HttpStatus;%0Aimport org.springframework.http.MediaTyp
+context.support.MessageSourceAccessor;%0Aimport org.springframework.http.HttpStatus;%0Aimport org.springframework.http.MediaType;%0Aimport org.springframework.security.core.SpringSecurityMessageSourc
 e;%0Ai
@@ -1057,16 +1057,76 @@
 tional;%0A
+%0Aimport java.nio.charset.Charset;%0Aimport java.util.Locale;%0A%0A
 import s
@@ -1186,16 +1186,76 @@
 c.given;
+%0Aimport static java.nio.charset.StandardCharsets.ISO_8859_1;
 %0A%0A/**%0A *
@@ -1398,16 +1398,229 @@
 Test%0A%7B%0A%0A
+    private static final String UNAUTHORIZED_MESSAGE_CODE = %22ExceptionTranslationFilter.insufficientAuthentication%22;%0A%0A    private final MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();%0A%0A
     @Inj
@@ -3142,32 +3142,393 @@
 m(%22password%22);%0A%0A
+        String defaultErrorMessage = messages.getMessage(UNAUTHORIZED_MESSAGE_CODE,%0A                Locale.ENGLISH);%0A%0A        String errorMessage = messages.getMessage(UNAUTHORIZED_MESSAGE_CODE,%0A                defaultErrorMessage);%0A%0A        String decodedErrorMessage = new String(errorMessage.getBytes(ISO_8859_1),%0A                Charset.defaultCharset());%0A%0A
         given().
@@ -3830,41 +3830,27 @@
 ing(
-%22Full authentication is required%22
+decodedErrorMessage
 ))%0A 

Fix langauge based error for PasswordEncoderControllerTest#shouldRequireAuthenticationAccess