fix migration with unknown permissions

This commit is contained in:
Sebastian Sdorra
2019-07-18 12:17:20 +02:00
parent 0840109d56
commit a4cb2f7caa
3 changed files with 75 additions and 43 deletions

View File

@@ -23,6 +23,8 @@ import java.nio.file.Path;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static java.util.Optional.ofNullable; import static java.util.Optional.ofNullable;
import static sonia.scm.version.Version.parse; import static sonia.scm.version.Version.parse;
@@ -30,6 +32,8 @@ import static sonia.scm.version.Version.parse;
@Extension @Extension
public class XmlSecurityV1UpdateStep implements UpdateStep { public class XmlSecurityV1UpdateStep implements UpdateStep {
private static final Pattern v1PermissionPattern = Pattern.compile("^repository:\\*:(READ|WRITE|OWNER)$");
private static final Logger LOG = LoggerFactory.getLogger(XmlSecurityV1UpdateStep.class); private static final Logger LOG = LoggerFactory.getLogger(XmlSecurityV1UpdateStep.class);
private final SCMContextProvider contextProvider; private final SCMContextProvider contextProvider;
@@ -63,30 +67,36 @@ public class XmlSecurityV1UpdateStep implements UpdateStep {
V1Security v1Security = (V1Security) jaxbContext.createUnmarshaller().unmarshal(v1SecurityFile.toFile()); V1Security v1Security = (V1Security) jaxbContext.createUnmarshaller().unmarshal(v1SecurityFile.toFile());
v1Security.entries.forEach(assignedPermission -> { v1Security.entries.forEach(assignedPermission -> {
Matcher matcher = v1PermissionPattern.matcher(assignedPermission.value.permission);
String newPermission = ""; if (matcher.matches()) {
if (assignedPermission.value.permission != null && !assignedPermission.value.permission.isEmpty()) { String newPermission = convertRole(matcher.group(1));
String[] splitPermission = assignedPermission.value.permission.split(":"); securityStore.put(new AssignedPermission(
switch(splitPermission[2]) { assignedPermission.value.name,
case "OWNER": Boolean.parseBoolean(assignedPermission.value.groupPermission),
newPermission = "repository:*"; newPermission
break; ));
case "WRITE":
newPermission = "repository:read,pull,push:*";
break;
case "READ":
newPermission = "repository:read,pull:*";
}
} }
securityStore.put(new AssignedPermission(
assignedPermission.value.name,
Boolean.parseBoolean(assignedPermission.value.groupPermission),
newPermission
));
}); });
} }
private String convertRole(String role) {
String newPermission;
switch (role) {
case "OWNER":
newPermission = "repository:*";
break;
case "WRITE":
newPermission = "repository:read,pull,push:*";
break;
case "READ":
newPermission = "repository:read,pull:*";
break;
default:
newPermission = "";
}
return newPermission;
}
private void forAllAdmins(Consumer<String> userConsumer, Consumer<String> groupConsumer) throws JAXBException { private void forAllAdmins(Consumer<String> userConsumer, Consumer<String> groupConsumer) throws JAXBException {
Path configDirectory = determineConfigDirectory(); Path configDirectory = determineConfigDirectory();
Path existingConfigFile = configDirectory.resolve("config" + StoreConstants.FILE_EXTENSION); Path existingConfigFile = configDirectory.resolve("config" + StoreConstants.FILE_EXTENSION);

View File

@@ -56,13 +56,6 @@ class XmlSecurityV1UpdateStepTest {
copyTestDatabaseFile(configDir, "config.xml"); copyTestDatabaseFile(configDir, "config.xml");
} }
@BeforeEach
void createSecurityV1XML(@TempDirectory.TempDir Path tempDir) throws IOException {
Path configDir = tempDir.resolve("config");
Files.createDirectories(configDir);
copyTestDatabaseFile(configDir, "securityV1.xml");
}
@Test @Test
void shouldCreatePermissionForUsersConfiguredAsAdmin() throws JAXBException { void shouldCreatePermissionForUsersConfiguredAsAdmin() throws JAXBException {
updateStep.doUpdate(); updateStep.doUpdate();
@@ -89,6 +82,18 @@ class XmlSecurityV1UpdateStepTest {
assertThat(assignedPermission).contains("admins", "vogons"); assertThat(assignedPermission).contains("admins", "vogons");
} }
}
@Nested
class WithExistingSecurityXml {
@BeforeEach
void createSecurityV1XML(@TempDirectory.TempDir Path tempDir) throws IOException {
Path configDir = tempDir.resolve("config");
Files.createDirectories(configDir);
copyTestDatabaseFile(configDir, "securityV1.xml");
}
@Test @Test
void shouldMapV1PermissionsFromSecurityV1XML() throws JAXBException { void shouldMapV1PermissionsFromSecurityV1XML() throws JAXBException {
updateStep.doUpdate(); updateStep.doUpdate();
@@ -101,6 +106,7 @@ class XmlSecurityV1UpdateStepTest {
assertThat(assignedPermission).contains("scmadmin"); assertThat(assignedPermission).contains("scmadmin");
assertThat(assignedPermission).contains("test"); assertThat(assignedPermission).contains("test");
} }
} }
private void copyTestDatabaseFile(Path configDir, String fileName) throws IOException { private void copyTestDatabaseFile(Path configDir, String fileName) throws IOException {

View File

@@ -1,19 +1,35 @@
<?xml version="1.0" ?> <?xml version="1.0" ?>
<configuration> <configuration>
<entry> <entry>
<key>4lRWOA7DH1</key> <key>4lRWOA7DH1</key>
<value> <value>
<group-permission>false</group-permission> <group-permission>false</group-permission>
<name>scmadmin</name> <name>scmadmin</name>
<permission>repository:*:READ</permission> <permission>repository:*:READ</permission>
</value> </value>
</entry> </entry>
<entry> <entry>
<key>CfRWOAANM2</key> <key>CfRWOAANM2</key>
<value> <value>
<group-permission>true</group-permission> <group-permission>true</group-permission>
<name>test</name> <name>test</name>
<permission>repository:*:OWNER</permission> <permission>repository:*:OWNER</permission>
</value> </value>
</entry> </entry>
<entry>
<key>CfRWOAANM2</key>
<value>
<group-permission>true</group-permission>
<name>test</name>
<permission>invalid:permission</permission>
</value>
</entry>
<entry>
<key>CfRWOAANM2</key>
<value>
<group-permission>true</group-permission>
<name>test</name>
<permission>repository:*:STRANGE</permission>
</value>
</entry>
</configuration> </configuration>