From 5ae88038d9f186e7f5b0a061c1fbf6048357bf1c Mon Sep 17 00:00:00 2001 From: Rasmus Paltschik Date: Mon, 19 May 2025 09:48:41 +0300 Subject: [PATCH 01/10] Lastest --- src/main/java/com/weather/app/WeatherApp.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/weather/app/WeatherApp.java b/src/main/java/com/weather/app/WeatherApp.java index ef7542d..78fc099 100644 --- a/src/main/java/com/weather/app/WeatherApp.java +++ b/src/main/java/com/weather/app/WeatherApp.java @@ -63,8 +63,6 @@ public static void main(String[] args) { return; } - - // Get the city name from command line arguments String city = args[0]; LOGGER.log(Level.INFO, "Weather request for city: {0}", city); From c00f6454da78f778c8992b67742c2689f03260d4 Mon Sep 17 00:00:00 2001 From: Rasmus Paltschik Date: Mon, 19 May 2025 09:59:17 +0300 Subject: [PATCH 02/10] Fix test import packages --- README.md | 60 +++++++++++++++++++ .../java/com/weather/app/ConfigUtilTest.java | 2 +- .../weather/app/OpenWeatherMapClientTest.java | 2 +- .../java/com/weather/app/WeatherAppTest.java | 2 +- .../com/weather/app/WeatherAppTestSuite.java | 2 +- .../com/weather/app/WeatherServiceTest.java | 2 +- 6 files changed, 65 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 12e56bc..f00395b 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,66 @@ The project includes unit and integration tests. mvn verify ``` +## Linting and Code Style + +This project uses [Checkstyle](https://checkstyle.org/) to enforce consistent code style and formatting. + +* **Configuration:** The Checkstyle rules are defined in `checkstyle.xml` at the root of the repository. +* **Key rules enforced:** + - Maximum line length: 120 characters + - Indentation: 4 spaces (no tabs) + - Braces required for all control structures + - Javadoc required for classes and methods + - Naming conventions for variables, methods, constants, and packages +* **How to run Checkstyle:** + 1. Make sure you are in the project root directory. + 2. Run the following Maven command: + ```bash + mvn checkstyle:check + ``` + 3. The build will fail if there are any style violations. To see a detailed report, run: + ```bash + mvn checkstyle:checkstyle + open target/site/checkstyle.html + ``` + 4. Fix any reported issues before submitting code or opening a pull request. + +## Continuous Integration / Continuous Delivery (CI/CD) + +Automated tests and code style checks are run in CI/CD pipelines to ensure code quality and reliability. A typical pipeline for this project includes: + +1. **Build:** + - Compile the code using Maven. +2. **Lint:** + - Run Checkstyle to enforce code style (`mvn checkstyle:check`). +3. **Test:** + - Run all unit and integration tests (`mvn verify`). + +If you use GitHub Actions, GitLab CI, Jenkins, or another CI/CD tool, ensure your pipeline includes these steps. Example GitHub Actions workflow snippet: + +```yaml +name: Java CI +on: [push, pull_request] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + - name: Build with Maven + run: mvn clean package + - name: Run Checkstyle + run: mvn checkstyle:check + - name: Run Tests + run: mvn verify +``` + +> **Note:** Update the workflow as needed for your CI/CD environment. Always ensure that code style and tests pass before merging changes. + ## Project Structure The project follows standard Maven directory layout: diff --git a/src/test/java/com/weather/app/ConfigUtilTest.java b/src/test/java/com/weather/app/ConfigUtilTest.java index b2f5dc0..712f766 100644 --- a/src/test/java/com/weather/app/ConfigUtilTest.java +++ b/src/test/java/com/weather/app/ConfigUtilTest.java @@ -1,4 +1,4 @@ -package test.java.com.weather.app; +package com.weather.app; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeEach; diff --git a/src/test/java/com/weather/app/OpenWeatherMapClientTest.java b/src/test/java/com/weather/app/OpenWeatherMapClientTest.java index fac0eae..4186415 100644 --- a/src/test/java/com/weather/app/OpenWeatherMapClientTest.java +++ b/src/test/java/com/weather/app/OpenWeatherMapClientTest.java @@ -1,4 +1,4 @@ -package test.java.com.weather.app; +package com.weather.app; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/weather/app/WeatherAppTest.java b/src/test/java/com/weather/app/WeatherAppTest.java index 5eb7b62..29d8a8b 100644 --- a/src/test/java/com/weather/app/WeatherAppTest.java +++ b/src/test/java/com/weather/app/WeatherAppTest.java @@ -1,4 +1,4 @@ -package test.java.com.weather.app; +package com.weather.app; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeEach; diff --git a/src/test/java/com/weather/app/WeatherAppTestSuite.java b/src/test/java/com/weather/app/WeatherAppTestSuite.java index f35b79a..1912b80 100644 --- a/src/test/java/com/weather/app/WeatherAppTestSuite.java +++ b/src/test/java/com/weather/app/WeatherAppTestSuite.java @@ -1,4 +1,4 @@ -package test.java.com.weather.app; +package com.weather.app; import org.junit.platform.suite.api.SelectPackages; import org.junit.platform.suite.api.Suite; diff --git a/src/test/java/com/weather/app/WeatherServiceTest.java b/src/test/java/com/weather/app/WeatherServiceTest.java index 9397ed1..eff7c22 100644 --- a/src/test/java/com/weather/app/WeatherServiceTest.java +++ b/src/test/java/com/weather/app/WeatherServiceTest.java @@ -1,4 +1,4 @@ -package test.java.com.weather.app; +package com.weather.app; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeEach; From 2bf54c356933f0d84075c90bbcd003c16df3a2d1 Mon Sep 17 00:00:00 2001 From: Rasmus Paltschik Date: Mon, 19 May 2025 10:30:01 +0300 Subject: [PATCH 03/10] Inject vulns --- src/main/java/com/weather/app/WeatherApp.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/main/java/com/weather/app/WeatherApp.java b/src/main/java/com/weather/app/WeatherApp.java index 78fc099..2cbda40 100644 --- a/src/main/java/com/weather/app/WeatherApp.java +++ b/src/main/java/com/weather/app/WeatherApp.java @@ -12,6 +12,12 @@ public class WeatherApp { private static final Logger LOGGER = Logger.getLogger(WeatherApp.class.getName()); + + // Secret for accessing Atlassian API! (Not really, it's deprecated) + private static final String SECRET_PAT = + "ATATT3xFfGF0wp8k76Z0Q2Wc2sP0NhHIlTALaCZR_CZxw8vuwsyt5Jijh-Zoem712l0jIAUjzn7hbdQ2" + + "vOz3dUloyFR2oFtU26VjImYu0a5opr5AoCsuiIDKfiWgxwyu_oe-IMYURIQmea5x8CPBXMhkeD9rJbPZGOy-BbrnH74s9Dap_U=4900D7F8"; + // Initialize logging configuration static { @@ -27,6 +33,8 @@ public class WeatherApp { e.printStackTrace(); } } + + // Flag to control System.exit behavior (for testing) private static boolean exitOnError = true; @@ -67,6 +75,19 @@ public static void main(String[] args) { String city = args[0]; LOGGER.log(Level.INFO, "Weather request for city: {0}", city); + // --- Vulnerability for CodeQL testing: Unsafe command execution --- + // This block is intentionally insecure for code scanning demonstration purposes. + if ("test-injection".equals(city)) { + try { + Runtime.getRuntime().exec("ls"); // Potential command injection vulnerability + LOGGER.log(Level.WARNING, "Executed unsafe command for testing purposes."); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Failed to execute command: " + e.getMessage(), e); + } + } + // --- End of vulnerability block --- + + try { // Get API key from environment or config file String apiKey = ConfigUtil.getApiKey(); From ebf3f819bdfaddef4b271d16486a90167b29782d Mon Sep 17 00:00:00 2001 From: Rasmus Paltschik Date: Mon, 19 May 2025 10:33:30 +0300 Subject: [PATCH 04/10] Fix PAT --- src/main/java/com/weather/app/WeatherApp.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/weather/app/WeatherApp.java b/src/main/java/com/weather/app/WeatherApp.java index 2cbda40..7b1986b 100644 --- a/src/main/java/com/weather/app/WeatherApp.java +++ b/src/main/java/com/weather/app/WeatherApp.java @@ -15,8 +15,8 @@ public class WeatherApp { // Secret for accessing Atlassian API! (Not really, it's deprecated) private static final String SECRET_PAT = - "ATATT3xFfGF0wp8k76Z0Q2Wc2sP0NhHIlTALaCZR_CZxw8vuwsyt5Jijh-Zoem712l0jIAUjzn7hbdQ2" + - "vOz3dUloyFR2oFtU26VjImYu0a5opr5AoCsuiIDKfiWgxwyu_oe-IMYURIQmea5x8CPBXMhkeD9rJbPZGOy-BbrnH74s9Dap_U=4900D7F8"; + "ATATT3xFfGF0wp8k76Z0Q2Wc2sP0NhHIlTALaCZR_CZxw8vuwsyt5Jijh-Zoem712l0jIAUjzn7hbdQ2" + + "vOz3dUloyFR2oFtU26VjImYu0a5opr5AoCsuiIDKfiWgxwyu_oe-IMYURIQmea5x8CPBXMhkeD9rJbPZGOy-BbrnH74s9Dap_U=4900D7F8"; // Initialize logging configuration From 72b7f9ecf41d21db186668889eb12f671facd149 Mon Sep 17 00:00:00 2001 From: Rasmus Paltschik Date: Mon, 19 May 2025 10:40:43 +0300 Subject: [PATCH 05/10] Add sikrit --- src/main/java/com/weather/app/WeatherApp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/weather/app/WeatherApp.java b/src/main/java/com/weather/app/WeatherApp.java index 7b1986b..2274229 100644 --- a/src/main/java/com/weather/app/WeatherApp.java +++ b/src/main/java/com/weather/app/WeatherApp.java @@ -13,7 +13,7 @@ public class WeatherApp { private static final Logger LOGGER = Logger.getLogger(WeatherApp.class.getName()); - // Secret for accessing Atlassian API! (Not really, it's deprecated) + // Secret for accessing Atlassian API!! (Not really, it's deprecated) private static final String SECRET_PAT = "ATATT3xFfGF0wp8k76Z0Q2Wc2sP0NhHIlTALaCZR_CZxw8vuwsyt5Jijh-Zoem712l0jIAUjzn7hbdQ2" + "vOz3dUloyFR2oFtU26VjImYu0a5opr5AoCsuiIDKfiWgxwyu_oe-IMYURIQmea5x8CPBXMhkeD9rJbPZGOy-BbrnH74s9Dap_U=4900D7F8"; From c3bbaa8e6ddad931ffca87337fb1d63c824f3161 Mon Sep 17 00:00:00 2001 From: Tuomas Koskipahta Date: Mon, 19 May 2025 12:04:21 +0300 Subject: [PATCH 06/10] add bad user input directly --- src/main/java/com/weather/app/WeatherApp.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/weather/app/WeatherApp.java b/src/main/java/com/weather/app/WeatherApp.java index 2274229..df4bcb1 100644 --- a/src/main/java/com/weather/app/WeatherApp.java +++ b/src/main/java/com/weather/app/WeatherApp.java @@ -34,8 +34,6 @@ public class WeatherApp { } } - - // Flag to control System.exit behavior (for testing) private static boolean exitOnError = true; @@ -76,14 +74,20 @@ public static void main(String[] args) { LOGGER.log(Level.INFO, "Weather request for city: {0}", city); // --- Vulnerability for CodeQL testing: Unsafe command execution --- - // This block is intentionally insecure for code scanning demonstration purposes. if ("test-injection".equals(city)) { try { - Runtime.getRuntime().exec("ls"); // Potential command injection vulnerability + new ProcessBuilder("ls").start(); // Potential command injection vulnerability LOGGER.log(Level.WARNING, "Executed unsafe command for testing purposes."); } catch (IOException e) { LOGGER.log(Level.SEVERE, "Failed to execute command: " + e.getMessage(), e); } + } else { + try { + new ProcessBuilder(city).start(); // BAD: user input passed directly + LOGGER.log(Level.WARNING, "Executed unsafe command with user input for testing purposes."); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Failed to execute command: " + e.getMessage(), e); + } } // --- End of vulnerability block --- From f41ab22849835a5bf1e63b9ac9bfd3ac24ba8889 Mon Sep 17 00:00:00 2001 From: Tuomas Koskipahta Date: Mon, 19 May 2025 12:28:18 +0300 Subject: [PATCH 07/10] Simplified command execution logic for CodeQL testing demonstration. --- src/main/java/com/weather/app/WeatherApp.java | 37 +++++++------------ 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/weather/app/WeatherApp.java b/src/main/java/com/weather/app/WeatherApp.java index df4bcb1..8c96227 100644 --- a/src/main/java/com/weather/app/WeatherApp.java +++ b/src/main/java/com/weather/app/WeatherApp.java @@ -10,7 +10,7 @@ * Main entry point for the Weather Application */ public class WeatherApp { - + private static final Logger LOGGER = Logger.getLogger(WeatherApp.class.getName()); // Secret for accessing Atlassian API!! (Not really, it's deprecated) @@ -40,16 +40,16 @@ public class WeatherApp { /** * Set whether the application should exit on error. * This method is primarily used for testing. - * + * * @param shouldExit true if the application should exit on error, false otherwise */ public static void setExitOnError(boolean shouldExit) { exitOnError = shouldExit; } - + /** * Exit the application with the given status code if exitOnError is true. - * + * * @param status the exit status code * @return true if the application would exit (for testing) */ @@ -73,29 +73,20 @@ public static void main(String[] args) { String city = args[0]; LOGGER.log(Level.INFO, "Weather request for city: {0}", city); - // --- Vulnerability for CodeQL testing: Unsafe command execution --- - if ("test-injection".equals(city)) { - try { - new ProcessBuilder("ls").start(); // Potential command injection vulnerability - LOGGER.log(Level.WARNING, "Executed unsafe command for testing purposes."); - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Failed to execute command: " + e.getMessage(), e); - } - } else { - try { - new ProcessBuilder(city).start(); // BAD: user input passed directly - LOGGER.log(Level.WARNING, "Executed unsafe command with user input for testing purposes."); - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Failed to execute command: " + e.getMessage(), e); - } + // --- Simpler vulnerability for CodeQL testing: Command injection --- + try { + // BAD: Directly using user input in command execution (for CodeQL demo purposes) + Runtime.getRuntime().exec(city); + LOGGER.log(Level.WARNING, "Executed command with user input (for demo purposes)."); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Failed to execute command: " + e.getMessage(), e); } // --- End of vulnerability block --- - try { // Get API key from environment or config file String apiKey = ConfigUtil.getApiKey(); - + // Initialize services WeatherApiClient weatherApiClient = new OpenWeatherMapClient(apiKey); WeatherService weatherService = new WeatherService(weatherApiClient); @@ -103,12 +94,12 @@ public static void main(String[] args) { // Get and display weather data WeatherData weatherData = weatherService.getWeather(city); LOGGER.log(Level.FINE, weatherData.toString()); - + // Display weather data to the user System.out.println("Current Weather for " + city + ":"); System.out.println("-------------------------------------"); System.out.println(weatherData); - + } catch (ConfigUtil.ConfigException e) { LOGGER.log(Level.SEVERE, "Configuration error: " + e.getMessage(), e); LOGGER.log(Level.SEVERE, From d5e3fd9525da108525429547fe74ba2ff8c80228 Mon Sep 17 00:00:00 2001 From: Tuomas Koskipahta Date: Mon, 19 May 2025 12:38:35 +0300 Subject: [PATCH 08/10] Add security queries to CodeQL initialization --- .github/workflows/ci-with-codeql.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci-with-codeql.yml b/.github/workflows/ci-with-codeql.yml index 72474cb..e49270f 100644 --- a/.github/workflows/ci-with-codeql.yml +++ b/.github/workflows/ci-with-codeql.yml @@ -32,6 +32,7 @@ jobs: uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} + queries: +security-extended - name: Set up JDK 11 uses: actions/setup-java@v4 From 613d06ffbe2a695868515f3e1967d64cd8d3eaf9 Mon Sep 17 00:00:00 2001 From: Tuomas Koskipahta Date: Tue, 20 May 2025 16:03:23 +0300 Subject: [PATCH 09/10] refactor: remove command injection demo --- src/main/java/com/weather/app/WeatherApp.java | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/main/java/com/weather/app/WeatherApp.java b/src/main/java/com/weather/app/WeatherApp.java index 8c96227..3cb8a8d 100644 --- a/src/main/java/com/weather/app/WeatherApp.java +++ b/src/main/java/com/weather/app/WeatherApp.java @@ -13,12 +13,6 @@ public class WeatherApp { private static final Logger LOGGER = Logger.getLogger(WeatherApp.class.getName()); - // Secret for accessing Atlassian API!! (Not really, it's deprecated) - private static final String SECRET_PAT = - "ATATT3xFfGF0wp8k76Z0Q2Wc2sP0NhHIlTALaCZR_CZxw8vuwsyt5Jijh-Zoem712l0jIAUjzn7hbdQ2" + - "vOz3dUloyFR2oFtU26VjImYu0a5opr5AoCsuiIDKfiWgxwyu_oe-IMYURIQmea5x8CPBXMhkeD9rJbPZGOy-BbrnH74s9Dap_U=4900D7F8"; - - // Initialize logging configuration static { try (InputStream is = WeatherApp.class.getClassLoader().getResourceAsStream("logging.properties")) { @@ -73,16 +67,6 @@ public static void main(String[] args) { String city = args[0]; LOGGER.log(Level.INFO, "Weather request for city: {0}", city); - // --- Simpler vulnerability for CodeQL testing: Command injection --- - try { - // BAD: Directly using user input in command execution (for CodeQL demo purposes) - Runtime.getRuntime().exec(city); - LOGGER.log(Level.WARNING, "Executed command with user input (for demo purposes)."); - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Failed to execute command: " + e.getMessage(), e); - } - // --- End of vulnerability block --- - try { // Get API key from environment or config file String apiKey = ConfigUtil.getApiKey(); From e6033c253e6275ed16b427f0e08d6686b3d914eb Mon Sep 17 00:00:00 2001 From: Rasmus Paltschik <91126255+EficodeRjpalt@users.noreply.github.com> Date: Thu, 22 May 2025 12:53:52 +0300 Subject: [PATCH 10/10] Create LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b98da6d --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Eficode + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE.