├── .github └── workflows │ ├── ci.yaml │ └── publish-packages.yaml ├── .gitignore ├── .mvn └── wrapper │ ├── MavenWrapperDownloader.java │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── backend ├── .gitignore ├── README.md ├── docker │ └── Dockerfile ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── wirehall │ │ │ └── commandhunt │ │ │ └── backend │ │ │ ├── CommandHuntApplication.java │ │ │ ├── controller │ │ │ ├── AuthController.java │ │ │ ├── MetaCommandController.java │ │ │ ├── PublicCommandController.java │ │ │ └── UserCommandController.java │ │ │ ├── dto │ │ │ ├── BaseCommand.java │ │ │ ├── ErrorResponse.java │ │ │ ├── Flag.java │ │ │ ├── MetaCommand.java │ │ │ ├── Node.java │ │ │ ├── Option.java │ │ │ ├── PublicCommand.java │ │ │ ├── User.java │ │ │ ├── UserCommand.java │ │ │ ├── auth │ │ │ │ ├── Login.java │ │ │ │ └── SignUp.java │ │ │ └── filter │ │ │ │ ├── Condition.java │ │ │ │ ├── Filter.java │ │ │ │ ├── PageResponse.java │ │ │ │ └── Pagination.java │ │ │ ├── exception │ │ │ ├── BadRequestException.java │ │ │ ├── GlobalExceptionHandler.java │ │ │ └── OAuthException.java │ │ │ ├── graph │ │ │ ├── DatabaseSeed.java │ │ │ ├── GraphConfiguration.java │ │ │ ├── GraphIO.java │ │ │ ├── MetadataManager.java │ │ │ └── SchemaBuilder.java │ │ │ ├── mapper │ │ │ ├── MetaCommandMapper.java │ │ │ ├── PaginationMapper.java │ │ │ ├── PublicCommandMapper.java │ │ │ ├── UserCommandMapper.java │ │ │ └── UserMapper.java │ │ │ ├── model │ │ │ ├── PublicCommandEntity.java │ │ │ ├── UserCommandEntity.java │ │ │ ├── UserEntity.java │ │ │ ├── auth │ │ │ │ └── CustomUserPrincipal.java │ │ │ └── graph │ │ │ │ ├── DataType.java │ │ │ │ ├── EdgeType.java │ │ │ │ ├── VertexType.java │ │ │ │ └── props │ │ │ │ ├── FlagProperty.java │ │ │ │ ├── MetaCommandProperty.java │ │ │ │ └── OptionProperty.java │ │ │ ├── repository │ │ │ ├── MetaCommandRepository.java │ │ │ ├── PublicCommandRepository.java │ │ │ ├── UserCommandRepository.java │ │ │ ├── UserCommandSpecification.java │ │ │ └── UserRepository.java │ │ │ ├── security │ │ │ ├── CurrentUser.java │ │ │ ├── CustomJwtAuthFilter.java │ │ │ ├── CustomOAuthRequestRepository.java │ │ │ ├── OAuthFailureHandler.java │ │ │ ├── OAuthSuccessHandler.java │ │ │ ├── OAuthUserFactory.java │ │ │ ├── RestAuthenticationEntryPoint.java │ │ │ └── WebSecurityConfig.java │ │ │ ├── service │ │ │ ├── MetaCommandService.java │ │ │ ├── PublicCommandService.java │ │ │ ├── UserCommandService.java │ │ │ ├── UserService.java │ │ │ └── auth │ │ │ │ ├── CustomOAuthUserService.java │ │ │ │ └── CustomUserDetailsService.java │ │ │ └── util │ │ │ ├── AuthUtil.java │ │ │ ├── CookieUtil.java │ │ │ ├── JwtUtil.java │ │ │ └── SecurityUtil.java │ └── resources │ │ ├── META-INF │ │ └── spring-configuration-metadata.json │ │ ├── application-dev.yml │ │ ├── application.yml │ │ ├── db │ │ ├── changelog │ │ │ ├── db.changelog-1.0.0.xml │ │ │ └── db.changelog-master.xml │ │ └── db.graphml │ │ ├── jg-cql-dev.properties │ │ ├── jg-cql.properties │ │ ├── jg-inmemory.properties │ │ └── logback-spring.xml │ └── test │ ├── java │ └── com │ │ └── wirehall │ │ └── commandhunt │ │ └── backend │ │ ├── repository │ │ ├── UserCommandRepositoryTest.java │ │ └── UserRepositoryTest.java │ │ └── service │ │ ├── UserCommandServiceTest.java │ │ ├── UserServiceTest.java │ │ └── auth │ │ └── CustomUserDetailsServiceTest.java │ └── resources │ └── sql │ ├── InsertSingleUser.sql │ └── InsertSingleUserCommand.sql ├── frontend ├── .env.production ├── .gitignore ├── README.md ├── assembly.xml ├── docker │ ├── Dockerfile │ └── nginx │ │ └── default.conf ├── package-lock.json ├── package.json ├── pom.xml ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo.svg │ ├── logo192.png │ ├── logo192.svg │ ├── logo240.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt └── src │ ├── App.js │ ├── App.scss │ ├── App.test.js │ ├── Utils.js │ ├── actions │ ├── AuthActions.js │ ├── CommandActions.js │ ├── UserCommandActions.js │ └── index.js │ ├── api │ └── API.js │ ├── components │ ├── Builder.js │ ├── Builder.scss │ ├── Content.js │ ├── Content.scss │ ├── Finder.js │ ├── Finder.scss │ ├── Footer.js │ ├── Footer.scss │ ├── Header.js │ ├── Header.scss │ ├── Login.js │ ├── Login.scss │ ├── Sidebar.js │ ├── Sidebar.scss │ ├── SignUp.js │ ├── SignUp.scss │ ├── UserCommands.js │ ├── UserCommands.scss │ └── common │ │ ├── DynamicTextInput.js │ │ ├── ItemsPerPage.js │ │ ├── ItemsPerPage.scss │ │ ├── Modal.js │ │ ├── Modal.scss │ │ ├── PageNotFound.js │ │ ├── PageNotFound.scss │ │ ├── Pagination.js │ │ ├── Pagination.scss │ │ ├── PermissionInput.js │ │ ├── SearchInput.js │ │ ├── SearchInput.scss │ │ ├── Spinner.js │ │ └── Spinner.scss │ ├── index.js │ ├── index.scss │ ├── reducers │ └── index.js │ ├── serviceWorker.js │ └── styles │ ├── _color.scss │ ├── _font.scss │ ├── _global.scss │ ├── _layout.scss │ ├── _modals.scss │ ├── _shared.scss │ └── icons │ ├── pagesize.svg │ ├── social │ ├── fbk.svg │ ├── ggl.svg │ ├── gh.svg │ ├── social.svg │ └── ttr.svg │ └── user.svg ├── helm ├── .gitignore ├── .helmignore ├── Chart.yaml ├── README.md ├── pom.xml ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── backend-deployment.yaml │ ├── backend-service.yaml │ ├── frontend-deployment.yaml │ ├── frontend-service.yaml │ ├── ingress.yaml │ ├── initdb-configmap.yml │ ├── letsencrypt-prod-issuer.yaml │ └── tests │ │ └── test-connection.yaml └── values.yaml ├── mvnw ├── mvnw.cmd └── pom.xml /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | pull_request: 5 | types: [opened, synchronize, reopened] 6 | # Note: GitHub does not pass secrets(for security reasons) to PR workflows created with forked repos 7 | # So do not use any actions that require secrets 8 | # Tee GITHUB_TOKEN secret is allowed with readonly access for PR workflows created with forked repos 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | env: 14 | # This will suppress any download for dependencies and plugins or upload messages which would clutter the console log. 15 | # `showDateTime` will show the passed time in milliseconds. You need to specify `--batch-mode` to make this work. 16 | MAVEN_OPTS: "-Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true" 17 | # As of Maven 3.3.0 instead of this you may define these options in `.mvn/maven.config` so the same config is used when running from the command line. 18 | MAVEN_CLI_OPTS: "--update-snapshots --batch-mode --errors --fail-at-end --show-version" 19 | 20 | steps: 21 | - uses: actions/checkout@v2 22 | with: 23 | fetch-depth: 0 24 | 25 | - name: Set up JDK 11 26 | uses: actions/setup-java@v2 27 | with: 28 | java-version: '11' 29 | distribution: 'adopt' 30 | server-id: github # Value of the distributionManagement/repository/id field of the pom.xml 31 | settings-path: ${{ github.workspace }} # Location for the settings.xml file 32 | 33 | - name: Cache SonarCloud Packages 34 | uses: actions/cache@v2 35 | with: 36 | path: ~/.sonar/cache 37 | key: ${{ runner.os }}-sonar 38 | restore-keys: ${{ runner.os }}-sonar 39 | - name: Cache Maven Packages 40 | uses: actions/cache@v2 41 | with: 42 | path: ~/.m2/repository 43 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 44 | restore-keys: ${{ runner.os }}-maven- 45 | - name: Cache NPM Packages 46 | uses: actions/cache@v2 47 | with: 48 | path: ~/.npm 49 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} 50 | restore-keys: ${{ runner.os }}-node- 51 | 52 | - name: Build with Maven 53 | run: mvn $MAVEN_CLI_OPTS verify 54 | 55 | - name: Publish Unit Test Results # Shown on actions or pull requests views on github 56 | uses: EnricoMi/publish-unit-test-result-action@v1 57 | if: always() 58 | with: 59 | files: backend/target/surefire-reports/TEST-*.xml 60 | 61 | - name: Codecov 62 | uses: codecov/codecov-action@v1.5.0 -------------------------------------------------------------------------------- /.github/workflows/publish-packages.yaml: -------------------------------------------------------------------------------- 1 | name: Publish Packages 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - feature/* 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | env: 13 | # This will suppress any download for dependencies and plugins or upload messages which would clutter the console log. 14 | # `showDateTime` will show the passed time in milliseconds. You need to specify `--batch-mode` to make this work. 15 | MAVEN_OPTS: "-Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true" 16 | # As of Maven 3.3.0 instead of this you may define these options in `.mvn/maven.config` so the same config is used when running from the command line. 17 | MAVEN_CLI_OPTS: "--update-snapshots --batch-mode --errors --fail-at-end --show-version" 18 | 19 | steps: 20 | - name: Login to GitHub Container Registry 21 | uses: docker/login-action@v1 22 | with: 23 | registry: ghcr.io 24 | username: ${{ github.repository_owner }} 25 | password: ${{ secrets.GITHUB_TOKEN }} 26 | 27 | - uses: actions/checkout@v2 28 | with: 29 | fetch-depth: 0 # Required for sonar scan 30 | 31 | - name: Set up JDK 11 32 | uses: actions/setup-java@v2 33 | with: 34 | java-version: '11' # Sonar scanner requires java 11 35 | distribution: 'adopt' 36 | server-id: github # Value of the distributionManagement/repository/id field of the pom.xml 37 | settings-path: ${{ github.workspace }} # location for the settings.xml file 38 | 39 | - name: Cache SonarCloud Packages 40 | uses: actions/cache@v2 41 | with: 42 | path: ~/.sonar/cache 43 | key: ${{ runner.os }}-sonar 44 | restore-keys: ${{ runner.os }}-sonar 45 | - name: Cache Maven Packages 46 | uses: actions/cache@v2 47 | with: 48 | path: ~/.m2/repository 49 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 50 | restore-keys: ${{ runner.os }}-maven- 51 | - name: Cache NPM Packages 52 | uses: actions/cache@v2 53 | with: 54 | path: ~/.npm 55 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} 56 | restore-keys: ${{ runner.os }}-node- 57 | 58 | - name: Build & Publish to GitHub Packages 59 | run: mvn $MAVEN_CLI_OPTS deploy -s $GITHUB_WORKSPACE/settings.xml org.sonarsource.scanner.maven:sonar-maven-plugin:sonar docker:build docker:push 60 | env: 61 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any 62 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} 63 | 64 | - name: Publish Unit Test Results # Shown on actions or pull requests views 65 | uses: EnricoMi/publish-unit-test-result-action@v1 66 | if: always() 67 | with: 68 | files: backend/target/surefire-reports/TEST-*.xml 69 | 70 | - name: Codecov 71 | uses: codecov/codecov-action@v1.5.0 72 | 73 | - name: Upload Coverage Reports # Available in actions tab on github 74 | uses: actions/upload-artifact@v2 75 | with: 76 | name: code-coverage-reports 77 | path: | 78 | backend/target/site/jacoco 79 | frontend/coverage 80 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | logs/ 4 | .flattened-pom.xml 5 | !.mvn/wrapper/maven-wrapper.jar 6 | !**/src/main/** 7 | !**/src/test/** 8 | 9 | ### STS ### 10 | .apt_generated 11 | .classpath 12 | .factorypath 13 | .project 14 | .settings 15 | .springBeans 16 | .sts4-cache 17 | 18 | ### IntelliJ IDEA ### 19 | .idea 20 | *.iws 21 | *.iml 22 | *.ipr 23 | 24 | ### NetBeans ### 25 | /nbproject/private/ 26 | /nbbuild/ 27 | /dist/ 28 | /nbdist/ 29 | /.nb-gradle/ 30 | build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | 35 | ### OS generated files ### 36 | .DS_Store 37 | .DS_Store? 38 | ._* 39 | .*.sw[op] 40 | .Spotlight-V100 41 | .Trashes 42 | ehthumbs.db 43 | Thumbs.db 44 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivekweb2013/commandhunt/10acc2e13a28df808ad4d0900c7f539fc8db4e22/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.2/apache-maven-3.6.2-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar 3 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to CommandHunt 2 | 3 | First off, thanks for taking the time to contribute! :tada::+1: 4 | 5 | The following is a set of guidelines for contributing to CommandHunt, which is hosted in the [CommandHunt Repository](https://github.com/vivekweb2013/commandhunt) on GitHub. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. 6 | 7 | ## Development Process 8 | GitHub is used to track issues and feature requests, as well as accept pull requests. 9 | 10 | ## Pull Requests 11 | Feel free to submit pull requests. 12 | 13 | 1. Fork the repo and create your branch from `master`. 14 | 2. If you've added code that should be tested, add tests. 15 | 3. If you've changed APIs, update the documentation. 16 | 4. Ensure the test suite passes. 17 | 5. Make sure your code lints. 18 | 19 | ## Issues 20 | GitHub Issues is used to track public bugs. 21 | Please ensure your description is clear and has sufficient instructions to be able to reproduce the issue. 22 | 23 | ## Coding Style 24 | * The `backend` module follows `Google Java Style`. Use [google-java-format](https://plugins.jetbrains.com/plugin/8527-google-java-format) plugin. 25 | * The `frontend` module follows the default formatting of `Visual Studio Code` editor. 26 | 27 | ## License 28 | By contributing to CommandHunt, you agree that your contributions will be licensed under its MIT License. 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 vivekweb2013 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 | 5 | 6 |

