Extract properties from users and groups in v1 into own file

This commit is contained in:
René Pfeuffer
2019-06-03 14:22:57 +02:00
parent 3b3ddd8fb0
commit 0be816dd28
6 changed files with 131 additions and 21 deletions

View File

@@ -8,6 +8,8 @@ import sonia.scm.group.xml.XmlGroupDAO;
import sonia.scm.migration.UpdateException; import sonia.scm.migration.UpdateException;
import sonia.scm.migration.UpdateStep; import sonia.scm.migration.UpdateStep;
import sonia.scm.plugin.Extension; import sonia.scm.plugin.Extension;
import sonia.scm.store.ConfigurationEntryStore;
import sonia.scm.store.ConfigurationEntryStoreFactory;
import sonia.scm.store.StoreConstants; import sonia.scm.store.StoreConstants;
import sonia.scm.version.Version; import sonia.scm.version.Version;
@@ -37,11 +39,20 @@ public class XmlGroupV1UpdateStep implements UpdateStep {
private final SCMContextProvider contextProvider; private final SCMContextProvider contextProvider;
private final XmlGroupDAO groupDAO; private final XmlGroupDAO groupDAO;
private final ConfigurationEntryStore<V1Properties> propertyStore;
@Inject @Inject
public XmlGroupV1UpdateStep(SCMContextProvider contextProvider, XmlGroupDAO groupDAO) { public XmlGroupV1UpdateStep(
SCMContextProvider contextProvider,
XmlGroupDAO groupDAO,
ConfigurationEntryStoreFactory configurationEntryStoreFactory
) {
this.contextProvider = contextProvider; this.contextProvider = contextProvider;
this.groupDAO = groupDAO; this.groupDAO = groupDAO;
this.propertyStore = configurationEntryStoreFactory
.withType(V1Properties.class)
.withName("group-properties-v1")
.build();
} }
@Override @Override
@@ -52,7 +63,7 @@ public class XmlGroupV1UpdateStep implements UpdateStep {
return; return;
} }
XmlGroupV1UpdateStep.V1GroupDatabase v1Database = readV1Database(v1GroupsFile.get()); XmlGroupV1UpdateStep.V1GroupDatabase v1Database = readV1Database(v1GroupsFile.get());
v1Database.groupList.groups.forEach(group -> update(group)); v1Database.groupList.groups.forEach(this::update);
} }
@Override @Override
@@ -75,6 +86,8 @@ public class XmlGroupV1UpdateStep implements UpdateStep {
group.setCreationDate(v1Group.creationDate); group.setCreationDate(v1Group.creationDate);
group.setLastModified(v1Group.lastModified); group.setLastModified(v1Group.lastModified);
groupDAO.add(group); groupDAO.add(group);
propertyStore.put(v1Group.name, v1Group.properties);
} }
private XmlGroupV1UpdateStep.V1GroupDatabase readV1Database(Path v1GroupsFile) throws JAXBException { private XmlGroupV1UpdateStep.V1GroupDatabase readV1Database(Path v1GroupsFile) throws JAXBException {
@@ -105,7 +118,7 @@ public class XmlGroupV1UpdateStep implements UpdateStep {
@XmlAccessorType(XmlAccessType.FIELD) @XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "group") @XmlRootElement(name = "group")
private static class V1Group { private static class V1Group {
private Map<String, String> properties; private V1Properties properties;
private long creationDate; private long creationDate;
private String description; private String description;
private Long lastModified; private Long lastModified;
@@ -127,6 +140,19 @@ public class XmlGroupV1UpdateStep implements UpdateStep {
} }
} }
@XmlAccessorType(XmlAccessType.FIELD)
private static class V1Property {
private String key;
private String value;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "properties")
private static class V1Properties {
@XmlElement(name = "item")
private List<V1Property> properties;
}
private static class GroupList { private static class GroupList {
@XmlElement(name = "group") @XmlElement(name = "group")
private List<V1Group> groups; private List<V1Group> groups;

View File

@@ -26,7 +26,6 @@ import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import static java.util.Optional.empty; import static java.util.Optional.empty;
@@ -41,12 +40,17 @@ public class XmlUserV1UpdateStep implements UpdateStep {
private final SCMContextProvider contextProvider; private final SCMContextProvider contextProvider;
private final XmlUserDAO userDAO; private final XmlUserDAO userDAO;
private final ConfigurationEntryStoreFactory configurationEntryStoreFactory; private final ConfigurationEntryStoreFactory configurationEntryStoreFactory;
private final ConfigurationEntryStore<V1Properties> propertyStore;
@Inject @Inject
public XmlUserV1UpdateStep(SCMContextProvider contextProvider, XmlUserDAO userDAO, ConfigurationEntryStoreFactory configurationEntryStoreFactory) { public XmlUserV1UpdateStep(SCMContextProvider contextProvider, XmlUserDAO userDAO, ConfigurationEntryStoreFactory configurationEntryStoreFactory) {
this.contextProvider = contextProvider; this.contextProvider = contextProvider;
this.userDAO = userDAO; this.userDAO = userDAO;
this.configurationEntryStoreFactory = configurationEntryStoreFactory; this.configurationEntryStoreFactory = configurationEntryStoreFactory;
this.propertyStore = configurationEntryStoreFactory
.withType(V1Properties.class)
.withName("user-properties-v1")
.build();
} }
@Override @Override
@@ -88,6 +92,8 @@ public class XmlUserV1UpdateStep implements UpdateStep {
LOG.debug("setting admin permissions for user {}", v1User.name); LOG.debug("setting admin permissions for user {}", v1User.name);
securityStore.put(new AssignedPermission(v1User.name, "*")); securityStore.put(new AssignedPermission(v1User.name, "*"));
} }
propertyStore.put(v1User.name, v1User.properties);
} }
private XmlUserV1UpdateStep.V1UserDatabase readV1Database(Path v1UsersFile) throws JAXBException { private XmlUserV1UpdateStep.V1UserDatabase readV1Database(Path v1UsersFile) throws JAXBException {
@@ -119,10 +125,23 @@ public class XmlUserV1UpdateStep implements UpdateStep {
return new File(contextProvider.getBaseDirectory(), StoreConstants.CONFIG_DIRECTORY_NAME).toPath(); return new File(contextProvider.getBaseDirectory(), StoreConstants.CONFIG_DIRECTORY_NAME).toPath();
} }
@XmlAccessorType(XmlAccessType.FIELD)
private static class V1Property {
private String key;
private String value;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "properties")
private static class V1Properties {
@XmlElement(name = "item")
private List<V1Property> properties;
}
@XmlAccessorType(XmlAccessType.FIELD) @XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "user") @XmlRootElement(name = "user")
private static class V1User { private static class V1User {
private Map<String, String> properties; private V1Properties properties;
private boolean admin; private boolean admin;
private long creationDate; private long creationDate;
private String displayName; private String displayName;

View File

@@ -13,9 +13,9 @@ import org.mockito.junit.jupiter.MockitoExtension;
import sonia.scm.SCMContextProvider; import sonia.scm.SCMContextProvider;
import sonia.scm.group.Group; import sonia.scm.group.Group;
import sonia.scm.group.xml.XmlGroupDAO; import sonia.scm.group.xml.XmlGroupDAO;
import sonia.scm.security.AssignedPermission; import sonia.scm.security.DefaultKeyGenerator;
import sonia.scm.store.ConfigurationEntryStore; import sonia.scm.store.ConfigurationEntryStoreFactory;
import sonia.scm.store.InMemoryConfigurationEntryStore; import sonia.scm.store.JAXBConfigurationEntryStoreFactory;
import javax.xml.bind.JAXBException; import javax.xml.bind.JAXBException;
import java.io.IOException; import java.io.IOException;
@@ -26,6 +26,7 @@ import java.util.Optional;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.linesOf;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
@@ -45,13 +46,14 @@ class XmlGroupV1UpdateStepTest {
ArgumentCaptor<Group> groupCaptor; ArgumentCaptor<Group> groupCaptor;
XmlGroupV1UpdateStep updateStep; XmlGroupV1UpdateStep updateStep;
ConfigurationEntryStore<AssignedPermission> assignedPermissionStore;
ConfigurationEntryStoreFactory storeFactory;
@BeforeEach @BeforeEach
void mockScmHome(@TempDirectory.TempDir Path tempDir) { void mockScmHome(@TempDirectory.TempDir Path tempDir) {
when(contextProvider.getBaseDirectory()).thenReturn(tempDir.toFile()); when(contextProvider.getBaseDirectory()).thenReturn(tempDir.toFile());
assignedPermissionStore = new InMemoryConfigurationEntryStore<>(); storeFactory = new JAXBConfigurationEntryStoreFactory(contextProvider, null, new DefaultKeyGenerator());
updateStep = new XmlGroupV1UpdateStep(contextProvider, groupDAO); updateStep = new XmlGroupV1UpdateStep(contextProvider, groupDAO, storeFactory);
} }
@Nested @Nested
@@ -88,6 +90,24 @@ class XmlGroupV1UpdateStepTest {
.hasFieldOrPropertyWithValue("lastModified", 1559550955883L) .hasFieldOrPropertyWithValue("lastModified", 1559550955883L)
.hasFieldOrPropertyWithValue("creationDate", 1559548942457L); .hasFieldOrPropertyWithValue("creationDate", 1559548942457L);
} }
@Test
void shouldExtractProperties(@TempDirectory.TempDir Path tempDir) throws JAXBException {
updateStep.doUpdate();
Path propertiesFile = tempDir.resolve("config").resolve("group-properties-v1.xml");
assertThat(propertiesFile)
.exists();
assertThat(linesOf(propertiesFile.toFile()))
.extracting(String::trim)
.containsSequence(
"<key>normals</key>",
"<value>",
"<item>",
"<key>mostly</key>",
"<value>humans</value>",
"</item>",
"</value>");
}
} }
private void copyTestDatabaseFile(Path configDir, String groupsFileName) throws IOException { private void copyTestDatabaseFile(Path configDir, String groupsFileName) throws IOException {

View File

@@ -12,10 +12,9 @@ import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import sonia.scm.SCMContextProvider; import sonia.scm.SCMContextProvider;
import sonia.scm.security.AssignedPermission; import sonia.scm.security.AssignedPermission;
import sonia.scm.store.ConfigurationEntryStore; import sonia.scm.security.DefaultKeyGenerator;
import sonia.scm.store.ConfigurationEntryStoreFactory; import sonia.scm.store.ConfigurationEntryStoreFactory;
import sonia.scm.store.InMemoryConfigurationEntryStore; import sonia.scm.store.JAXBConfigurationEntryStoreFactory;
import sonia.scm.store.InMemoryConfigurationEntryStoreFactory;
import sonia.scm.user.User; import sonia.scm.user.User;
import sonia.scm.user.xml.XmlUserDAO; import sonia.scm.user.xml.XmlUserDAO;
@@ -27,6 +26,7 @@ import java.nio.file.Path;
import java.util.Optional; import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.linesOf;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
@@ -46,14 +46,14 @@ class XmlUserV1UpdateStepTest {
ArgumentCaptor<User> userCaptor; ArgumentCaptor<User> userCaptor;
XmlUserV1UpdateStep updateStep; XmlUserV1UpdateStep updateStep;
ConfigurationEntryStore<AssignedPermission> assignedPermissionStore;
ConfigurationEntryStoreFactory storeFactory;
@BeforeEach @BeforeEach
void mockScmHome(@TempDirectory.TempDir Path tempDir) { void mockScmHome(@TempDirectory.TempDir Path tempDir) {
when(contextProvider.getBaseDirectory()).thenReturn(tempDir.toFile()); when(contextProvider.getBaseDirectory()).thenReturn(tempDir.toFile());
assignedPermissionStore = new InMemoryConfigurationEntryStore<>(); storeFactory = new JAXBConfigurationEntryStoreFactory(contextProvider, null, new DefaultKeyGenerator());
ConfigurationEntryStoreFactory inMemoryConfigurationEntryStoreFactory = new InMemoryConfigurationEntryStoreFactory(assignedPermissionStore); updateStep = new XmlUserV1UpdateStep(contextProvider, userDAO, storeFactory);
updateStep = new XmlUserV1UpdateStep(contextProvider, userDAO, inMemoryConfigurationEntryStoreFactory);
} }
@Nested @Nested
@@ -74,7 +74,16 @@ class XmlUserV1UpdateStepTest {
@Test @Test
void shouldCreateNewPermissionsForV1AdminUser() throws JAXBException { void shouldCreateNewPermissionsForV1AdminUser() throws JAXBException {
updateStep.doUpdate(); updateStep.doUpdate();
Optional<AssignedPermission> assignedPermission = assignedPermissionStore.getAll().values().stream().filter(a -> a.getName().equals("scmadmin")).findFirst(); Optional<AssignedPermission> assignedPermission =
storeFactory
.withType(AssignedPermission.class)
.withName("security")
.build()
.getAll()
.values()
.stream()
.filter(a -> a.getName().equals("scmadmin"))
.findFirst();
assertThat(assignedPermission.get().getPermission().getValue()).contains("*"); assertThat(assignedPermission.get().getPermission().getValue()).contains("*");
assertThat(assignedPermission.get().isGroupPermission()).isFalse(); assertThat(assignedPermission.get().isGroupPermission()).isFalse();
} }
@@ -100,6 +109,28 @@ class XmlUserV1UpdateStepTest {
.hasFieldOrPropertyWithValue("lastModified", 1558597367492L) .hasFieldOrPropertyWithValue("lastModified", 1558597367492L)
.hasFieldOrPropertyWithValue("creationDate", 1558597074732L); .hasFieldOrPropertyWithValue("creationDate", 1558597074732L);
} }
@Test
void shouldExtractProperties(@TempDirectory.TempDir Path tempDir) throws JAXBException {
updateStep.doUpdate();
Path propertiesFile = tempDir.resolve("config").resolve("user-properties-v1.xml");
assertThat(propertiesFile)
.exists();
assertThat(linesOf(propertiesFile.toFile()))
.extracting(String::trim)
.containsSequence(
"<key>dent</key>",
"<value>",
"<item>",
"<key>born.on</key>",
"<value>earth</value>",
"</item>",
"<item>",
"<key>last.seen</key>",
"<value>end of the universe</value>",
"</item>",
"</value>");
}
} }
private void copyTestDatabaseFile(Path configDir, String usersFileName) throws IOException { private void copyTestDatabaseFile(Path configDir, String usersFileName) throws IOException {

View File

@@ -11,7 +11,12 @@
<type>xml</type> <type>xml</type>
</group> </group>
<group> <group>
<properties/> <properties>
<item>
<key>mostly</key>
<value>humans</value>
</item>
</properties>
<creationDate>1559548942457</creationDate> <creationDate>1559548942457</creationDate>
<description>Normal people</description> <description>Normal people</description>
<name>normals</name> <name>normals</name>

View File

@@ -24,7 +24,16 @@
<type>xml</type> <type>xml</type>
</user> </user>
<user> <user>
<properties/> <properties>
<item>
<key>born.on</key>
<value>earth</value>
</item>
<item>
<key>last.seen</key>
<value>end of the universe</value>
</item>
</properties>
<admin>false</admin> <admin>false</admin>
<creationDate>1558597107621</creationDate> <creationDate>1558597107621</creationDate>
<displayName>Arthur Dent</displayName> <displayName>Arthur Dent</displayName>