/** * This file is part of lavagna. * * lavagna is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * lavagna is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with lavagna. If not, see <http://www.gnu.org/licenses/>. */ package io.lavagna.web.security.login.oauth; import io.lavagna.web.security.SecurityConfiguration.SessionHandler; import io.lavagna.web.security.SecurityConfiguration.User; import io.lavagna.web.security.SecurityConfiguration.Users; import io.lavagna.web.security.login.oauth.OAuthResultHandler.OAuthRequestBuilder; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.scribe.builder.ServiceBuilder; import org.scribe.builder.api.Api; import org.scribe.model.OAuthRequest; import org.scribe.model.Response; import org.scribe.model.Verb; import org.scribe.oauth.OAuthService; import org.springframework.mock.web.MockHttpSession; import org.springframework.web.context.WebApplicationContext; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class HandlersTest { @Mock private ServiceBuilder sBuilder; @Mock private SessionHandler sessionHandler; @Mock private Users users; @Mock private HttpServletRequest req, req2; @Mock private HttpServletResponse resp, resp2; @Mock private OAuthService oauthService; @Mock private ServletContext servletContext; @Mock private WebApplicationContext webappContext; @Mock private OAuthRequestBuilder reqBuilder; @Mock private OAuthRequest oauthReq; @Mock private Response oauthRes; @Mock private User user; private MockHttpSession session; private String key = "key"; private String secret = "secret"; private String callback = "callback"; private String errPage = "error"; private OAuthResultHandler bitbucketHandler; private OAuthResultHandler googleHandler; private OAuthResultHandler githubHandler; private OAuthResultHandler gitlabHandler; private OAuthResultHandler twitterHandler; @Before public void prepare() { when(sBuilder.provider(any(Api.class))).thenReturn(sBuilder); when(sBuilder.apiKey(any(String.class))).thenReturn(sBuilder); when(sBuilder.apiSecret(any(String.class))).thenReturn(sBuilder); when(sBuilder.callback(any(String.class))).thenReturn(sBuilder); when(sBuilder.scope(any(String.class))).thenReturn(sBuilder); when(sBuilder.build()).thenReturn(oauthService); session = new MockHttpSession(); when(req2.getParameter("code")).thenReturn("code"); when(req2.getParameter("oauth_verifier")).thenReturn("code"); when(req.getSession()).thenReturn(session); when(req2.getSession()).thenReturn(session); when(reqBuilder.req(any(Verb.class), any(String.class))).thenReturn(oauthReq); when(oauthReq.send()).thenReturn(oauthRes); when(users.findUserByName(any(String.class), any(String.class))).thenReturn(user); bitbucketHandler = BitbucketHandler.FACTORY.build(sBuilder, reqBuilder, new OAuthProvider("bitbucket", key, secret), callback, users, sessionHandler, errPage); githubHandler = GithubHandler.FACTORY.build(sBuilder, reqBuilder, new OAuthProvider("github", key, secret), callback, users, sessionHandler, errPage); googleHandler = GoogleHandler.FACTORY.build(sBuilder, reqBuilder, new OAuthProvider("google", key, secret), callback, users, sessionHandler, errPage); gitlabHandler = GitlabHandler.FACTORY.build(sBuilder, reqBuilder, new OAuthProvider("gitlab", key, secret), callback, users, sessionHandler, errPage); twitterHandler = TwitterHandler.FACTORY.build(sBuilder, reqBuilder, new OAuthProvider("twiiter", key, secret), callback, users, sessionHandler, errPage); } @Test public void handleBitbucketFlowAuth() throws IOException { when(oauthService.getAuthorizationUrl(null)).thenReturn("redirect"); bitbucketHandler.handleAuthorizationUrl(req, resp); verify(resp).sendRedirect("redirect&state=" + session.getAttribute("EXPECTED_STATE_FOR_oauth.bitbucket")); when(req2.getParameter("state")).thenReturn((String) session.getAttribute("EXPECTED_STATE_FOR_oauth.bitbucket")); when(oauthRes.getBody()).thenReturn("{\"username\" : \"username\"}"); when(users.userExistsAndEnabled("oauth.bitbucket", "username")).thenReturn(true); when(users.findUserByName("oauth.bitbucket", "username")).thenReturn(user); when(req2.getContextPath()).thenReturn(""); Assert.assertTrue(!session.isInvalid()); bitbucketHandler.handleCallback(req2, resp2); verify(resp2).sendRedirect("/"); verify(sessionHandler).setUser(user.getId(), user.isAnonymous(), req2, resp2); } @Test public void handleTwitterFlowAuth() throws IOException { when(oauthService.getAuthorizationUrl(null)).thenReturn("redirect"); twitterHandler.handleAuthorizationUrl(req, resp); verify(resp).sendRedirect("redirect"); when(oauthRes.getBody()).thenReturn("{\"screen_name\" : \"username\"}"); when(users.userExistsAndEnabled("oauth.twitter", "username")).thenReturn(true); when(users.findUserByName("oauth.twitter", "username")).thenReturn(user); when(req2.getContextPath()).thenReturn(""); Assert.assertTrue(!session.isInvalid()); twitterHandler.handleCallback(req2, resp2); verify(resp2).sendRedirect("/"); verify(sessionHandler).setUser(user.getId(), user.isAnonymous(), req2, resp2); } @Test public void handleGithubFlowAuth() throws IOException { when(oauthService.getAuthorizationUrl(null)).thenReturn("redirect"); githubHandler.handleAuthorizationUrl(req, resp); verify(resp).sendRedirect("redirect&state=" + session.getAttribute("EXPECTED_STATE_FOR_oauth.github")); when(req2.getParameter("state")).thenReturn((String) session.getAttribute("EXPECTED_STATE_FOR_oauth.github")); when(oauthRes.getBody()).thenReturn("{\"login\" : \"login\"}"); when(users.userExistsAndEnabled("oauth.github", "login")).thenReturn(true); when(users.findUserByName("oauth.github", "login")).thenReturn(user); when(req2.getContextPath()).thenReturn(""); Assert.assertTrue(!session.isInvalid()); githubHandler.handleCallback(req2, resp2); verify(resp2).sendRedirect("/"); verify(sessionHandler).setUser(user.getId(), user.isAnonymous(), req2, resp2); } @Test public void handleGoogleFlowAuth() throws IOException { when(oauthService.getAuthorizationUrl(null)).thenReturn("redirect"); googleHandler.handleAuthorizationUrl(req, resp); verify(resp).sendRedirect("redirect&state=" + session.getAttribute("EXPECTED_STATE_FOR_oauth.google")); when(req2.getParameter("state")).thenReturn((String) session.getAttribute("EXPECTED_STATE_FOR_oauth.google")); when(oauthRes.getBody()).thenReturn("{\"email\" : \"email\", \"email_verified\" : true}"); when(users.userExistsAndEnabled("oauth.google", "email")).thenReturn(true); when(users.findUserByName("oauth.google", "email")).thenReturn(user); when(req2.getContextPath()).thenReturn("/context-path"); Assert.assertTrue(!session.isInvalid()); googleHandler.handleCallback(req2, resp2); verify(resp2).sendRedirect("/context-path/"); verify(sessionHandler).setUser(user.getId(), user.isAnonymous(), req2, resp2); } @Test public void handleGitlabFlowAuth() throws IOException { when(oauthService.getAuthorizationUrl(null)).thenReturn("redirect"); gitlabHandler.handleAuthorizationUrl(req, resp); verify(resp).sendRedirect("redirect&state=" + session.getAttribute("EXPECTED_STATE_FOR_oauth.gitlab")); when(req2.getParameter("state")).thenReturn((String) session.getAttribute("EXPECTED_STATE_FOR_oauth.gitlab")); when(oauthRes.getBody()).thenReturn("{\"username\" : \"username\"}"); when(users.userExistsAndEnabled("oauth.gitlab", "username")).thenReturn(true); when(users.findUserByName("oauth.gitlab", "username")).thenReturn(user); when(req2.getContextPath()).thenReturn("/context-path"); Assert.assertTrue(!session.isInvalid()); gitlabHandler.handleCallback(req2, resp2); verify(resp2).sendRedirect("/context-path/"); verify(sessionHandler).setUser(user.getId(), user.isAnonymous(), req2, resp2); } }