/*
* Licensed to Apereo under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Apereo 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 the following location:
*
* 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.
*/
package org.jasig.cas.support.oauth.web;
import org.jasig.cas.support.oauth.CentralOAuthService;
import org.jasig.cas.support.oauth.OAuthConstants;
import org.jasig.cas.support.oauth.services.OAuthRegisteredService;
import org.jasig.cas.support.oauth.token.TokenType;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;
import javax.servlet.http.HttpSession;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* This class tests the {@link OAuth20AuthorizeController} class.
*
* @author Jerome Leleu
* @author Michael Haselton
* @since 3.5.2
*/
public final class OAuth20AuthorizeControllerTests {
private static final String CONTEXT = "/oauth2.0/";
private static final String RESPONSE_TYPE = "code";
private static final String INVALID_RESPONSE_TYPE = "not_code_or_token";
private static final String CLIENT_ID = "1";
private static final String NO_SUCH_CLIENT_ID = "nope";
private static final String REDIRECT_URI = "http://someurl";
private static final String OTHER_REDIRECT_URI = "http://someotherurl";
private static final String ACCESS_TYPE = "offline";
private static final TokenType DEFAULT_ACCESS_TYPE = TokenType.ONLINE;
private static final String INVALID_ACCESS_TYPE = "not_online_or_offline";
private static final String UNSUPPORTED_ACCESS_TYPE = "personal";
private static final String CAS_SERVER = "casserver";
private static final String CAS_SCHEME = "https";
private static final int CAS_PORT = 443;
private static final String CAS_URL = CAS_SCHEME + "://" + CAS_SERVER + ":" + CAS_PORT;
private static final String SERVICE_NAME = "serviceName";
private static final String SCOPE = "scope1 scope2";
private static final String DEFAULT_SCOPE = "";
private static final String STATE = "state";
@Test
public void verifyInvalidResponseType() throws Exception {
final MockHttpServletRequest mockRequest = new MockHttpServletRequest("GET", CONTEXT
+ OAuthConstants.AUTHORIZE_URL);
mockRequest.setParameter(OAuthConstants.RESPONSE_TYPE, INVALID_RESPONSE_TYPE);
mockRequest.setParameter(OAuthConstants.CLIENT_ID, CLIENT_ID);
mockRequest.setParameter(OAuthConstants.REDIRECT_URI, REDIRECT_URI);
mockRequest.setParameter(OAuthConstants.ACCESS_TYPE, ACCESS_TYPE);
final MockHttpServletResponse mockResponse = new MockHttpServletResponse();
final OAuth20WrapperController oauth20WrapperController = new OAuth20WrapperController();
oauth20WrapperController.afterPropertiesSet();
final ModelAndView modelAndView = oauth20WrapperController.handleRequest(mockRequest, mockResponse);
assertEquals(OAuthConstants.ERROR_VIEW, modelAndView.getViewName());
}
@Test
public void verifyNoClientId() throws Exception {
final MockHttpServletRequest mockRequest = new MockHttpServletRequest("GET", CONTEXT
+ OAuthConstants.AUTHORIZE_URL);
mockRequest.setParameter(OAuthConstants.RESPONSE_TYPE, RESPONSE_TYPE);
mockRequest.setParameter(OAuthConstants.REDIRECT_URI, REDIRECT_URI);
mockRequest.setParameter(OAuthConstants.ACCESS_TYPE, ACCESS_TYPE);
final MockHttpServletResponse mockResponse = new MockHttpServletResponse();
final OAuth20WrapperController oauth20WrapperController = new OAuth20WrapperController();
oauth20WrapperController.afterPropertiesSet();
final ModelAndView modelAndView = oauth20WrapperController.handleRequest(mockRequest, mockResponse);
assertEquals(OAuthConstants.ERROR_VIEW, modelAndView.getViewName());
}
@Test
public void verifyNoRedirectUri() throws Exception {
final MockHttpServletRequest mockRequest = new MockHttpServletRequest("GET", CONTEXT
+ OAuthConstants.AUTHORIZE_URL);
mockRequest.setParameter(OAuthConstants.RESPONSE_TYPE, RESPONSE_TYPE);
mockRequest.setParameter(OAuthConstants.CLIENT_ID, CLIENT_ID);
mockRequest.setParameter(OAuthConstants.ACCESS_TYPE, ACCESS_TYPE);
final MockHttpServletResponse mockResponse = new MockHttpServletResponse();
final OAuth20WrapperController oauth20WrapperController = new OAuth20WrapperController();
oauth20WrapperController.afterPropertiesSet();
final ModelAndView modelAndView = oauth20WrapperController.handleRequest(mockRequest, mockResponse);
assertEquals(OAuthConstants.ERROR_VIEW, modelAndView.getViewName());
}
@Test
public void verifyInvalidAccessType() throws Exception {
final MockHttpServletRequest mockRequest = new MockHttpServletRequest("GET", CONTEXT
+ OAuthConstants.AUTHORIZE_URL);
mockRequest.setParameter(OAuthConstants.RESPONSE_TYPE, RESPONSE_TYPE);
mockRequest.setParameter(OAuthConstants.CLIENT_ID, CLIENT_ID);
mockRequest.setParameter(OAuthConstants.REDIRECT_URI, REDIRECT_URI);
mockRequest.setParameter(OAuthConstants.ACCESS_TYPE, INVALID_ACCESS_TYPE);
final MockHttpServletResponse mockResponse = new MockHttpServletResponse();
final OAuth20WrapperController oauth20WrapperController = new OAuth20WrapperController();
oauth20WrapperController.afterPropertiesSet();
final ModelAndView modelAndView = oauth20WrapperController.handleRequest(mockRequest, mockResponse);
assertEquals(OAuthConstants.ERROR_VIEW, modelAndView.getViewName());
}
@Test
public void verifyUnsupportedAccessType() throws Exception {
final MockHttpServletRequest mockRequest = new MockHttpServletRequest("GET", CONTEXT
+ OAuthConstants.AUTHORIZE_URL);
mockRequest.setParameter(OAuthConstants.RESPONSE_TYPE, RESPONSE_TYPE);
mockRequest.setParameter(OAuthConstants.CLIENT_ID, CLIENT_ID);
mockRequest.setParameter(OAuthConstants.REDIRECT_URI, REDIRECT_URI);
mockRequest.setParameter(OAuthConstants.ACCESS_TYPE, UNSUPPORTED_ACCESS_TYPE);
final MockHttpServletResponse mockResponse = new MockHttpServletResponse();
final OAuth20WrapperController oauth20WrapperController = new OAuth20WrapperController();
oauth20WrapperController.afterPropertiesSet();
final ModelAndView modelAndView = oauth20WrapperController.handleRequest(mockRequest, mockResponse);
assertEquals(OAuthConstants.ERROR_VIEW, modelAndView.getViewName());
}
@Test
public void verifyNoRegisteredService() throws Exception {
final OAuthRegisteredService service = getRegisteredService(REDIRECT_URI, CLIENT_ID);
final CentralOAuthService centralOAuthService = mock(CentralOAuthService.class);
when(centralOAuthService.getRegisteredService(CLIENT_ID)).thenReturn(service);
when(centralOAuthService.getRegisteredService(NO_SUCH_CLIENT_ID)).thenReturn(null);
final MockHttpServletRequest mockRequest = new MockHttpServletRequest("GET", CONTEXT
+ OAuthConstants.AUTHORIZE_URL);
mockRequest.setParameter(OAuthConstants.RESPONSE_TYPE, RESPONSE_TYPE);
mockRequest.setParameter(OAuthConstants.CLIENT_ID, NO_SUCH_CLIENT_ID);
mockRequest.setParameter(OAuthConstants.REDIRECT_URI, REDIRECT_URI);
mockRequest.setParameter(OAuthConstants.ACCESS_TYPE, ACCESS_TYPE);
final MockHttpServletResponse mockResponse = new MockHttpServletResponse();
final OAuth20WrapperController oauth20WrapperController = new OAuth20WrapperController();
oauth20WrapperController.setCentralOAuthService(centralOAuthService);
oauth20WrapperController.afterPropertiesSet();
final ModelAndView modelAndView = oauth20WrapperController.handleRequest(mockRequest, mockResponse);
assertEquals(OAuthConstants.ERROR_VIEW, modelAndView.getViewName());
}
@Test
public void verifyRedirectUriDoesNotStartWithServiceId() throws Exception {
final OAuthRegisteredService service = getRegisteredService(REDIRECT_URI, CLIENT_ID);
final CentralOAuthService centralOAuthService = mock(CentralOAuthService.class);
when(centralOAuthService.getRegisteredService(CLIENT_ID)).thenReturn(service);
final MockHttpServletRequest mockRequest = new MockHttpServletRequest("GET", CONTEXT
+ OAuthConstants.AUTHORIZE_URL);
mockRequest.setParameter(OAuthConstants.RESPONSE_TYPE, RESPONSE_TYPE);
mockRequest.setParameter(OAuthConstants.CLIENT_ID, CLIENT_ID);
mockRequest.setParameter(OAuthConstants.REDIRECT_URI, OTHER_REDIRECT_URI);
mockRequest.setParameter(OAuthConstants.ACCESS_TYPE, ACCESS_TYPE);
final MockHttpServletResponse mockResponse = new MockHttpServletResponse();
final OAuth20WrapperController oauth20WrapperController = new OAuth20WrapperController();
oauth20WrapperController.setCentralOAuthService(centralOAuthService);
oauth20WrapperController.afterPropertiesSet();
final ModelAndView modelAndView = oauth20WrapperController.handleRequest(mockRequest, mockResponse);
assertEquals(OAuthConstants.ERROR_VIEW, modelAndView.getViewName());
}
@Test
public void verifyOK() throws Exception {
final OAuthRegisteredService service = getRegisteredService(REDIRECT_URI, SERVICE_NAME);
final CentralOAuthService centralOAuthService = mock(CentralOAuthService.class);
when(centralOAuthService.getRegisteredService(CLIENT_ID)).thenReturn(service);
final MockHttpServletRequest mockRequest = new MockHttpServletRequest("GET", CONTEXT
+ OAuthConstants.AUTHORIZE_URL);
mockRequest.setParameter(OAuthConstants.RESPONSE_TYPE, RESPONSE_TYPE);
mockRequest.setParameter(OAuthConstants.CLIENT_ID, CLIENT_ID);
mockRequest.setParameter(OAuthConstants.REDIRECT_URI, REDIRECT_URI);
mockRequest.setParameter(OAuthConstants.ACCESS_TYPE, ACCESS_TYPE);
mockRequest.setParameter(OAuthConstants.STATE, STATE);
mockRequest.setParameter(OAuthConstants.SCOPE, SCOPE);
final MockHttpServletResponse mockResponse = new MockHttpServletResponse();
final OAuth20WrapperController oauth20WrapperController = new OAuth20WrapperController();
oauth20WrapperController.setCentralOAuthService(centralOAuthService);
oauth20WrapperController.setLoginUrl(CAS_URL);
oauth20WrapperController.afterPropertiesSet();
final ModelAndView modelAndView = oauth20WrapperController.handleRequest(mockRequest, mockResponse);
assertTrue(modelAndView.getView() instanceof RedirectView);
final RedirectView redirectView = (RedirectView) modelAndView.getView();
assertTrue(redirectView.getUrl().contains("?service=http"));
assertTrue(redirectView.getUrl().endsWith(OAuthConstants.CALLBACK_AUTHORIZE_URL));
final HttpSession session = mockRequest.getSession();
assertEquals(Boolean.FALSE, session.getAttribute(OAuthConstants.BYPASS_APPROVAL_PROMPT));
assertEquals(OAuthConstants.APPROVAL_PROMPT_AUTO, session.getAttribute(OAuthConstants.OAUTH20_APPROVAL_PROMPT));
assertEquals(TokenType.OFFLINE, session.getAttribute(OAuthConstants.OAUTH20_TOKEN_TYPE));
assertEquals(RESPONSE_TYPE, session.getAttribute(OAuthConstants.OAUTH20_RESPONSE_TYPE));
assertEquals(CLIENT_ID, session.getAttribute(OAuthConstants.OAUTH20_CLIENT_ID));
assertEquals(REDIRECT_URI, session.getAttribute(OAuthConstants.OAUTH20_REDIRECT_URI));
assertEquals(SERVICE_NAME, session.getAttribute(OAuthConstants.OAUTH20_SERVICE_NAME));
assertEquals(SCOPE, session.getAttribute(OAuthConstants.OAUTH20_SCOPE));
assertEquals(STATE, session.getAttribute(OAuthConstants.OAUTH20_STATE));
}
@Test
public void verifyDefaultsOK() throws Exception {
final OAuthRegisteredService service = getRegisteredService(REDIRECT_URI, SERVICE_NAME);
final CentralOAuthService centralOAuthService = mock(CentralOAuthService.class);
when(centralOAuthService.getRegisteredService(CLIENT_ID)).thenReturn(service);
final MockHttpServletRequest mockRequest = new MockHttpServletRequest("GET", CONTEXT
+ OAuthConstants.AUTHORIZE_URL);
mockRequest.setParameter(OAuthConstants.CLIENT_ID, CLIENT_ID);
mockRequest.setParameter(OAuthConstants.REDIRECT_URI, REDIRECT_URI);
mockRequest.setParameter(OAuthConstants.STATE, STATE);
final MockHttpServletResponse mockResponse = new MockHttpServletResponse();
final OAuth20WrapperController oauth20WrapperController = new OAuth20WrapperController();
oauth20WrapperController.setCentralOAuthService(centralOAuthService);
oauth20WrapperController.setLoginUrl(CAS_URL);
oauth20WrapperController.afterPropertiesSet();
final ModelAndView modelAndView = oauth20WrapperController.handleRequest(mockRequest, mockResponse);
assertTrue(modelAndView.getView() instanceof RedirectView);
final RedirectView redirectView = (RedirectView) modelAndView.getView();
assertTrue(redirectView.getUrl().contains("?service=http"));
assertTrue(redirectView.getUrl().endsWith(OAuthConstants.CALLBACK_AUTHORIZE_URL));
final HttpSession session = mockRequest.getSession();
assertEquals(Boolean.FALSE, session.getAttribute(OAuthConstants.BYPASS_APPROVAL_PROMPT));
assertEquals(OAuthConstants.APPROVAL_PROMPT_AUTO, session.getAttribute(OAuthConstants.OAUTH20_APPROVAL_PROMPT));
assertEquals(DEFAULT_ACCESS_TYPE, session.getAttribute(OAuthConstants.OAUTH20_TOKEN_TYPE));
assertEquals(RESPONSE_TYPE, session.getAttribute(OAuthConstants.OAUTH20_RESPONSE_TYPE));
assertEquals(CLIENT_ID, session.getAttribute(OAuthConstants.OAUTH20_CLIENT_ID));
assertEquals(REDIRECT_URI, session.getAttribute(OAuthConstants.OAUTH20_REDIRECT_URI));
assertEquals(SERVICE_NAME, session.getAttribute(OAuthConstants.OAUTH20_SERVICE_NAME));
assertEquals(DEFAULT_SCOPE, session.getAttribute(OAuthConstants.OAUTH20_SCOPE));
assertEquals(STATE, session.getAttribute(OAuthConstants.OAUTH20_STATE));
}
private OAuthRegisteredService getRegisteredService(final String serviceId, final String name) {
final OAuthRegisteredService registeredServiceImpl = new OAuthRegisteredService();
registeredServiceImpl.setName(name);
registeredServiceImpl.setServiceId(serviceId);
registeredServiceImpl.setClientId(CLIENT_ID);
return registeredServiceImpl;
}
}