feat(security): prevent dev mode activation on production flavor builds
This commit is contained in:
@@ -108,6 +108,23 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
<includes>
|
||||
<include>build-info.properties</include>
|
||||
</includes>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>false</filtering>
|
||||
<excludes>
|
||||
<exclude>build-info.properties</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.openjfx</groupId>
|
||||
@@ -138,6 +155,7 @@
|
||||
<Implementation-Title>CyberCore Signer</Implementation-Title>
|
||||
<Implementation-Version>${project.version}</Implementation-Version>
|
||||
<Implementation-Vendor>CyberCore</Implementation-Vendor>
|
||||
<Build-Flavor>${cybercore.build.flavor}</Build-Flavor>
|
||||
</manifestEntries>
|
||||
</transformer>
|
||||
</transformers>
|
||||
|
||||
+31
@@ -19,12 +19,39 @@ public class CyberCoreSignerApplication {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(CyberCoreSignerApplication.class);
|
||||
|
||||
private static final String BUILD_INFO_RESOURCE = "/build-info.properties";
|
||||
private static String buildFlavor = "production";
|
||||
private static boolean developmentMode = false;
|
||||
private static boolean headlessMode = false;
|
||||
private static boolean noWaitMode = false;
|
||||
private static int configuredPort = CcspServer.DEFAULT_PORT;
|
||||
private static volatile CcspServer runningServer = null;
|
||||
|
||||
static {
|
||||
loadBuildInfo();
|
||||
}
|
||||
|
||||
private static void loadBuildInfo() {
|
||||
try (var is = CyberCoreSignerApplication.class.getResourceAsStream(BUILD_INFO_RESOURCE)) {
|
||||
if (is != null) {
|
||||
var props = new java.util.Properties();
|
||||
props.load(is);
|
||||
String flavor = props.getProperty("build.flavor");
|
||||
if (flavor != null && !flavor.isBlank()) {
|
||||
buildFlavor = flavor.trim().toLowerCase();
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
public static String getBuildFlavor() {
|
||||
return buildFlavor;
|
||||
}
|
||||
|
||||
public static void setBuildFlavorForTesting(String flavor) {
|
||||
buildFlavor = flavor;
|
||||
}
|
||||
|
||||
public static CcspServer getRunningServer() {
|
||||
return runningServer;
|
||||
}
|
||||
@@ -147,6 +174,10 @@ public class CyberCoreSignerApplication {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
String arg = args[i];
|
||||
if ("--dev".equalsIgnoreCase(arg) || "-dev".equalsIgnoreCase(arg)) {
|
||||
if ("production".equalsIgnoreCase(buildFlavor)) {
|
||||
logger.error("ALERTA DE SEGURANÇA: Modo de desenvolvimento (--dev) não é permitido em compilações de produção (flavor: production).");
|
||||
throw new SecurityException("Modo de desenvolvimento (--dev) bloqueado em compilações de produção.");
|
||||
}
|
||||
developmentMode = true;
|
||||
} else if ("--headless".equalsIgnoreCase(arg) || "-headless".equalsIgnoreCase(arg)
|
||||
|| "--cli".equalsIgnoreCase(arg)) {
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
build.version=${project.version}
|
||||
build.flavor=${cybercore.build.flavor}
|
||||
+22
-2
@@ -8,16 +8,36 @@ import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
class CyberCoreSignerApplicationTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Deve inicializar a aplicação com argumentos sem erros")
|
||||
@DisplayName("Deve inicializar a aplicação com argumentos sem erros em compilação normal")
|
||||
void shouldBootstrapWithoutErrors() {
|
||||
try {
|
||||
assertThatCode(() -> CyberCoreSignerApplication.main(new String[]{"--dev", "--headless", "--no-wait", "--port", "29999"}))
|
||||
assertThatCode(() -> CyberCoreSignerApplication.main(new String[]{"--headless", "--no-wait", "--port", "29999"}))
|
||||
.doesNotThrowAnyException();
|
||||
} finally {
|
||||
CyberCoreSignerApplication.stopServer();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Deve bloquear o modo dev em compilações de produção")
|
||||
void shouldBlockDevModeInProductionFlavor() {
|
||||
CyberCoreSignerApplication.setBuildFlavorForTesting("production");
|
||||
org.assertj.core.api.Assertions.assertThatThrownBy(() ->
|
||||
CyberCoreSignerApplication.parseArguments(new String[]{"--dev"})
|
||||
).isInstanceOf(SecurityException.class)
|
||||
.hasMessageContaining("bloqueado em compilações de produção");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Deve permitir o modo dev quando o flavor for development")
|
||||
void shouldAllowDevModeInDevelopmentFlavor() {
|
||||
CyberCoreSignerApplication.setBuildFlavorForTesting("development");
|
||||
org.assertj.core.api.Assertions.assertThatCode(() ->
|
||||
CyberCoreSignerApplication.parseArguments(new String[]{"--dev"})
|
||||
).doesNotThrowAnyException();
|
||||
org.assertj.core.api.Assertions.assertThat(CyberCoreSignerApplication.isDevelopmentMode()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Deve realizar o parse correto do argumento --port")
|
||||
void shouldParsePortArgument() {
|
||||
|
||||
Reference in New Issue
Block a user