package org.apereo.cas.adaptors.rest; import com.fasterxml.jackson.databind.ObjectMapper; import org.apereo.cas.authentication.exceptions.AccountDisabledException; import org.apereo.cas.authentication.AuthenticationHandler; import org.apereo.cas.authentication.CoreAuthenticationTestUtils; import org.apereo.cas.authentication.HandlerResult; import org.apereo.cas.authentication.principal.DefaultPrincipalFactory; import org.apereo.cas.authentication.principal.Principal; import org.apereo.cas.config.CasCoreAuthenticationConfiguration; import org.apereo.cas.config.CasCoreAuthenticationHandlersConfiguration; import org.apereo.cas.config.CasCoreAuthenticationMetadataConfiguration; import org.apereo.cas.config.CasCoreAuthenticationPolicyConfiguration; import org.apereo.cas.config.CasCoreAuthenticationPrincipalConfiguration; import org.apereo.cas.config.CasCoreAuthenticationSupportConfiguration; import org.apereo.cas.config.CasCoreHttpConfiguration; import org.apereo.cas.config.CasCoreServicesConfiguration; import org.apereo.cas.config.CasCoreUtilConfiguration; import org.apereo.cas.config.CasPersonDirectoryConfiguration; import org.apereo.cas.config.CasRestAuthenticationConfiguration; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.test.web.client.ResponseActions; import org.springframework.web.client.RestTemplate; import javax.security.auth.login.AccountNotFoundException; import javax.security.auth.login.FailedLoginException; import java.io.StringWriter; import static org.junit.Assert.*; import static org.springframework.test.web.client.ExpectedCount.*; import static org.springframework.test.web.client.match.MockRestRequestMatchers.*; import static org.springframework.test.web.client.response.MockRestResponseCreators.*; /** * This is {@link RestAuthenticationHandlerTests}. * * @author Misagh Moayyed * @since 5.0.0 */ @RunWith(SpringRunner.class) @SpringBootTest(classes = {CasRestAuthenticationConfiguration.class, CasCoreAuthenticationConfiguration.class, CasCoreAuthenticationPrincipalConfiguration.class, CasCoreAuthenticationPolicyConfiguration.class, CasCoreAuthenticationMetadataConfiguration.class, CasCoreAuthenticationSupportConfiguration.class, CasCoreAuthenticationHandlersConfiguration.class, CasCoreHttpConfiguration.class, CasCoreServicesConfiguration.class, RefreshAutoConfiguration.class, CasPersonDirectoryConfiguration.class, CasCoreUtilConfiguration.class}) @TestPropertySource(properties = "cas.authn.rest.uri=http://localhost:8081/authn") @EnableScheduling public class RestAuthenticationHandlerTests { @Rule public ExpectedException thrown = ExpectedException.none(); @Autowired @Qualifier("restAuthenticationHandler") private AuthenticationHandler authenticationHandler; @Autowired @Qualifier("restAuthenticationTemplate") private RestTemplate restAuthenticationTemplate; private ResponseActions server; @Before public void setUp() throws Exception { server = MockRestServiceServer.bindTo(restAuthenticationTemplate).build() .expect(manyTimes(), requestTo("http://localhost:8081/authn")) .andExpect(method(HttpMethod.POST)); } @Test public void verifySuccess() throws Exception { final Principal principalWritten = new DefaultPrincipalFactory().createPrincipal("casuser"); final ObjectMapper mapper = new ObjectMapper(); final StringWriter writer = new StringWriter(); mapper.writeValue(writer, principalWritten); server.andRespond(withSuccess(writer.toString(), MediaType.APPLICATION_JSON)); final HandlerResult res = authenticationHandler.authenticate(CoreAuthenticationTestUtils.getCredentialsWithSameUsernameAndPassword()); assertEquals(res.getPrincipal().getId(), "casuser"); } @Test public void verifyDisabledAccount() throws Exception { server.andRespond(withStatus(HttpStatus.FORBIDDEN)); this.thrown.expect(AccountDisabledException.class); this.thrown.expectMessage("Could not authenticate forbidden account for test"); authenticationHandler.authenticate(CoreAuthenticationTestUtils.getCredentialsWithSameUsernameAndPassword()); } @Test public void verifyUnauthorized() throws Exception { server.andRespond(withStatus(HttpStatus.UNAUTHORIZED)); this.thrown.expect(FailedLoginException.class); this.thrown.expectMessage("Could not authenticate account for test"); authenticationHandler.authenticate(CoreAuthenticationTestUtils.getCredentialsWithSameUsernameAndPassword()); } @Test public void verifyNotFound() throws Exception { server.andRespond(withStatus(HttpStatus.NOT_FOUND)); this.thrown.expect(AccountNotFoundException.class); this.thrown.expectMessage("Could not locate account for test"); authenticationHandler.authenticate(CoreAuthenticationTestUtils.getCredentialsWithSameUsernameAndPassword()); } }