From b488f178ab372f49f35a7aaec5fb0bc716160b4f Mon Sep 17 00:00:00 2001 From: Duarte Meneses Date: Mon, 16 Oct 2017 10:03:38 +0200 Subject: [PATCH] SONAR-9939 Parse base64 license --- .../org/sonar/server/edition/License.java | 48 ++++++++++++++++--- .../org/sonar/server/edition/LicenseTest.java | 44 ++++++++++++++++- 2 files changed, 84 insertions(+), 8 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/License.java b/server/sonar-server/src/main/java/org/sonar/server/edition/License.java index f430d26a165..fbfdaef18a9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/License.java +++ b/server/sonar-server/src/main/java/org/sonar/server/edition/License.java @@ -19,22 +19,36 @@ */ package org.sonar.server.edition; -import com.google.common.collect.ImmutableList; -import java.util.List; +import com.google.common.collect.ImmutableSet; +import java.io.StringReader; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Collection; +import java.util.Optional; +import java.util.Properties; +import java.util.Set; import javax.annotation.concurrent.Immutable; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; @Immutable public class License { + private static final Logger LOG = Loggers.get(License.class); + private static final String EDITION_KEY = "Edition"; + private static final String PLUGINS_KEY = "Plugins"; + private final String editionKey; - private final List pluginKeys; + private final Set pluginKeys; private final String content; - public License(String editionKey, List pluginKeys, String content) { + public License(String editionKey, Collection pluginKeys, String content) { this.editionKey = enforceNotNullNorEmpty(editionKey, "editionKey"); - this.pluginKeys = ImmutableList.copyOf(pluginKeys); + this.pluginKeys = ImmutableSet.copyOf(pluginKeys); this.content = enforceNotNullNorEmpty(content, "content"); } @@ -48,11 +62,33 @@ public class License { return editionKey; } - public List getPluginKeys() { + public Set getPluginKeys() { return pluginKeys; } public String getContent() { return content; } + + public static Optional parse(String base64) { + try { + String data = new String(Base64.decodeBase64(base64.trim().getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8); + + Properties props = new Properties(); + props.load(new StringReader(data)); + + Collection plugins = Arrays.asList(StringUtils.split(props.getProperty(PLUGINS_KEY), ',')); + String editionKey = props.getProperty(EDITION_KEY); + + if (editionKey != null && !plugins.isEmpty()) { + return Optional.of(new License(editionKey, plugins, base64)); + } else { + LOG.debug("Failed to parse license: no edition key and/or no plugin found"); + } + } catch (Exception e) { + LOG.debug("Failed to parse license", e); + } + return Optional.empty(); + + } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/edition/LicenseTest.java b/server/sonar-server/src/test/java/org/sonar/server/edition/LicenseTest.java index 51c0e2762a3..d894b5975e5 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/edition/LicenseTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/edition/LicenseTest.java @@ -19,8 +19,13 @@ */ package org.sonar.server.edition; -import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import java.io.IOException; +import java.io.StringWriter; +import java.util.Base64; import java.util.Collections; +import java.util.Optional; +import java.util.Properties; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -70,9 +75,44 @@ public class LicenseTest { new License("edition-key", Collections.emptyList(), ""); } + @Test + public void parse_returns_empty_if_license_is_invalid_string() { + assertThat(License.parse("trash")).isEmpty(); + } + + @Test + public void parse_succeeds() throws IOException { + Properties props = new Properties(); + props.setProperty("Plugins", "plugin1,plugin2"); + props.setProperty("Edition", "dev"); + StringWriter writer = new StringWriter(); + props.store(writer, ""); + + byte[] encoded = Base64.getEncoder().encode(writer.toString().getBytes()); + + Optional license = License.parse(new String(encoded)); + assertThat(license).isPresent(); + assertThat(license.get().getEditionKey()).isEqualTo("dev"); + assertThat(license.get().getPluginKeys()).containsOnly("plugin1", "plugin2"); + } + + @Test + public void parse_is_empty_if_no_plugin() throws IOException { + Properties props = new Properties(); + props.setProperty("Plugins", ""); + props.setProperty("Edition", "dev"); + StringWriter writer = new StringWriter(); + props.store(writer, ""); + + byte[] encoded = Base64.getEncoder().encode(writer.toString().getBytes()); + + Optional license = License.parse(new String(encoded)); + assertThat(license).isEmpty(); + } + @Test public void verify_getters() { - ImmutableList pluginKeys = ImmutableList.of("a", "b", "c"); + ImmutableSet pluginKeys = ImmutableSet.of("a", "b", "c"); License underTest = new License("edition-key", pluginKeys, "content"); -- 2.39.5