7 | Find, Build, Store, Copy & Share Commands! 8 |
9 | https://commandhunt.com 10 |

11 |

12 | 13 |
14 | 15 | ## CommandHunt 16 | 17 | [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/vivekweb2013/commandhunt/Publish%20Packages/master?color=forestgreen)](https://github.com/vivekweb2013/commandhunt/actions?query=branch%3Amaster) 18 | [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=vivekweb2013_commandhunt&metric=alert_status)](https://sonarcloud.io/dashboard?id=vivekweb2013_commandhunt) 19 | [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=vivekweb2013_commandhunt&metric=coverage)](https://sonarcloud.io/dashboard?id=vivekweb2013_commandhunt) 20 | [![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=vivekweb2013_commandhunt&metric=code_smells)](https://sonarcloud.io/dashboard?id=vivekweb2013_commandhunt) 21 | [![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=vivekweb2013_commandhunt&metric=ncloc)](https://sonarcloud.io/dashboard?id=vivekweb2013_commandhunt) 22 | [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=vivekweb2013_commandhunt&metric=reliability_rating)](https://sonarcloud.io/dashboard?id=vivekweb2013_commandhunt) 23 | [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=vivekweb2013_commandhunt&metric=security_rating)](https://sonarcloud.io/dashboard?id=vivekweb2013_commandhunt) 24 | [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=vivekweb2013_commandhunt&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=vivekweb2013_commandhunt) 25 | 26 | [CommandHunt](https://commandhunt.com) is a web application that allows users to find, build, store, copy and publish(share) the commands. 27 | 28 | ### Features 29 | - Login with social-networks (OAuth providers) such as Google, Facebook and GitHub. 30 | - Easily find a specific command using search input. 31 | - Filtering, sorting and pagination supported. 32 | - Build the command with required values and save it privately to your account. 33 | - Access all the saved commands, filter them based on a keyword. 34 | - Publish a command to share it with others using the public link. 35 | - Copy the command to clipboard with just one click. 36 | - Print the command. 37 | - Responsive user interface. 38 | - Any application link can be bookmarked in the browser. 39 | 40 | ### Contribution Guidelines 41 | > Every Contribution Makes a Difference 42 | 43 | Read the [Contribution Guidelines](CONTRIBUTING.md) before you contribute. 44 | -------------------------------------------------------------------------------- /backend/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | logs/ 4 | graph/ 5 | !.mvn/wrapper/maven-wrapper.jar 6 | !**/src/main/** 7 | !**/src/test/** 8 | 9 | ### STS ### 10 | .apt_generated 11 | .classpath 12 | .factorypath 13 | .project 14 | .settings 15 | .springBeans 16 | .sts4-cache 17 | 18 | ### IntelliJ IDEA ### 19 | .idea 20 | *.iws 21 | *.iml 22 | *.ipr 23 | 24 | ### NetBeans ### 25 | /nbproject/private/ 26 | /nbbuild/ 27 | /dist/ 28 | /nbdist/ 29 | /.nb-gradle/ 30 | build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | 35 | ### OS generated files ### 36 | .DS_Store 37 | .DS_Store? 38 | ._* 39 | .*.sw[op] 40 | .Spotlight-V100 41 | .Trashes 42 | ehthumbs.db 43 | Thumbs.db 44 | -------------------------------------------------------------------------------- /backend/README.md: -------------------------------------------------------------------------------- 1 | ## CommandHunt Backend Module 2 | This is the backend module of commandhunt application. 3 | 4 | ### Build the backend module 5 | 6 | The following command is used to build this backend module. 7 | ```shell 8 | mvn clean install -e 9 | ``` 10 | This will build the project. It also runs the tests in the build process. 11 | 12 | Alternately, you can also build the project & skip the test execution with below command. 13 | ```shell 14 | mvn clean install -DskipTests 15 | ``` 16 | 17 | ### Running the backend module locally 18 | 19 | **Note:** Before starting the backend module, export OAuth env variables(as defined in application.yml file) for using OAuth login. 20 | 21 | There are several ways to run a Spring Boot application on your local machine. One way is to execute the `main` method in the `CommandHuntApplication` class from your IDE. 22 | 23 | Alternatively you can also use the below maven command that start the module using spring-boot plugin: 24 | 25 | ```shell 26 | mvn spring-boot:run 27 | ``` 28 | -------------------------------------------------------------------------------- /backend/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jdk-alpine 2 | WORKDIR /usr/app 3 | ARG JAR_FILE=./app/*.jar 4 | COPY ${JAR_FILE} ./app.jar 5 | ENTRYPOINT ["java","-jar","app.jar"] -------------------------------------------------------------------------------- /backend/src/main/java/com/wirehall/commandhunt/backend/CommandHuntApplication.java: -------------------------------------------------------------------------------- 1 | package com.wirehall.commandhunt.backend; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class CommandHuntApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(CommandHuntApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /backend/src/main/java/com/wirehall/commandhunt/backend/controller/MetaCommandController.java: -------------------------------------------------------------------------------- 1 | package com.wirehall.commandhunt.backend.controller; 2 | 3 | import com.wirehall.commandhunt.backend.dto.MetaCommand; 4 | import com.wirehall.commandhunt.backend.dto.filter.Filter; 5 | import com.wirehall.commandhunt.backend.dto.filter.PageResponse; 6 | import com.wirehall.commandhunt.backend.service.MetaCommandService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.http.MediaType; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | import javax.validation.Valid; 12 | import java.util.List; 13 | 14 | @RestController 15 | @RequestMapping(value = "api", produces = MediaType.APPLICATION_JSON_VALUE) 16 | public class MetaCommandController { 17 | 18 | private final MetaCommandService metaCommandService; 19 | 20 | @Autowired 21 | public MetaCommandController(MetaCommandService metaCommandService) { 22 | this.metaCommandService = metaCommandService; 23 | } 24 | 25 | @GetMapping(value = "/meta-command") 26 | public PageResponse getAllMetaCommands(@Valid Filter filter) { 27 | return metaCommandService.getAllMetaCommands(filter); 28 | } 29 | 30 | @GetMapping(value = "/meta-command/{id}") 31 | public MetaCommand getMetaCommandById(@PathVariable(name = "id") String id) { 32 | return metaCommandService.getMetaCommandById(id); 33 | } 34 | 35 | @GetMapping(value = "/meta-command/search") 36 | public MetaCommand getMetaCommandByName(@RequestParam(name = "name") String name) { 37 | return metaCommandService.getMetaCommandByName(name); 38 | } 39 | 40 | @GetMapping( 41 | value = "/meta-command/search", 42 | params = {"query"}) 43 | public List getMatchingMetaCommands(@RequestParam(name = "query") String query) { 44 | return metaCommandService.getMatchingMetaCommands(query); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /backend/src/main/java/com/wirehall/commandhunt/backend/controller/PublicCommandController.java: -------------------------------------------------------------------------------- 1 | package com.wirehall.commandhunt.backend.controller; 2 | 3 | import com.wirehall.commandhunt.backend.dto.PublicCommand; 4 | import com.wirehall.commandhunt.backend.service.PublicCommandService; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.http.MediaType; 9 | import org.springframework.security.access.prepost.PreAuthorize; 10 | import org.springframework.web.bind.annotation.*; 11 | 12 | import java.security.Principal; 13 | 14 | /** 15 | * Controller for performing action on public-command. A public command can be retrieved by anyone 16 | * without the need to login into the system. Only logged-in user can create a public command. A 17 | * public command can not be updated after creation. Not even the owner of the command is allowed to 18 | * update. A public command can be deleted by the owner. 19 | */ 20 | @RestController 21 | @RequestMapping(value = "api/public", produces = MediaType.APPLICATION_JSON_VALUE) 22 | public class PublicCommandController { 23 | private static final Logger LOGGER = LoggerFactory.getLogger(PublicCommandController.class); 24 | 25 | private final PublicCommandService publicCommandService; 26 | 27 | @Autowired 28 | public PublicCommandController(PublicCommandService publicCommandService) { 29 | this.publicCommandService = publicCommandService; 30 | } 31 | 32 | @GetMapping(value = "/public-command/{id}") 33 | public PublicCommand getPublicCommandById( 34 | @PathVariable(name = "id") Long publicCommandId, Principal principal) { 35 | LOGGER.info("Request for retrieving public-command with id: {}", publicCommandId); 36 | String userEmail = principal == null ? null : principal.getName(); 37 | return publicCommandService.getPublicCommandById(publicCommandId, userEmail); 38 | } 39 | 40 | @PostMapping(value = "/public-command") 41 | @PreAuthorize("hasRole('ROLE_USER')") 42 | public PublicCommand addPublicCommand( 43 | @RequestBody PublicCommand publicCommand, Principal principal) { 44 | LOGGER.info( 45 | "Request from user: {} for adding public-command: {}", principal.getName(), publicCommand); 46 | return publicCommandService.addPublicCommand(publicCommand, principal.getName()); 47 | } 48 | 49 | @DeleteMapping(value = "/public-command/{id}") 50 | @PreAuthorize("hasRole('ROLE_USER')") 51 | public void deleteUserCommand( 52 | @PathVariable(name = "id") Long publicCommandId, Principal principal) { 53 | LOGGER.info( 54 | "Request from user: {} for deleting public-command with id: {}", 55 | principal.getName(), 56 | publicCommandId); 57 | publicCommandService.deletePublicCommand(publicCommandId, principal.getName()); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /backend/src/main/java/com/wirehall/commandhunt/backend/controller/UserCommandController.java: -------------------------------------------------------------------------------- 1 | package com.wirehall.commandhunt.backend.controller; 2 | 3 | import com.wirehall.commandhunt.backend.dto.UserCommand; 4 | import com.wirehall.commandhunt.backend.dto.filter.Filter; 5 | import com.wirehall.commandhunt.backend.dto.filter.PageResponse; 6 | import com.wirehall.commandhunt.backend.service.UserCommandService; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.http.MediaType; 11 | import org.springframework.security.access.prepost.PreAuthorize; 12 | import org.springframework.web.bind.annotation.*; 13 | 14 | import javax.validation.Valid; 15 | import java.security.Principal; 16 | 17 | @RestController 18 | @RequestMapping(value = "api/user", produces = MediaType.APPLICATION_JSON_VALUE) 19 | @PreAuthorize("hasRole('ROLE_USER')") 20 | public class UserCommandController { 21 | 22 | private static final Logger LOGGER = LoggerFactory.getLogger(UserCommandController.class); 23 | 24 | private final UserCommandService userCommandService; 25 | 26 | @Autowired 27 | public UserCommandController(UserCommandService userCommandService) { 28 | this.userCommandService = userCommandService; 29 | } 30 | 31 | @GetMapping(value = "/user-command") 32 | public PageResponse getAllUserCommands(@Valid Filter filter, Principal principal) { 33 | LOGGER.info("Request from user: {} for retrieving user-commands", principal.getName()); 34 | LOGGER.info("Received filters: {}", filter); 35 | return userCommandService.getAllUserCommands(filter, principal.getName()); 36 | } 37 | 38 | @GetMapping(value = "/user-command/{id}") 39 | public UserCommand getUserCommandById(@PathVariable(name = "id") Long id, Principal principal) { 40 | LOGGER.info( 41 | "Request from user: {} for retrieving user-command with id: {}", principal.getName(), id); 42 | return userCommandService.getUserCommandById(id, principal.getName()); 43 | } 44 | 45 | @PostMapping(value = "/user-command") 46 | public void addUserCommand(@RequestBody UserCommand userCommand, Principal principal) { 47 | LOGGER.info( 48 | "Request from user: {} for adding user-command: {}", principal.getName(), userCommand); 49 | userCommandService.addUserCommand(userCommand, principal.getName()); 50 | } 51 | 52 | @PutMapping(value = "/user-command/{id}") 53 | public void updateUserCommand(@RequestBody UserCommand userCommand, Principal principal) { 54 | LOGGER.info( 55 | "Request from user: {} for updating user-command: {}", principal.getName(), userCommand); 56 | userCommandService.updateUserCommand(userCommand, principal.getName()); 57 | } 58 | 59 | @DeleteMapping(value = "/user-command/{id}") 60 | public void deleteUserCommand( 61 | @PathVariable(name = "id") Long userCommandId, Principal principal) { 62 | LOGGER.info( 63 | "Request from user: {} for deleting user-command with id: {}", 64 | principal.getName(), 65 | userCommandId); 66 | userCommandService.deleteUserCommand(userCommandId, principal.getName()); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /backend/src/main/java/com/wirehall/commandhunt/backend/dto/BaseCommand.java: -------------------------------------------------------------------------------- 1 | package com.wirehall.commandhunt.backend.dto; 2 | 3 | import javax.validation.constraints.NotNull; 4 | import java.sql.Timestamp; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | public abstract class BaseCommand { 10 | 11 | private Long id; 12 | 13 | @NotNull private String commandName; 14 | @NotNull private String commandText; 15 | 16 | private Timestamp createdOn; 17 | 18 | private Map flags = new HashMap<>(); 19 | private Map> options = new HashMap<>(); 20 | 21 | public Long getId() { 22 | return id; 23 | } 24 | 25 | public void setId(Long id) { 26 | this.id = id; 27 | } 28 | 29 | public String getCommandName() { 30 | return commandName; 31 | } 32 | 33 | public void setCommandName(String commandName) { 34 | this.commandName = commandName; 35 | } 36 | 37 | public String getCommandText() { 38 | return commandText; 39 | } 40 | 41 | public void setCommandText(String commandText) { 42 | this.commandText = commandText; 43 | } 44 | 45 | public Timestamp getCreatedOn() { 46 | return createdOn; 47 | } 48 | 49 | public void setCreatedOn(Timestamp createdOn) { 50 | this.createdOn = createdOn; 51 | } 52 | 53 | /** 54 | * Returns the stored flags as name-value pairs. 55 | * 56 | * @return The key-value map of flag name and its value. 57 | */ 58 | public Map getFlags() { 59 | return flags; 60 | } 61 | 62 | /** 63 | * Sets the flags as name-value pairs. 64 | * 65 | * @param flags The key-value map of flag name and its value. 66 | */ 67 | public void setFlags(Map flags) { 68 | this.flags = flags; 69 | } 70 | 71 | /** 72 | * Returns the stored options as name-value pairs. 73 | * 74 | * @return The key-value map of option name and its value. 75 | */ 76 | public Map> getOptions() { 77 | return options; 78 | } 79 | 80 | /** 81 | * Sets the options as name-value pairs. 82 | * 83 | * @param options The key-value map of option name and its value. 84 | */ 85 | public void setOptions(Map> options) { 86 | this.options = options; 87 | } 88 | 89 | @Override 90 | public String toString() { 91 | return "BaseCommand{" 92 | + "id=" 93 | + id 94 | + ", commandName='" 95 | + commandName 96 | + '\'' 97 | + ", commandText='" 98 | + commandText 99 | + '\'' 100 | + ", createdOn=" 101 | + createdOn 102 | + ", flags=" 103 | + flags 104 | + ", options=" 105 | + options 106 | + '}'; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /backend/src/main/java/com/wirehall/commandhunt/backend/dto/ErrorResponse.java: -------------------------------------------------------------------------------- 1 | package com.wirehall.commandhunt.backend.dto; 2 | 3 | import com.fasterxml.jackson.annotation.JsonTypeInfo; 4 | import com.fasterxml.jackson.annotation.JsonTypeName; 5 | 6 | import java.util.List; 7 | 8 | @JsonTypeName("error") 9 | @JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) 10 | public class ErrorResponse { 11 | 12 | private String message; 13 | private List details; 14 | 15 | public ErrorResponse(String message) { 16 | this.message = message; 17 | } 18 | 19 | public String getMessage() { 20 | return message; 21 | } 22 | 23 | public void setMessage(String message) { 24 | this.message = message; 25 | } 26 | 27 | public List getDetails() { 28 | return details; 29 | } 30 | 31 | public void setDetails(List details) { 32 | this.details = details; 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return "ErrorResponse{" + "message='" + message + '\'' + ", details=" + details + '}'; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /backend/src/main/java/com/wirehall/commandhunt/backend/dto/Flag.java: -------------------------------------------------------------------------------- 1 | package com.wirehall.commandhunt.backend.dto; 2 | 3 | import com.wirehall.commandhunt.backend.model.graph.props.FlagProperty; 4 | import org.springframework.lang.NonNull; 5 | 6 | import java.util.EnumMap; 7 | import java.util.Map; 8 | 9 | public class Flag extends Node implements Comparable { 10 | 11 | public Flag() { 12 | super(FlagProperty.class); 13 | } 14 | 15 | @Override 16 | public Map getProperties() { 17 | if (properties == null) { 18 | properties = new EnumMap<>(FlagProperty.class); 19 | } 20 | return properties; 21 | } 22 | 23 | @Override 24 | public int compareTo(@NonNull Flag f) { 25 | if (this.equals(f)) return 0; 26 | byte i = (byte) this.properties.get(FlagProperty.SEQUENCE); 27 | byte j = (byte) f.properties.get(FlagProperty.SEQUENCE); 28 | return i - j; 29 | } 30 | 31 | @Override 32 | public boolean equals(Object obj) { 33 | return super.equals(obj); 34 | } 35 | 36 | @Override 37 | public int hashCode() { 38 | return super.hashCode(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /backend/src/main/java/com/wirehall/commandhunt/backend/dto/MetaCommand.java: -------------------------------------------------------------------------------- 1 | package com.wirehall.commandhunt.backend.dto; 2 | 3 | import com.wirehall.commandhunt.backend.model.graph.props.MetaCommandProperty; 4 | 5 | import java.util.ArrayList; 6 | import java.util.EnumMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | /** This class holds the metadata of a specific command. */ 11 | public class MetaCommand extends Node { 12 | 13 | private List flags; 14 | private List