mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-13 17:05:43 +01:00
fixed admin permissions of initial created scmadmin user account
This commit is contained in:
@@ -1,41 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
||||||
<!--
|
|
||||||
|
|
||||||
Copyright (c) 2010, Sebastian Sdorra
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
3. Neither the name of SCM-Manager; nor the names of its
|
|
||||||
contributors may be used to endorse or promote products derived from this
|
|
||||||
software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
http://bitbucket.org/sdorra/scm-manager
|
|
||||||
|
|
||||||
|
|
||||||
-->
|
|
||||||
<users>
|
|
||||||
<name>scmadmin</name>
|
|
||||||
<displayName>SCM Administrator</displayName>
|
|
||||||
<mail>scm-admin@scm-manager.org</mail>
|
|
||||||
<password>$shiro1$SHA-512$8192$$yrNahBVDa4Gz+y5gat4msdjyvjtHlVE+N5nTl4WIDhtBFwhSIib13mKJt1sWmVqgHDWi3VwX7fkdkJ2+WToTbw==</password>
|
|
||||||
<admin>true</admin>
|
|
||||||
<type>xml</type>
|
|
||||||
</users>
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!--
|
|
||||||
|
|
||||||
Copyright (c) 2010, Sebastian Sdorra
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
3. Neither the name of SCM-Manager; nor the names of its
|
|
||||||
contributors may be used to endorse or promote products derived from this
|
|
||||||
software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
http://bitbucket.org/sdorra/scm-manager
|
|
||||||
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Document : anonymous-account.xml
|
|
||||||
Created on : December 30, 2010, 12:44 PM
|
|
||||||
Author : sdorra
|
|
||||||
Description:
|
|
||||||
Purpose of the document follows.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<users>
|
|
||||||
<name>anonymous</name>
|
|
||||||
<displayName>SCM Anonymous</displayName>
|
|
||||||
<mail>scm-anonymous@scm-manager.org</mail>
|
|
||||||
<admin>false</admin>
|
|
||||||
<type>xml</type>
|
|
||||||
</users>
|
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package sonia.scm.boot;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import org.apache.shiro.authc.credential.PasswordService;
|
||||||
|
import sonia.scm.plugin.Extension;
|
||||||
|
import sonia.scm.security.PermissionAssigner;
|
||||||
|
import sonia.scm.security.PermissionDescriptor;
|
||||||
|
import sonia.scm.user.User;
|
||||||
|
import sonia.scm.user.UserManager;
|
||||||
|
import sonia.scm.web.security.AdministrationContext;
|
||||||
|
import sonia.scm.web.security.PrivilegedAction;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.servlet.ServletContextEvent;
|
||||||
|
import javax.servlet.ServletContextListener;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
@Extension
|
||||||
|
public class SetupContextListener implements ServletContextListener {
|
||||||
|
|
||||||
|
private final AdministrationContext administrationContext;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SetupContextListener(AdministrationContext administrationContext) {
|
||||||
|
this.administrationContext = administrationContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextInitialized(ServletContextEvent sce) {
|
||||||
|
administrationContext.runAsAdmin(SetupAction.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextDestroyed(ServletContextEvent sce) {}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
static class SetupAction implements PrivilegedAction {
|
||||||
|
|
||||||
|
private final UserManager userManager;
|
||||||
|
private final PasswordService passwordService;
|
||||||
|
private final PermissionAssigner permissionAssigner;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SetupAction(UserManager userManager, PasswordService passwordService, PermissionAssigner permissionAssigner) {
|
||||||
|
this.userManager = userManager;
|
||||||
|
this.passwordService = passwordService;
|
||||||
|
this.permissionAssigner = permissionAssigner;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (isFirstStart()) {
|
||||||
|
createAdminAccount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isFirstStart() {
|
||||||
|
return userManager.getAll().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createAdminAccount() {
|
||||||
|
User scmadmin = new User("scmadmin", "SCM Administrator", "scm-admin@scm-manager.org");
|
||||||
|
String password = passwordService.encryptPassword("scmadmin");
|
||||||
|
scmadmin.setPassword(password);
|
||||||
|
userManager.create(scmadmin);
|
||||||
|
|
||||||
|
PermissionDescriptor descriptor = new PermissionDescriptor("*");
|
||||||
|
permissionAssigner.setPermissionsForUser("scmadmin", Collections.singleton(descriptor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -71,13 +71,6 @@ import java.util.List;
|
|||||||
public class DefaultUserManager extends AbstractUserManager
|
public class DefaultUserManager extends AbstractUserManager
|
||||||
{
|
{
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
public static final String ADMIN_PATH = "/sonia/scm/config/admin-account.xml";
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
public static final String ANONYMOUS_PATH =
|
|
||||||
"/sonia/scm/config/anonymous-account.xml";
|
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
public static final String STORE_NAME = "users";
|
public static final String STORE_NAME = "users";
|
||||||
|
|
||||||
@@ -173,12 +166,6 @@ public class DefaultUserManager extends AbstractUserManager
|
|||||||
@Override
|
@Override
|
||||||
public void init(SCMContextProvider context)
|
public void init(SCMContextProvider context)
|
||||||
{
|
{
|
||||||
|
|
||||||
// create default account only, if no other account is available
|
|
||||||
if (userDAO.getAll().isEmpty())
|
|
||||||
{
|
|
||||||
createDefaultAccounts();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -457,28 +444,6 @@ public class DefaultUserManager extends AbstractUserManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private void createDefaultAccounts()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
logger.info("create default accounts");
|
|
||||||
|
|
||||||
JAXBContext context = JAXBContext.newInstance(User.class);
|
|
||||||
Unmarshaller unmarshaller = context.createUnmarshaller();
|
|
||||||
|
|
||||||
createDefaultAccount(unmarshaller, ADMIN_PATH);
|
|
||||||
createDefaultAccount(unmarshaller, ANONYMOUS_PATH);
|
|
||||||
}
|
|
||||||
catch (JAXBException ex)
|
|
||||||
{
|
|
||||||
logger.error("could not create default accounts", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//~--- fields ---------------------------------------------------------------
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
private final UserDAO userDAO;
|
private final UserDAO userDAO;
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
package sonia.scm.boot;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import org.apache.shiro.authc.credential.PasswordService;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import sonia.scm.security.PermissionAssigner;
|
||||||
|
import sonia.scm.security.PermissionDescriptor;
|
||||||
|
import sonia.scm.user.User;
|
||||||
|
import sonia.scm.user.UserManager;
|
||||||
|
import sonia.scm.user.UserTestData;
|
||||||
|
import sonia.scm.web.security.AdministrationContext;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class SetupContextListenerTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private AdministrationContext administrationContext;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private SetupContextListener setupContextListener;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private UserManager userManager;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private PasswordService passwordService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private PermissionAssigner permissionAssigner;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private SetupContextListener.SetupAction setupAction;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setupObjectUnderTest() {
|
||||||
|
doAnswer(ic -> {
|
||||||
|
setupAction.run();
|
||||||
|
return null;
|
||||||
|
}).when(administrationContext).runAsAdmin(SetupContextListener.SetupAction.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldCreateAdminAccountAndAssignPermissions() {
|
||||||
|
when(passwordService.encryptPassword("scmadmin")).thenReturn("secret");
|
||||||
|
|
||||||
|
setupContextListener.contextInitialized(null);
|
||||||
|
|
||||||
|
verifyAdminCreated();
|
||||||
|
verifyAdminPermissionsAssigned();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldDoNothingOnSecondStart() {
|
||||||
|
List<User> users = Lists.newArrayList(UserTestData.createTrillian());
|
||||||
|
when(userManager.getAll()).thenReturn(users);
|
||||||
|
|
||||||
|
setupContextListener.contextInitialized(null);
|
||||||
|
|
||||||
|
verify(userManager, never()).create(any(User.class));
|
||||||
|
verify(permissionAssigner, never()).setPermissionsForUser(anyString(), any(Collection.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyAdminPermissionsAssigned() {
|
||||||
|
ArgumentCaptor<String> usernameCaptor = ArgumentCaptor.forClass(String.class);
|
||||||
|
ArgumentCaptor<Collection<PermissionDescriptor>> permissionCaptor = ArgumentCaptor.forClass(Collection.class);
|
||||||
|
verify(permissionAssigner).setPermissionsForUser(usernameCaptor.capture(), permissionCaptor.capture());
|
||||||
|
String username = usernameCaptor.getValue();
|
||||||
|
assertThat(username).isEqualTo("scmadmin");
|
||||||
|
PermissionDescriptor descriptor = permissionCaptor.getValue().iterator().next();
|
||||||
|
assertThat(descriptor.getValue()).isEqualTo("*");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyAdminCreated() {
|
||||||
|
ArgumentCaptor<User> userCaptor = ArgumentCaptor.forClass(User.class);
|
||||||
|
verify(userManager).create(userCaptor.capture());
|
||||||
|
User user = userCaptor.getValue();
|
||||||
|
assertThat(user.getName()).isEqualTo("scmadmin");
|
||||||
|
assertThat(user.getPassword()).isEqualTo("secret");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -97,39 +97,6 @@ public class DefaultUserManagerTest extends UserManagerTestBase
|
|||||||
when(userDAO.get("trillian")).thenReturn(trillian);
|
when(userDAO.get("trillian")).thenReturn(trillian);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testDefaultAccountAfterFristStart()
|
|
||||||
{
|
|
||||||
List<User> users = Lists.newArrayList(new User("tuser"));
|
|
||||||
|
|
||||||
when(userDAO.getAll()).thenReturn(users);
|
|
||||||
|
|
||||||
UserManager userManager = new DefaultUserManager(userDAO);
|
|
||||||
|
|
||||||
userManager.init(contextProvider);
|
|
||||||
verify(userDAO, never()).add(any(User.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void testDefaultAccountCreation()
|
|
||||||
{
|
|
||||||
when(userDAO.getAll()).thenReturn(Collections.EMPTY_LIST);
|
|
||||||
|
|
||||||
UserManager userManager = new DefaultUserManager(userDAO);
|
|
||||||
|
|
||||||
userManager.init(contextProvider);
|
|
||||||
verify(userDAO, times(2)).add(any(User.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = InvalidPasswordException.class)
|
@Test(expected = InvalidPasswordException.class)
|
||||||
public void shouldFailChangePasswordForWrongOldPassword() {
|
public void shouldFailChangePasswordForWrongOldPassword() {
|
||||||
UserManager userManager = new DefaultUserManager(userDAO);
|
UserManager userManager = new DefaultUserManager(userDAO);
|
||||||
|
|||||||
Reference in New Issue
Block a user