/* * Copyright 2017 ThoughtWorks, Inc. * * Licensed 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 * * 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 com.thoughtworks.go.server.web; import com.thoughtworks.go.server.security.GoAuthority; import com.thoughtworks.go.server.service.RailsAssetsService; import com.thoughtworks.go.server.service.VersionInfoService; import com.thoughtworks.go.server.service.support.toggle.FeatureToggleService; import com.thoughtworks.go.server.service.support.toggle.Toggles; import com.thoughtworks.go.util.SystemEnvironment; import org.apache.velocity.VelocityContext; import org.apache.velocity.context.Context; import org.eclipse.jetty.server.Request; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.security.GrantedAuthority; import org.springframework.security.GrantedAuthorityImpl; import org.springframework.security.context.SecurityContextImpl; import org.springframework.security.providers.TestingAuthenticationToken; import org.springframework.security.userdetails.User; import org.springframework.security.userdetails.ldap.LdapUserDetailsImpl; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsNull.nullValue; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.*; import static org.mockito.MockitoAnnotations.initMocks; import static org.springframework.security.context.HttpSessionContextIntegrationFilter.SPRING_SECURITY_CONTEXT_KEY; public class GoVelocityViewTest { private GoVelocityView view; private HttpServletRequest request; private Context velocityContext; private SecurityContextImpl securityContext; @Mock private RailsAssetsService railsAssetsService; @Mock private FeatureToggleService featureToggleService; @Mock private VersionInfoService versionInfoService; @Before public void setUp() throws Exception { initMocks(this); when(featureToggleService.isToggleOn(anyString())).thenReturn(true); Toggles.initializeWith(featureToggleService); view = spy(new GoVelocityView()); doReturn(railsAssetsService).when(view).getRailsAssetsService(); doReturn(versionInfoService).when(view).getVersionInfoService(); request = new MockHttpServletRequest(); velocityContext = new VelocityContext(); securityContext = new SecurityContextImpl(); } @Test public void shouldRetriveLdapCompleteNameFromSessionWhenAuthenticated() throws Exception { securityContext.setAuthentication(new TestingAuthenticationToken(new LdapUserDetailsImpl() { public String getUsername() { return "test1"; } public String getDn() { return "cn=Test User, ou=Beijing, ou=Employees, ou=Enterprise, ou=Principal"; } }, null, null)); request.getSession().setAttribute(SPRING_SECURITY_CONTEXT_KEY, securityContext); view.exposeHelpers(velocityContext, request); assertThat(velocityContext.get(GoVelocityView.PRINCIPAL), is("Test User")); } @Test public void shouldSetAdministratorIfUserIsAdministrator() throws Exception { securityContext.setAuthentication( new TestingAuthenticationToken("jez", "badger", new GrantedAuthority[]{new GrantedAuthorityImpl(GoAuthority.ROLE_SUPERVISOR.toString())})); request.getSession().setAttribute(SPRING_SECURITY_CONTEXT_KEY, securityContext); view.exposeHelpers(velocityContext, request); assertThat(velocityContext.get(GoVelocityView.ADMINISTRATOR), is(true)); } @Test public void shouldSetTemplateAdministratorIfUserIsTemplateAdministrator() throws Exception { securityContext.setAuthentication( new TestingAuthenticationToken("jez", "badger", new GrantedAuthority[]{new GrantedAuthorityImpl(GoAuthority.ROLE_TEMPLATE_SUPERVISOR.toString())})); request.getSession().setAttribute(SPRING_SECURITY_CONTEXT_KEY, securityContext); view.exposeHelpers(velocityContext, request); assertThat(velocityContext.get(GoVelocityView.TEMPLATE_ADMINISTRATOR), is(true)); } @Test public void shouldSetTemplateViewUserRightsForTemplateViewUser() throws Exception { securityContext.setAuthentication( new TestingAuthenticationToken("templateView", "badger", new GrantedAuthority[]{new GrantedAuthorityImpl(GoAuthority.ROLE_TEMPLATE_VIEW_USER.toString())})); request.getSession().setAttribute(SPRING_SECURITY_CONTEXT_KEY, securityContext); view.exposeHelpers(velocityContext, request); assertThat(velocityContext.get(GoVelocityView.TEMPLATE_VIEW_USER), is(true)); } @Test public void shouldSetViewAdministratorRightsIfUserHasAnyLevelOfAdministratorRights() throws Exception { securityContext.setAuthentication(new TestingAuthenticationToken("jez", "badger", new GrantedAuthority[]{new GrantedAuthorityImpl(GoAuthority.ROLE_TEMPLATE_SUPERVISOR.toString())})); request.getSession().setAttribute(SPRING_SECURITY_CONTEXT_KEY, securityContext); view.exposeHelpers(velocityContext, request); assertThat(velocityContext.get(GoVelocityView.VIEW_ADMINISTRATOR_RIGHTS), is(true)); securityContext.setAuthentication(new TestingAuthenticationToken("jez", "badger", new GrantedAuthority[]{new GrantedAuthorityImpl(GoAuthority.ROLE_GROUP_SUPERVISOR.toString())})); request.getSession().setAttribute(SPRING_SECURITY_CONTEXT_KEY, securityContext); view.exposeHelpers(velocityContext, request); assertThat(velocityContext.get(GoVelocityView.VIEW_ADMINISTRATOR_RIGHTS), is(true)); securityContext.setAuthentication(new TestingAuthenticationToken("jez", "badger", new GrantedAuthority[]{new GrantedAuthorityImpl(GoAuthority.ROLE_SUPERVISOR.toString())})); request.getSession().setAttribute(SPRING_SECURITY_CONTEXT_KEY, securityContext); view.exposeHelpers(velocityContext, request); assertThat(velocityContext.get(GoVelocityView.VIEW_ADMINISTRATOR_RIGHTS), is(true)); securityContext.setAuthentication(new TestingAuthenticationToken("jez", "badger", new GrantedAuthority[]{new GrantedAuthorityImpl(GoAuthority.ROLE_TEMPLATE_VIEW_USER.toString())})); request.getSession().setAttribute(SPRING_SECURITY_CONTEXT_KEY, securityContext); view.exposeHelpers(velocityContext, request); assertThat(velocityContext.get(GoVelocityView.VIEW_ADMINISTRATOR_RIGHTS), is(true)); securityContext.setAuthentication(new TestingAuthenticationToken("jez", "badger", new GrantedAuthority[]{new GrantedAuthorityImpl(GoAuthority.ROLE_USER.toString())})); request.getSession().setAttribute(SPRING_SECURITY_CONTEXT_KEY, securityContext); view.exposeHelpers(velocityContext, request); assertThat(velocityContext.get(GoVelocityView.VIEW_ADMINISTRATOR_RIGHTS), is(nullValue())); } @Test public void shouldSetGroupAdministratorIfUserIsAPipelineGroupAdministrator() throws Exception { securityContext.setAuthentication( new TestingAuthenticationToken("jez", "badger", new GrantedAuthority[]{new GrantedAuthorityImpl(GoAuthority.ROLE_GROUP_SUPERVISOR.toString())})); request.getSession().setAttribute(SPRING_SECURITY_CONTEXT_KEY, securityContext); view.exposeHelpers(velocityContext, request); assertThat(velocityContext.get(GoVelocityView.ADMINISTRATOR), is(nullValue())); assertThat(velocityContext.get(GoVelocityView.GROUP_ADMINISTRATOR), is(true)); } @Test public void shouldNotSetPrincipalIfNoSession() throws Exception { view.exposeHelpers(velocityContext, request); assertNull("Principal should be null", velocityContext.get(GoVelocityView.PRINCIPAL)); } @Test public void shouldNotSetPrincipalIfAuthenticationInformationNotAvailable() throws Exception { request.getSession().setAttribute(SPRING_SECURITY_CONTEXT_KEY, securityContext); view.exposeHelpers(velocityContext, request); assertNull("Principal should be null", velocityContext.get(GoVelocityView.PRINCIPAL)); } @Test public void principalIsTheUsernameWhenNothingElseAvailable() throws Exception { request.getSession().setAttribute(SPRING_SECURITY_CONTEXT_KEY, securityContext); securityContext.setAuthentication( new TestingAuthenticationToken( new User("Test User", "pwd", true, new GrantedAuthority[]{new GrantedAuthorityImpl("nowt")}), null, null)); view.exposeHelpers(velocityContext, request); assertThat(velocityContext.get(GoVelocityView.PRINCIPAL), is("Test User")); } @Test public void shouldSetAssetsPathVariableWhenRailsNewWithCompressedJavascriptsIsUsed() throws Exception { SystemEnvironment systemEnvironment = mock(SystemEnvironment.class); when(systemEnvironment.useCompressedJs()).thenReturn(true); when(railsAssetsService.getAssetPath("application.js")).thenReturn("assets/application-digest.js"); when(railsAssetsService.getAssetPath("application.css")).thenReturn("assets/application-digest.css"); when(railsAssetsService.getAssetPath("vm/application.css")).thenReturn("assets/vm/application-digest.css"); when(railsAssetsService.getAssetPath("css/application.css")).thenReturn("assets/css/application-digest.css"); when(railsAssetsService.getAssetPath("g9/stage_bar_cancelled_icon.png")).thenReturn("assets/g9/stage_bar_cancelled_icon.png"); when(railsAssetsService.getAssetPath("spinner.gif")).thenReturn("assets/spinner.gif"); when(railsAssetsService.getAssetPath("cruise.ico")).thenReturn("assets/cruise.ico"); GoVelocityView view = spy(new GoVelocityView(systemEnvironment)); doReturn(railsAssetsService).when(view).getRailsAssetsService(); doReturn(versionInfoService).when(view).getVersionInfoService(); Request servletRequest = mock(Request.class); when(servletRequest.getSession()).thenReturn(mock(HttpSession.class)); view.exposeHelpers(velocityContext, servletRequest); assertThat(velocityContext.get(GoVelocityView.CONCATENATED_JAVASCRIPT_FILE_PATH), is("assets/application-digest.js")); assertThat(velocityContext.get(GoVelocityView.CONCATENATED_APPLICATION_CSS_FILE_PATH), is("assets/application-digest.css")); assertThat(velocityContext.get(GoVelocityView.CONCATENATED_VM_APPLICATION_CSS_FILE_PATH), is("assets/vm/application-digest.css")); assertThat(velocityContext.get(GoVelocityView.CONCATENATED_CSS_APPLICATION_CSS_FILE_PATH), is("assets/css/application-digest.css")); assertThat(velocityContext.get(GoVelocityView.CONCATENATED_STAGE_BAR_CANCELLED_ICON_FILE_PATH), is("assets/g9/stage_bar_cancelled_icon.png")); assertThat(velocityContext.get(GoVelocityView.CONCATENATED_SPINNER_ICON_FILE_PATH), is("assets/spinner.gif")); assertThat(velocityContext.get(GoVelocityView.CONCATENATED_CRUISE_ICON_FILE_PATH), is("assets/cruise.ico")); assertThat(velocityContext.get(GoVelocityView.PATH_RESOLVER), is(railsAssetsService)); } @Test public void shouldSetAssetsPathVariableWhenRailsNewIsUsedInDevelopmentEnvironment() throws Exception { SystemEnvironment systemEnvironment = mock(SystemEnvironment.class); when(systemEnvironment.useCompressedJs()).thenReturn(false); when(railsAssetsService.getAssetPath("application.js")).thenReturn("assets/application.js"); when(railsAssetsService.getAssetPath("application.css")).thenReturn("assets/application.css"); when(railsAssetsService.getAssetPath("vm/application.css")).thenReturn("assets/vm/application.css"); when(railsAssetsService.getAssetPath("css/application.css")).thenReturn("assets/css/application.css"); GoVelocityView view = spy(new GoVelocityView(systemEnvironment)); doReturn(railsAssetsService).when(view).getRailsAssetsService(); doReturn(versionInfoService).when(view).getVersionInfoService(); Request servletRequest = mock(Request.class); when(servletRequest.getSession()).thenReturn(mock(HttpSession.class)); view.exposeHelpers(velocityContext, servletRequest); assertThat(velocityContext.get(GoVelocityView.CONCATENATED_JAVASCRIPT_FILE_PATH), is("assets/application.js")); assertThat(velocityContext.get(GoVelocityView.CONCATENATED_APPLICATION_CSS_FILE_PATH), is("assets/application.css")); assertThat(velocityContext.get(GoVelocityView.CONCATENATED_VM_APPLICATION_CSS_FILE_PATH), is("assets/vm/application.css")); assertThat(velocityContext.get(GoVelocityView.CONCATENATED_CSS_APPLICATION_CSS_FILE_PATH), is("assets/css/application.css")); } @Test public void shouldSetFeatureToggleValues() throws Exception { Request servletRequest = mock(Request.class); when(servletRequest.getSession()).thenReturn(mock(HttpSession.class)); view.exposeHelpers(velocityContext, servletRequest); assertThat(velocityContext.get(Toggles.PIPELINE_COMMENT_FEATURE_TOGGLE_KEY), is(true)); } @Test public void shouldSetGoUpdateFeatureValues() throws Exception { Request servletRequest = mock(Request.class); when(versionInfoService.isGOUpdateCheckEnabled()).thenReturn(true); when(servletRequest.getSession()).thenReturn(mock(HttpSession.class)); when(versionInfoService.getGoUpdate()).thenReturn("16.1.0-123"); view.exposeHelpers(velocityContext, servletRequest); assertTrue((Boolean) velocityContext.get(GoVelocityView.GO_UPDATE_CHECK_ENABLED)); assertThat(velocityContext.get(GoVelocityView.GO_UPDATE), is("16.1.0-123")); } }