├── .eslintrc.json ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── codeql-analysis.yml │ ├── integrationtests.yml │ ├── productiontests.yml │ └── unittests.yml ├── .gitignore ├── .gitmodules ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── app ├── __init__.py ├── admin │ ├── __init__.py │ └── routes.py ├── api │ ├── __init__.py │ ├── routes.py │ └── v1 │ │ ├── __init__.py │ │ └── routes.py ├── auth │ ├── __init__.py │ ├── acls.py │ └── routes.py ├── exceptions.py ├── frontend │ ├── __init__.py │ └── routes.py ├── product │ ├── __init__.py │ └── routes.py ├── profile │ ├── __init__.py │ └── routes.py ├── review │ ├── __init__.py │ └── routes.py ├── vcs_proxy │ ├── __init__.py │ └── routes.py └── vulnerability │ ├── __init__.py │ ├── routes.py │ └── views │ ├── __init__.py │ ├── details.py │ ├── vulncode_db.py │ └── vulnerability.py ├── cfg.py ├── crawl_patches.py ├── data ├── __init__.py ├── database.py ├── forms │ └── __init__.py ├── models │ ├── __init__.py │ ├── base.py │ ├── cwe.py │ ├── nvd.py │ ├── nvd_template.py │ ├── user.py │ └── vulnerability.py └── utils.py ├── deploy.sh ├── deps ├── common_requirements.txt ├── dev_requirements.txt ├── requirements.txt └── vcs_requirements.txt ├── docker ├── .dockerignore ├── README.md ├── cve-data │ └── fetch_cwe.sh ├── db_schema.sql ├── docker-admin.sh ├── docker-compose.admin.yml ├── docker-compose.yml ├── frontend │ └── Dockerfile ├── go-cve-dictionary │ └── Dockerfile ├── utils │ └── Dockerfile └── vcs_proxy │ └── Dockerfile ├── example_app.yaml ├── example_vcs_proxy.yaml ├── format.sh ├── gce_vcs_proxy.py ├── lib ├── __init__.py ├── app_factory.py ├── statemachine.py ├── utils.py ├── vcs_handler │ ├── __init__.py │ ├── github_handler.py │ ├── gitrepo_handler.py │ └── vcs_handler.py └── vcs_management.py ├── lint.sh ├── main.py ├── manage.sh ├── migrations ├── README ├── alembic.ini ├── env.py ├── script.py.mako └── versions │ ├── 13b73f6d1082_restructuring_vulnerability_pk_and_.py │ ├── 1af56ef5ac3c_user_states.py │ ├── 27a721daab2e_renamed_email_to_login_in_user_table.py │ ├── 32ded3390554_adding_table_that_keeps_track_of_open_.py │ ├── 4c879a183a73_makes_vulnerability_resources_fk_non_.py │ ├── 4d799bc13b95_pii_flags.py │ ├── 5dd1d09f15fe_adding_index_to_created_date_column_for_.py │ ├── 611733367157_adding_new_fields_and_keys_indices_to_.py │ ├── 6704686720fa_invite_codes.py │ ├── 6a577b4c41fe_new_user_state.py │ ├── 82f8f48c6ee6_initial_layout.py │ ├── 8696079cdbfc_removes_redundant_index_from_oss_.py │ ├── 9a935d8fb960_updating_the_index_over_cpe_to_cover_.py │ ├── 9d370f33f1a0_user_login_types.py │ ├── c10e1faccb1c_adds_a_distinct_vulnerbility_table_.py │ ├── c77061c72a59_products.py │ ├── d694cd137157_re_establishes_the_foreign_key_between_.py │ ├── f02f9e75f973_user_roles.py │ └── fb11cb6a2398_updating_review_state_machine_to_.py ├── mypy.ini ├── package.json ├── pylintrc ├── pytest.ini ├── requirements.txt ├── run.sh ├── setup.sh ├── static ├── css │ ├── main.css │ ├── third_party │ │ ├── all.min.css │ │ ├── bootstrap-grid.css │ │ ├── bootstrap-grid.css.map │ │ ├── bootstrap-grid.min.css │ │ ├── bootstrap-grid.min.css.map │ │ ├── bootstrap-reboot.css │ │ ├── bootstrap-reboot.css.map │ │ ├── bootstrap-reboot.min.css │ │ ├── bootstrap-reboot.min.css.map │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ ├── bootstrap.min.css.map │ │ ├── jquery-ui.min.css │ │ ├── jquery.dataTables.min.css │ │ ├── jstree │ │ │ ├── 32px.png │ │ │ ├── 40px.png │ │ │ ├── style.min.css │ │ │ └── throbber.gif │ │ ├── mdb.css │ │ └── mdb.min.css.map │ ├── tutorial.css │ └── webfonts │ │ ├── fa-brands-400.eot │ │ ├── fa-brands-400.svg │ │ ├── fa-brands-400.ttf │ │ ├── fa-brands-400.woff │ │ ├── fa-brands-400.woff2 │ │ ├── fa-regular-400.eot │ │ ├── fa-regular-400.svg │ │ ├── fa-regular-400.ttf │ │ ├── fa-regular-400.woff │ │ ├── fa-regular-400.woff2 │ │ ├── fa-solid-900.eot │ │ ├── fa-solid-900.svg │ │ ├── fa-solid-900.ttf │ │ ├── fa-solid-900.woff │ │ └── fa-solid-900.woff2 ├── js │ ├── embed.js │ ├── embed_internal.js │ ├── lib │ │ ├── CommentWidget.js │ │ ├── Constants.js │ │ ├── Editor.js │ │ ├── File.js │ │ ├── FileComment.js │ │ ├── FileMarker.js │ │ ├── FileTree.js │ │ ├── UI.js │ │ └── ZoneViewWidget.js │ ├── main.js │ ├── product_search.js │ ├── third_party │ │ ├── bootstrap.bundle.js │ │ ├── bootstrap.bundle.js.map │ │ ├── bootstrap.bundle.min.js │ │ ├── bootstrap.bundle.min.js.map │ │ ├── bootstrap.js │ │ ├── bootstrap.js.map │ │ ├── bootstrap.min.js │ │ ├── bootstrap.min.js.map │ │ ├── jquery-ui.min.js │ │ ├── jquery.dataTables.min.js │ │ ├── jquery.min.js │ │ ├── jstree.min.js │ │ ├── loader.js │ │ ├── mdb.min.js │ │ ├── mdb.min.js.map │ │ ├── popper.min.js │ │ ├── popper.min.js.map │ │ ├── showdown.min.js │ │ └── showdown.min.js.map │ └── tutorial.js ├── logos │ ├── GitHub-Mark-120px-plus.png │ ├── GitHub-Mark-32px.png │ └── GitHub-Mark-64px.png ├── monaco │ ├── min-maps │ │ └── vs │ │ │ ├── base │ │ │ └── worker │ │ │ │ └── workerMain.js.map │ │ │ ├── editor │ │ │ ├── editor.main.js.map │ │ │ ├── editor.main.nls.de.js.map │ │ │ ├── editor.main.nls.es.js.map │ │ │ ├── editor.main.nls.fr.js.map │ │ │ ├── editor.main.nls.it.js.map │ │ │ ├── editor.main.nls.ja.js.map │ │ │ ├── editor.main.nls.js.map │ │ │ ├── editor.main.nls.ko.js.map │ │ │ ├── editor.main.nls.ru.js.map │ │ │ ├── editor.main.nls.zh-cn.js.map │ │ │ └── editor.main.nls.zh-tw.js.map │ │ │ └── loader.js.map │ ├── min │ │ └── vs │ │ │ ├── base │ │ │ ├── browser │ │ │ │ └── ui │ │ │ │ │ └── codiconLabel │ │ │ │ │ └── codicon │ │ │ │ │ └── codicon.ttf │ │ │ └── worker │ │ │ │ └── workerMain.js │ │ │ ├── basic-languages │ │ │ ├── abap │ │ │ │ └── abap.js │ │ │ ├── apex │ │ │ │ └── apex.js │ │ │ ├── azcli │ │ │ │ └── azcli.js │ │ │ ├── bat │ │ │ │ └── bat.js │ │ │ ├── cameligo │ │ │ │ └── cameligo.js │ │ │ ├── clojure │ │ │ │ └── clojure.js │ │ │ ├── coffee │ │ │ │ └── coffee.js │ │ │ ├── cpp │ │ │ │ └── cpp.js │ │ │ ├── csharp │ │ │ │ └── csharp.js │ │ │ ├── csp │ │ │ │ └── csp.js │ │ │ ├── css │ │ │ │ └── css.js │ │ │ ├── dockerfile │ │ │ │ └── dockerfile.js │ │ │ ├── fsharp │ │ │ │ └── fsharp.js │ │ │ ├── go │ │ │ │ └── go.js │ │ │ ├── graphql │ │ │ │ └── graphql.js │ │ │ ├── handlebars │ │ │ │ └── handlebars.js │ │ │ ├── html │ │ │ │ └── html.js │ │ │ ├── ini │ │ │ │ └── ini.js │ │ │ ├── java │ │ │ │ └── java.js │ │ │ ├── javascript │ │ │ │ └── javascript.js │ │ │ ├── kotlin │ │ │ │ └── kotlin.js │ │ │ ├── less │ │ │ │ └── less.js │ │ │ ├── lua │ │ │ │ └── lua.js │ │ │ ├── markdown │ │ │ │ └── markdown.js │ │ │ ├── mips │ │ │ │ └── mips.js │ │ │ ├── msdax │ │ │ │ └── msdax.js │ │ │ ├── mysql │ │ │ │ └── mysql.js │ │ │ ├── objective-c │ │ │ │ └── objective-c.js │ │ │ ├── pascal │ │ │ │ └── pascal.js │ │ │ ├── pascaligo │ │ │ │ └── pascaligo.js │ │ │ ├── perl │ │ │ │ └── perl.js │ │ │ ├── pgsql │ │ │ │ └── pgsql.js │ │ │ ├── php │ │ │ │ └── php.js │ │ │ ├── postiats │ │ │ │ └── postiats.js │ │ │ ├── powerquery │ │ │ │ └── powerquery.js │ │ │ ├── powershell │ │ │ │ └── powershell.js │ │ │ ├── pug │ │ │ │ └── pug.js │ │ │ ├── python │ │ │ │ └── python.js │ │ │ ├── r │ │ │ │ └── r.js │ │ │ ├── razor │ │ │ │ └── razor.js │ │ │ ├── redis │ │ │ │ └── redis.js │ │ │ ├── redshift │ │ │ │ └── redshift.js │ │ │ ├── restructuredtext │ │ │ │ └── restructuredtext.js │ │ │ ├── ruby │ │ │ │ └── ruby.js │ │ │ ├── rust │ │ │ │ └── rust.js │ │ │ ├── sb │ │ │ │ └── sb.js │ │ │ ├── scheme │ │ │ │ └── scheme.js │ │ │ ├── scss │ │ │ │ └── scss.js │ │ │ ├── shell │ │ │ │ └── shell.js │ │ │ ├── solidity │ │ │ │ └── solidity.js │ │ │ ├── sophia │ │ │ │ └── sophia.js │ │ │ ├── sql │ │ │ │ └── sql.js │ │ │ ├── st │ │ │ │ └── st.js │ │ │ ├── swift │ │ │ │ └── swift.js │ │ │ ├── tcl │ │ │ │ └── tcl.js │ │ │ ├── twig │ │ │ │ └── twig.js │ │ │ ├── typescript │ │ │ │ └── typescript.js │ │ │ ├── vb │ │ │ │ └── vb.js │ │ │ ├── xml │ │ │ │ └── xml.js │ │ │ └── yaml │ │ │ │ └── yaml.js │ │ │ ├── editor │ │ │ ├── editor.main.css │ │ │ ├── editor.main.js │ │ │ ├── editor.main.nls.de.js │ │ │ ├── editor.main.nls.es.js │ │ │ ├── editor.main.nls.fr.js │ │ │ ├── editor.main.nls.it.js │ │ │ ├── editor.main.nls.ja.js │ │ │ ├── editor.main.nls.js │ │ │ ├── editor.main.nls.ko.js │ │ │ ├── editor.main.nls.ru.js │ │ │ ├── editor.main.nls.zh-cn.js │ │ │ └── editor.main.nls.zh-tw.js │ │ │ ├── language │ │ │ ├── css │ │ │ │ ├── cssMode.js │ │ │ │ └── cssWorker.js │ │ │ ├── html │ │ │ │ ├── htmlMode.js │ │ │ │ └── htmlWorker.js │ │ │ ├── json │ │ │ │ ├── jsonMode.js │ │ │ │ └── jsonWorker.js │ │ │ └── typescript │ │ │ │ ├── tsMode.js │ │ │ │ └── tsWorker.js │ │ │ └── loader.js │ └── themes │ │ ├── darcula.json │ │ └── monokai.json └── tutorial │ └── 1.json ├── templates ├── admin │ ├── invite_codes.html │ └── user_list.html ├── base.html ├── base_nonav.html ├── custom_bootstrap_form.html ├── editor │ ├── editor_container.html │ ├── file_tree.html │ ├── metadata_edit.html │ └── metadata_view.html ├── error_generic.html ├── footer.html ├── header.html ├── index.html ├── index_vuln_list.html ├── list_vuln_entries.html ├── local_login.html ├── login.html ├── macros │ ├── generate_vuln_table.html │ ├── pagination.html │ ├── products.html │ ├── statusbar.html │ ├── text_format.html │ └── user.html ├── maintenance.html ├── navbar.html ├── nvd_view.html ├── product │ └── view.html ├── profile │ ├── edit_proposal.html │ ├── index.html │ ├── profile_viewer.html │ └── proposals_view.html ├── review │ ├── feedback_card.html │ └── list.html ├── terms.html ├── terms_text.html └── vulnerability │ ├── code_editor.html │ ├── create.html │ ├── delete.html │ ├── edit.html │ ├── embedded.html │ ├── forms │ ├── code_location.html │ └── product_search.html │ ├── info.html │ ├── review │ └── review.html │ ├── snippet.html │ ├── view.html │ ├── view_details.html │ ├── view_overview.html │ └── vuln_create.html ├── tests ├── __init__.py ├── app_tests │ ├── __init__.py │ ├── api │ │ ├── __init__.py │ │ ├── test_routes.py │ │ └── v1 │ │ │ ├── __init__.py │ │ │ └── test_routes.py │ ├── auth │ │ ├── __init__.py │ │ └── test_routes.py │ ├── frontend │ │ ├── __init__.py │ │ └── test_routes.py │ ├── product │ │ ├── __init__.py │ │ └── test_routes.py │ ├── profile │ │ ├── __init__.py │ │ └── test_routes.py │ └── vulnerability │ │ ├── __init__.py │ │ ├── test_routes.py │ │ └── views │ │ └── __init__.py ├── conftest.py ├── data_tests │ ├── models │ │ ├── __init__.py │ │ └── test_vulnerability.py │ └── test_utils.py ├── lib_tests │ └── __init__.py ├── misc_tests │ ├── __init__.py │ └── test_crawl_patches.py ├── run_integration_tests.sh ├── run_production_tests.sh └── run_unit_tests.sh └── tools └── github_releases.py /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true 5 | }, 6 | "extends": "google", 7 | "globals": { 8 | "Atomics": "readonly", 9 | "SharedArrayBuffer": "readonly" 10 | }, 11 | "parserOptions": { 12 | "ecmaVersion": 2018, 13 | "sourceType": "module" 14 | }, 15 | "rules": { 16 | "require-jsdoc": "off", 17 | "prefer-const": "off" 18 | } 19 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '30 14 * * 5' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | 28 | strategy: 29 | fail-fast: false 30 | matrix: 31 | language: [ 'javascript', 'python' ] 32 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 33 | # Learn more: 34 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 35 | 36 | steps: 37 | - name: Checkout repository 38 | uses: actions/checkout@v2 39 | 40 | # Initializes the CodeQL tools for scanning. 41 | - name: Initialize CodeQL 42 | uses: github/codeql-action/init@v1 43 | with: 44 | languages: ${{ matrix.language }} 45 | # If you wish to specify custom queries, you can do so here or in a config file. 46 | # By default, queries listed here will override any specified in a config file. 47 | # Prefix the list here with "+" to use these queries and those in the config file. 48 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 49 | 50 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 51 | # If this step fails, then you should remove it and run the build manually (see below) 52 | - name: Autobuild 53 | uses: github/codeql-action/autobuild@v1 54 | 55 | # ℹ️ Command-line programs to run using the OS shell. 56 | # 📚 https://git.io/JvXDl 57 | 58 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 59 | # and modify them (or add more) to build your code if your project 60 | # uses a compiled language 61 | 62 | #- run: | 63 | # make bootstrap 64 | # make release 65 | 66 | - name: Perform CodeQL Analysis 67 | uses: github/codeql-action/analyze@v1 68 | -------------------------------------------------------------------------------- /.github/workflows/integrationtests.yml: -------------------------------------------------------------------------------- 1 | name: Integration Tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | build: 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Environment 18 | run: env 19 | - name: Checkout 20 | run: | 21 | if [ "$GITHUB_EVENT_NAME" == 'push' ] 22 | then 23 | git clone --recursive https://github.com/$GITHUB_REPOSITORY $GITHUB_WORKSPACE && \ 24 | git -C "$GITHUB_WORKSPACE" checkout $GITHUB_SHA 25 | elif [ "$GITHUB_EVENT_NAME" == 'pull_request' ] 26 | then 27 | git clone --single-branch --recursive https://github.com/$GITHUB_REPOSITORY $GITHUB_WORKSPACE && \ 28 | git -C "$GITHUB_WORKSPACE" fetch origin $GITHUB_REF && \ 29 | git -C "$GITHUB_WORKSPACE" checkout FETCH_HEAD 30 | else 31 | git clone --recursive -b $GITHUB_HEAD_REF https://github.com/$GITHUB_REPOSITORY $GITHUB_WORKSPACE 32 | fi 33 | - name: Build base containers 34 | run: ./setup.sh 35 | - name: Run the tests 36 | run: ./docker/docker-admin.sh test 37 | -------------------------------------------------------------------------------- /.github/workflows/productiontests.yml: -------------------------------------------------------------------------------- 1 | name: Production Tests 2 | 3 | on: 4 | schedule: 5 | # * is a special character in YAML so you have to quote this string 6 | # Note: Time is specified in UTC. 7 | - cron: '0 */12 * * *' 8 | 9 | 10 | jobs: 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Environment 17 | run: env 18 | - name: Checkout 19 | run: | 20 | git clone --recursive https://github.com/$GITHUB_REPOSITORY $GITHUB_WORKSPACE 21 | - name: Build base containers 22 | run: ./setup.sh 23 | - name: Run the tests 24 | run: ./docker/docker-admin.sh production_test 25 | -------------------------------------------------------------------------------- /.github/workflows/unittests.yml: -------------------------------------------------------------------------------- 1 | name: Unit Tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | build: 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Environment 18 | run: env 19 | - name: Checkout 20 | run: | 21 | if [ "$GITHUB_EVENT_NAME" == 'push' ] 22 | then 23 | git clone --recursive https://github.com/$GITHUB_REPOSITORY $GITHUB_WORKSPACE && \ 24 | git -C "$GITHUB_WORKSPACE" checkout $GITHUB_SHA 25 | elif [ "$GITHUB_EVENT_NAME" == 'pull_request' ] 26 | then 27 | git clone --single-branch --recursive https://github.com/$GITHUB_REPOSITORY $GITHUB_WORKSPACE && \ 28 | git -C "$GITHUB_WORKSPACE" fetch origin $GITHUB_REF && \ 29 | git -C "$GITHUB_WORKSPACE" checkout FETCH_HEAD 30 | else 31 | git clone --recursive -b $GITHUB_HEAD_REF https://github.com/$GITHUB_REPOSITORY $GITHUB_WORKSPACE 32 | fi 33 | - name: Setup Python 3.7 34 | run: | 35 | python_dir=$(ls -1d $RUNNER_TOOL_CACHE/Python/3.7*/x64 | tail -1) 36 | echo "${python_dir}" >> $GITHUB_PATH 37 | echo "${python_dir}/bin" >> $GITHUB_PATH 38 | echo "pythonLocation=${python_dir}" >> $GITHUB_ENV 39 | - name: Install dependencies 40 | run: | 41 | python -m pip install --upgrade pip 42 | # Install mysql_config on machine to avoid "OSError: mysql_config not found" error during pip install for mysqlclient. 43 | sudo apt-get update && sudo apt-get install -y libmysqlclient-dev 44 | pip3 install -r deps/requirements.txt 45 | pip3 install -r deps/dev_requirements.txt 46 | pip3 install -r deps/vcs_requirements.txt 47 | - name: Run Python tests 48 | run: | 49 | ./tests/run_unit_tests.sh 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | app.yaml 2 | vcs_proxy.yaml 3 | *.log 4 | *.log.* 5 | misc/* 6 | cache/* 7 | cert 8 | cert/* 9 | third_party/* 10 | # Permanent third party content. 11 | !third_party/go-cve-dictionary 12 | env/* 13 | vulnerable_code/* 14 | *.py[co] 15 | *.iml 16 | cloud_sql_proxy 17 | *~ 18 | *.sw[po] 19 | __pycache__/ 20 | venv/ 21 | local_cfg.py 22 | .idea 23 | node_modules 24 | docker/db-data 25 | docker/cve-data/* 26 | !docker/cve-data/fetch_cwe.sh 27 | .coverage 28 | htmlcov 29 | .pytest_cache 30 | .mypy_cache 31 | .vscode 32 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "third_party/go-cve-dictionary"] 2 | path = third_party/go-cve-dictionary 3 | url = git://github.com/kotakanbe/go-cve-dictionary 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution; 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## Code reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult 22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 23 | information on using pull requests. 24 | 25 | ## Community Guidelines 26 | 27 | This project follows [Google's Open Source Community 28 | Guidelines](https://opensource.google.com/conduct/). 29 | -------------------------------------------------------------------------------- /app/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from flask import flash, redirect, url_for 16 | 17 | 18 | def flash_error(text, redirect_target=None): 19 | flash(text, "danger") 20 | if redirect_target: 21 | return redirect(url_for(redirect_target)) 22 | -------------------------------------------------------------------------------- /app/admin/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /app/api/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /app/api/v1/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /app/auth/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /app/exceptions.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | class InvalidIdentifierException(Exception): 17 | pass 18 | 19 | 20 | class InvalidProducts(Exception): 21 | pass 22 | -------------------------------------------------------------------------------- /app/frontend/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /app/frontend/routes.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | from flask import Blueprint 15 | from flask import render_template 16 | from flask import send_from_directory 17 | 18 | from app.vulnerability.views.vulncode_db import VulncodeDB 19 | from app.auth.acls import skip_authorization 20 | 21 | bp = Blueprint("frontend", __name__) 22 | 23 | 24 | @bp.route("/static/") 25 | @skip_authorization 26 | def serve_static(path): 27 | return send_from_directory("static", path) 28 | 29 | 30 | @bp.route("/") 31 | @skip_authorization 32 | def serve_index(): 33 | vcdb = VulncodeDB() 34 | return render_template("index.html", vcdb=vcdb) 35 | 36 | 37 | @bp.route("/maintenance") 38 | @skip_authorization 39 | def maintenance(): 40 | return render_template("maintenance.html") 41 | 42 | 43 | @bp.route("/list_entries") 44 | @skip_authorization 45 | def list_entries(): 46 | vcdb = VulncodeDB() 47 | return render_template("list_vuln_entries.html", vcdb=vcdb) 48 | 49 | 50 | @bp.route("/terms") 51 | @skip_authorization 52 | def terms(): 53 | return render_template("terms_text.html") 54 | -------------------------------------------------------------------------------- /app/product/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /app/profile/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /app/review/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /app/vcs_proxy/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /app/vcs_proxy/routes.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from flask import Blueprint 16 | 17 | bp = Blueprint("vcs_proxy", __name__) 18 | 19 | 20 | # TODO: Refactor this to be automatically determined for the VCS proxy and 21 | # main application. 22 | # Note: Keep this in sync with the route in gce_vcs_proxy.py. 23 | @bp.route("/main_api") 24 | def main_api(): 25 | pass 26 | -------------------------------------------------------------------------------- /app/vulnerability/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /app/vulnerability/views/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /data/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /data/database.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Attention: DO NOT DELETE THE * IMPORT BELOW 16 | # -> Required to import all model definitions to allow database creation. 17 | 18 | from typing import Dict, Iterable, Optional 19 | from flask import Flask 20 | from flask_migrate import Migrate # type: ignore 21 | from sqlalchemy.engine import reflection 22 | 23 | from data.models import * # pylint: disable=wildcard-import 24 | from data.models.base import db, ma 25 | 26 | 27 | class Database: 28 | db = db 29 | ma = ma # pylint: disable=invalid-name 30 | migrate = Migrate(db=db) 31 | 32 | def __init__(self, app: Optional[Flask] = None): 33 | """Initializes the questionnaire object.""" 34 | self.app = app 35 | 36 | def init_app(self, app: Flask): 37 | self.app = app 38 | with self.app.app_context(): 39 | self.db.init_app(self.app) 40 | self.ma.init_app(self.app) 41 | self.migrate.init_app(self.app) 42 | 43 | # Create the database from all model definitions. 44 | # Note: This is a no-op if the tables already exist. 45 | # self.db.create_all() 46 | 47 | def reset_all(self): 48 | # Attention: This will drop the complete database with all its entries. 49 | self.db.drop_all() 50 | 51 | # Hack to remove all indices from the database... 52 | insp: reflection.Inspector = reflection.Inspector.from_engine(self.db.engine) 53 | table_names: Iterable[str] = insp.get_table_names() 54 | for name in table_names: 55 | indexes: Iterable[Dict[str, str]] = insp.get_indexes(name) 56 | for index in indexes: 57 | self.db.engine.execute(f"DROP INDEX IF EXISTS {index['name']}") 58 | self.app.logger.warning("!!! Attention !!! FLUSHED the main database.") 59 | 60 | # Create the database from all model definitions. 61 | self.db.create_all() 62 | 63 | self.db.session.commit() 64 | 65 | @property 66 | def session(self): 67 | return self.db.session 68 | 69 | def query(self, *args, **kwargs): 70 | return self.db.session.query(*args, **kwargs) 71 | 72 | 73 | DEFAULT_DATABASE = Database() 74 | 75 | 76 | def init_app(app: Flask): 77 | DEFAULT_DATABASE.init_app(app) 78 | -------------------------------------------------------------------------------- /data/models/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from data.utils import populate_models 16 | from data.models.user import User, InviteCode 17 | from data.models.vulnerability import ( 18 | RepositoryFileComments, 19 | RepositoryFileMarkers, 20 | RepositoryFiles, 21 | RepositoryFilesSchema, 22 | Vulnerability, 23 | VulnerabilityGitCommits, 24 | VulnerabilityResources, 25 | VulnerabilityState, 26 | Product, 27 | ) 28 | from data.models.nvd import Cpe, Description, Nvd, Reference, default_nvd_view_options 29 | 30 | __all__ = populate_models(__name__) 31 | -------------------------------------------------------------------------------- /data/models/cwe.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from sqlalchemy import Column, Text, String 16 | 17 | from data.models.base import CweBase 18 | from data.utils import populate_models 19 | 20 | 21 | class CweData(CweBase): 22 | __tablename__ = "cwe_data" 23 | 24 | cwe_id = Column(String(255), primary_key=True, index=True) 25 | cwe_name = Column(Text) 26 | 27 | 28 | # must be set after all definitions 29 | __all__ = populate_models(__name__) 30 | -------------------------------------------------------------------------------- /data/utils.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import sys 16 | import inspect 17 | 18 | from data.models.base import db, ma 19 | 20 | 21 | def populate_models(modname): 22 | mod = sys.modules.get(modname) 23 | names = [] 24 | if not mod: 25 | return names 26 | 27 | for name, clazz in inspect.getmembers(mod, inspect.isclass): 28 | # getattr can't be used here as it also looks into superclasses 29 | is_abstract = clazz.__dict__.get("__abstract__", False) 30 | if issubclass(clazz, (db.Model, ma.SQLAlchemyAutoSchema)) and not is_abstract: 31 | names.append(name) 32 | return names 33 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2019 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Deploy newest files to PROD. 17 | echo "Deploying to PROD." 18 | echo "Y" | gcloud app deploy 19 | echo "Done." -------------------------------------------------------------------------------- /deps/common_requirements.txt: -------------------------------------------------------------------------------- 1 | # Dependencies shared by multiple components like the frontend and version control system (VCS) prox 2 | Flask==2.0.1 3 | sqlakeyset==0.1.1559103842 4 | 5 | # Pin sqlalchemy until pytest-flask-sqlalchemy gets fully removed. 6 | # It's not well maintained and has compatibility issues with SQLAlchemy 1.4.x 7 | # Example: https://github.com/jeancochrane/pytest-flask-sqlalchemy/issues/46 is fixed 8 | # Potential workaround for the whole package is provided in 9 | # https://github.com/jeancochrane/pytest-flask-sqlalchemy/issues/46#issuecomment-829694672 10 | sqlalchemy<1.4 -------------------------------------------------------------------------------- /deps/dev_requirements.txt: -------------------------------------------------------------------------------- 1 | -r requirements.txt 2 | 3 | pylint 4 | black==21.5b1 5 | pyyaml 6 | pytest==5.2.0 7 | pytest-mock==1.11.0 8 | pytest-cov==2.7.1 9 | # security checks 10 | bandit==1.6.2 11 | # static type checks 12 | mypy==0.770 13 | mypy-extensions==0.4.3 14 | sqlalchemy-stubs==0.3 15 | # Used for crawl_patches. 16 | pandas==0.25.1 17 | # usability for flask shell 18 | flask-shell-ipython==0.4.1 19 | -------------------------------------------------------------------------------- /deps/requirements.txt: -------------------------------------------------------------------------------- 1 | -r common_requirements.txt 2 | 3 | # 'MySQLdb' dependency. 4 | mysqlclient==2.0.3 5 | # Main Flask related dependencies. 6 | Flask-Bootstrap==3.3.7.1 7 | flask-marshmallow==0.14.0 8 | Flask-Migrate==2.7.0 9 | Authlib==0.15.3 10 | Flask-SQLAlchemy==2.5.1 11 | # Not in use due to a problem when matching against multiple fulltext columns with a joined table. 12 | # SQLAlchemy-FullText-Search==0.2.5 13 | Flask-WTF==0.14.3 14 | marshmallow-sqlalchemy==0.25.0 15 | google-auth==1.23 16 | flask-bouncer==0.3.0 17 | bouncer==0.1.12 18 | # Flask-debugtoolbar requirements ------- 19 | flask-debugtoolbar==0.11.0 20 | setuptools==57.0.0 21 | sqlparse==0.3.0 22 | pygments==2.7.4 23 | colorama==0.4.4 24 | # Provides a WSGI werkzeug server alternative. 25 | #gevent==1.4.0 26 | # Required to make Flask's jsonify work with decimal numbers. 27 | simplejson==3.17.2 28 | # --------------------------------------- 29 | # Misc. requirements 30 | # GAE logging 31 | google-cloud-logging==2.0.0 32 | -------------------------------------------------------------------------------- /deps/vcs_requirements.txt: -------------------------------------------------------------------------------- 1 | -r common_requirements.txt 2 | 3 | # Dependencies for the version control system (VCS) proxy that serves source code from GitHub or Git repositories. 4 | dulwich>=0.19,<0.20 5 | gitpython==2.1.11 6 | PyGithub==1.40 7 | unidiff==0.5.5 8 | pyyaml -------------------------------------------------------------------------------- /docker/.dockerignore: -------------------------------------------------------------------------------- 1 | db-data/ -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | Build 2 | ----- 3 | The contained core Docker services (see `docker-compose.yml`) are: 4 | - vcs-proxy 5 | - database 6 | - frontend 7 | 8 | They can be built and started with: 9 | ``` 10 | $ cd docker 11 | $ docker-compose build 12 | $ docker-compose up 13 | ``` 14 | 15 | More 16 | --- 17 | Additional Docker services (see `docker-compose.admin.yml`) include: 18 | - go-cve-dictionary - Fetching of NVD and CWE data. 19 | - utils - Linting and formatting tools. 20 | - tests-db - Ephemeral (using tmpfs) MySQL instance for test data. 21 | - tests - Python runtime with relevant dependencies for test execution. 22 | 23 | You can interact with all above services through `docker-admin.sh`: 24 | ``` 25 | $ cd docker 26 | $ ./docker-admin.sh 27 | ``` 28 | This allows you to: 29 | - Load data: latest CVE updates, this year's CVE data, full CVE data and CWE data. 30 | - Execute unit tests contained in `/tests/`. 31 | - Execute `crawl_patches` which will create Vulncode-DB entries from given NVD entries. 32 | - Format the code with `eslint` and `yapf`. 33 | - Lint the code with `eslint` and `pylint`. 34 | - Get a shell inside a specific docker service. 35 | -------------------------------------------------------------------------------- /docker/cve-data/fetch_cwe.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # Copyright 2019 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | wget https://cwe.mitre.org/data/xml/views/2000.xml.zip 17 | unzip 2000.xml.zip 18 | perl -lne 'print $1 if /((?<= ID=").*?" Name=".*?(?="))/' 2000.xml | sed 's/" Name="/| /' | awk '{print "CWE-" $0}' > cwe.csv 19 | rm 2000.xml* 20 | echo "Created cwe.csv. Importing into database." 21 | while ! nc -z database 3306 ; do 22 | echo 'Waiting for database:3306...'; sleep 5; 23 | done; 24 | echo "load data local infile 'cwe.csv' into table cwe.cwe_data fields terminated by '|' lines terminated by '\n' (cwe_id, cwe_name)" | mysql --local-infile=1 -hdatabase -uroot -ppass 25 | echo "Done" 26 | -------------------------------------------------------------------------------- /docker/db_schema.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS main; 2 | CREATE DATABASE IF NOT EXISTS cve; 3 | CREATE DATABASE IF NOT EXISTS cwe; -------------------------------------------------------------------------------- /docker/docker-compose.admin.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | go-cve-dictionary: 4 | build: 5 | context: ../third_party/go-cve-dictionary 6 | dockerfile: ../../docker/go-cve-dictionary/Dockerfile 7 | image: go-cve-dictionary 8 | links: 9 | - "database" 10 | volumes: 11 | - ./cve-data/:/vuls 12 | - ./cve-data/logs:/var/log/vuls 13 | depends_on: 14 | - database 15 | # Uncomment if you prefer using a host database instead. 16 | #network_mode: "host" 17 | 18 | utils: 19 | build: 20 | context: .. 21 | dockerfile: ./docker/utils/Dockerfile 22 | image: utils 23 | volumes: 24 | - ../:/app 25 | 26 | tests-db: 27 | image: mysql:5.7 28 | command: --default-authentication-plugin=mysql_native_password --init-file /docker-entrypoint-initdb.d/db_schema.sql --character-set-server=utf8 --collation-server=utf8_general_ci 29 | tmpfs: 30 | - /var/lib/mysql:rw,noexec,nosuid,size=1024m 31 | volumes: 32 | - ./db_schema.sql:/docker-entrypoint-initdb.d/db_schema.sql 33 | - ../:/app 34 | restart: always 35 | environment: 36 | MYSQL_ROOT_PASSWORD: test_db_pass 37 | ports: 38 | - "127.0.0.1:3309:3306" 39 | expose: 40 | - "3306" 41 | 42 | tests: 43 | image: frontend 44 | # Wait for the database to be available before starting the tests. 45 | command: > 46 | bash -c "while ! (exec 6<>/dev/tcp/tests-db/3306) 2>/dev/null; do 47 | echo 'Waiting for tests-db:3306...'; sleep 5; 48 | done; 49 | bash /app/tests/run_integration_tests.sh" 50 | environment: 51 | MYSQL_HOST: tests-db 52 | COOKIE_SECRET_KEY: not-so-secret 53 | depends_on: 54 | - tests-db 55 | volumes: 56 | - ../:/app 57 | 58 | # TODO: This one is redundant to tests. Consider refactoring this. 59 | production_tests: 60 | image: frontend 61 | # Wait for the database to be available before starting the tests. 62 | command: > 63 | bash -c "while ! (exec 6<>/dev/tcp/tests-db/3306) 2>/dev/null; do 64 | echo 'Waiting for tests-db:3306...'; sleep 5; 65 | done; 66 | bash /app/tests/run_production_tests.sh" 67 | environment: 68 | MYSQL_HOST: tests-db 69 | COOKIE_SECRET_KEY: not-so-secret 70 | depends_on: 71 | - tests-db 72 | volumes: 73 | - ../:/app 74 | -------------------------------------------------------------------------------- /docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | vcs-proxy: 4 | build: 5 | context: .. 6 | dockerfile: ./docker/vcs_proxy/Dockerfile 7 | volumes: 8 | - ../:/app 9 | #- /etc/passwd:/etc/passwd:ro 10 | #- /etc/group:/etc/group:ro 11 | image: vcs-proxy 12 | #user: "${UID}:${GID}" 13 | # The VCS proxy will be reachable from your host on http://127.0.0.1:8088 14 | ports: 15 | - "8088:8088" 16 | 17 | database: 18 | image: mysql:latest 19 | command: --default-authentication-plugin=mysql_native_password --init-file /docker-entrypoint-initdb.d/db_schema.sql --character-set-server=utf8 --collation-server=utf8_general_ci 20 | volumes: 21 | - ./db-data/:/var/lib/mysql 22 | # Uncomment if you needs mysql logs. 23 | #- ./db-logs/:/logs 24 | - ./db_schema.sql:/docker-entrypoint-initdb.d/db_schema.sql 25 | restart: always 26 | environment: 27 | MYSQL_ROOT_PASSWORD: pass 28 | # Publishing mysql port as 3308 for debugging purposes. 29 | ports: 30 | - "127.0.0.1:3308:3306" 31 | expose: 32 | - "3306" 33 | 34 | frontend: 35 | build: 36 | context: .. 37 | dockerfile: ./docker/frontend/Dockerfile 38 | # Wait for the database to be available before starting the application. 39 | command: > 40 | bash -c "while ! (exec 6<>/dev/tcp/database/3306) 2>/dev/null; do 41 | echo 'Waiting for database:3306...'; sleep 5; 42 | done; 43 | bash /app/run.sh" 44 | volumes: 45 | - ../:/app 46 | #- /etc/passwd:/etc/passwd:ro 47 | #- /etc/group:/etc/group:ro 48 | environment: 49 | - MYSQL_HOST=database 50 | - VCS_PROXY_LOCAL_URL=https://vcs-proxy:8088/ 51 | #user: "${UID}:${GID}" 52 | depends_on: 53 | - vcs-proxy 54 | - database 55 | image: frontend 56 | links: 57 | - "vcs-proxy" 58 | - "database" 59 | # The main application will be reachable from your host on http://127.0.0.1:8080 60 | ports: 61 | - "8080:8080" 62 | 63 | -------------------------------------------------------------------------------- /docker/frontend/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7 2 | 3 | WORKDIR /app_setup 4 | COPY deps/common_requirements.txt /app_setup/ 5 | COPY deps/requirements.txt /app_setup/ 6 | COPY deps/vcs_requirements.txt /app_setup/ 7 | COPY deps/dev_requirements.txt /app_setup/ 8 | 9 | 10 | RUN apt-get -y install default-libmysqlclient-dev 11 | 12 | # Install dependencies. 13 | RUN pip3 install -r /app_setup/requirements.txt 14 | RUN pip3 install -r /app_setup/vcs_requirements.txt 15 | RUN pip3 install -r /app_setup/dev_requirements.txt 16 | 17 | # Used as a bind-mount by docker-compose. 18 | WORKDIR /app 19 | EXPOSE 8080/tcp 20 | 21 | #USER nobody:nogroup -------------------------------------------------------------------------------- /docker/go-cve-dictionary/Dockerfile: -------------------------------------------------------------------------------- 1 | # Based upon Dockerfile in version c2bcc418e037d6bc2d6b47c2d782900126b4f884: 2 | # https://github.com/kotakanbe/go-cve-dictionary/blob/c2bcc418e037d6bc2d6b47c2d782900126b4f884/Dockerfile 3 | FROM golang:alpine as builder 4 | RUN apk add --no-cache \ 5 | git \ 6 | make \ 7 | gcc \ 8 | musl-dev 9 | 10 | ENV REPOSITORY github.com/kotakanbe/go-cve-dictionary 11 | COPY . $GOPATH/src/$REPOSITORY 12 | RUN cd $GOPATH/src/$REPOSITORY && make install 13 | # && sed -i 's/static.nvd.nist.gov/nvd.nist.gov/' nvd/nvd.go 14 | 15 | FROM alpine:3.7 16 | RUN apk add --no-cache perl mysql-client 17 | MAINTAINER hikachan sadayuki-matsuno 18 | 19 | ENV LOGDIR /var/log/vuls 20 | ENV WORKDIR /vuls 21 | 22 | RUN apk add --no-cache ca-certificates \ 23 | && mkdir -p $WORKDIR $LOGDIR 24 | COPY --from=builder /go/bin/go-cve-dictionary /usr/local/bin/ 25 | 26 | WORKDIR $WORKDIR 27 | ENV PWD $WORKDIR 28 | 29 | -------------------------------------------------------------------------------- /docker/utils/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:alpine 2 | 3 | WORKDIR /app_setup 4 | # Install eslint dependencies. 5 | COPY package.json /app_setup/ 6 | RUN npm install 7 | # Make eslint and other utilities available by adjusting the PATH variable. 8 | ENV PATH="/app_setup/node_modules/.bin/:${PATH}" 9 | 10 | # Install yapf, plyint and other dependencies. 11 | RUN apk add --no-cache python3 bash build-base python3-dev 12 | #RUN python3 -m ensurepip 13 | #RUN pip3 install --upgrade pip 14 | RUN pip3 install black futures pylint bandit mypy sqlalchemy-stubs mypy-extensions marshmallow 15 | 16 | WORKDIR /app 17 | -------------------------------------------------------------------------------- /docker/vcs_proxy/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7 2 | 3 | WORKDIR /app_setup 4 | COPY deps/common_requirements.txt /app_setup/ 5 | COPY deps/vcs_requirements.txt /app_setup/ 6 | 7 | RUN pip3 install -r vcs_requirements.txt 8 | 9 | # Used as a bind-mount by docker-compose. 10 | WORKDIR /app 11 | EXPOSE 8088/tcp 12 | 13 | #RUN chown -R nobody:nogroup /proxy/* 14 | #USER nobody:nogroup 15 | # CMD ["/usr/local/bin/python", "-m", "/proxy/gce_vcs_proxy.py"] 16 | # Address weird werkzeug bug ("Restarting with stat" + can't import yaml module) with -m parameter. 17 | CMD ["/usr/local/bin/python", "-m", "gce_vcs_proxy"] 18 | -------------------------------------------------------------------------------- /example_app.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | runtime: python38 16 | 17 | handlers: 18 | - url: /static 19 | static_dir: static 20 | secure: always 21 | - url: /.* 22 | script: auto 23 | secure: always 24 | 25 | env_variables: 26 | # Replace all settings according to your local / qa / prod environment. 27 | 28 | # OAuth settings. 29 | GOOGLE_OAUTH_CONSUMER_KEY: '' 30 | GOOGLE_OAUTH_CONSUMER_SECRET: '' 31 | GITHUB_OAUTH_CONSUMER_KEY: '' 32 | GITHUB_OAUTH_CONSUMER_SECRET: '' 33 | 34 | # Site settings. 35 | CSRF_SESSION_KEY: 'secret' 36 | COOKIE_SECRET_KEY: 'secret' 37 | 38 | # Database settings for local. 39 | MYSQL_LOCAL_USER: 'root' 40 | MYSQL_LOCAL_PASS: 'pass' 41 | # Only specify the following if you are using a non-docker vcs-proxy. 42 | # VCS_PROXY_LOCAL_URL: 'https://127.0.0.1:8088/' 43 | # Enables connecting to the remote database using the cloud sql proxy. 44 | # Proxy CloudSQL with 45 | # ./cloud_sql_proxy -instances [MYSQL_CONNECTION_NAME]=tcp:3307 46 | # USE_REMOTE_DB_THROUGH_CLOUDSQL_PROXY: FALSE 47 | # CLOUDSQL_PORT: 3307 48 | # CLOUDSQL_NAME: '' 49 | # CLOUDSQL_PASS: '' 50 | 51 | # Database settings for qa. 52 | # QA_PROJECT_ID: '[PROJECT_ID]' 53 | # MYSQL_QA_USER: '' 54 | # MYSQL_QA_PASS: '' 55 | # This should have the form: [PROJECT_ID]:[AREA]:[PROJECT_NAME] 56 | # MYSQL_QA_CONNECTION_NAME: '' 57 | # VCS_PROXY_QA_URL: '' 58 | 59 | # Database settings for prod. 60 | # PROD_PROJECT_ID: '[PROJECT_ID]' 61 | # MYSQL_PROD_USER: '' 62 | # MYSQL_PROD_PASS: '' 63 | # This should have the form: [PROJECT_ID]:[AREA]:[PROJECT_NAME] 64 | # MYSQL_PROD_CONNECTION_NAME: '' 65 | # VCS_PROXY_PROD_URL: '' 66 | 67 | # Admin emails separated by ','. This is required to make permanent changes to the database. 68 | APPLICATION_ADMINS: 'user@gmail.com' 69 | 70 | # Restrict the login to administrators only. 71 | RESTRICT_LOGIN: True 72 | 73 | # Allow external registrations. Can be: 'INVITE_ONLY' (default), 'CLOSED' or 'OPEN'. 74 | # REGISTRATION_MODE: 'INVITE_ONLY' 75 | 76 | # Shows a warning as changes can only be stored permanently by admins. 77 | # DEMO_MODE: False 78 | # Show a "maintenance page". 79 | # MAINTENANCE_MODE: False 80 | -------------------------------------------------------------------------------- /example_vcs_proxy.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Set the following only if you have a dedicated production hostname. 16 | # PROD_HOSTNAME: example-host 17 | # You can setup a Github API access token to be used below. 18 | # GITHUB_API_ACCESS_TOKEN: SECRET_TOKEN -------------------------------------------------------------------------------- /format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2019 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | function info() { 18 | echo -e "[\033[94m*\033[0m]" "$@" 19 | } 20 | 21 | function error() { 22 | echo -e "[\033[91m!\033[0m]" "$@" 23 | } 24 | 25 | function success() { 26 | echo -e "[\033[92m+\033[0m]" "$@" 27 | } 28 | 29 | function fatal() { 30 | error "$@" 31 | exit 1 32 | } 33 | 34 | if npx eslint &>/dev/null 35 | then 36 | info 'Formatting *.js files.' 37 | npx eslint "**/*.js" --fix --quiet --ignore-path '.gitignore' --ignore-pattern 'static/monaco/' --ignore-pattern 'static/js/third_party' --debug 2>&1 > /dev/null | grep "Processing" | sed 's/^.*Processing\(.*\)$/Reformatting\1/' 38 | else 39 | error 'Please install eslint. Install node.js and run: npm install' 40 | fi 41 | 42 | if which black &>/dev/null 43 | then 44 | info 'Formatting python files with black' 45 | black app lib data tests migrations tools *.py || fatal 'Error during formatting python files' 46 | else 47 | fatal 'Please install black: pip3 install black' 48 | fi 49 | 50 | success "Done. Happy coding :)" 51 | -------------------------------------------------------------------------------- /lib/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /lib/vcs_handler/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from os.path import dirname, basename, isfile 16 | import glob 17 | 18 | __all__ = [ 19 | basename(f)[:-3] 20 | for f in glob.glob(dirname(__file__) + "/*.py") 21 | if isfile(f) and not f.endswith("__init__.py") 22 | ] 23 | -------------------------------------------------------------------------------- /lint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2019 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | function info() { 18 | echo -e "[\033[94m*\033[0m]" "$@" 19 | } 20 | 21 | function error() { 22 | echo -e "[\033[91m!\033[0m]" "$@" 23 | } 24 | 25 | function success() { 26 | echo -e "[\033[92m+\033[0m]" "$@" 27 | } 28 | 29 | function fatal() { 30 | error "$@" 31 | exit 1 32 | } 33 | 34 | failures=0 35 | 36 | if npx eslint &>/dev/null 37 | then 38 | info 'Linting *.js files with eslint' 39 | npx eslint **/*.js --ignore-path .gitignore 40 | else 41 | fatal 'Please install eslint. Install node.js and run: npm install' 42 | fi 43 | 44 | if which pylint &>/dev/null 45 | then 46 | info 'Linting python files with pylint' 47 | pylint --rcfile=./pylintrc --reports=no --disable=fixme *.py app data lib || failures=$(($failures+1)) 48 | else 49 | fatal 'Please install pylint' 50 | fi 51 | 52 | if which bandit &>/dev/null 53 | then 54 | info 'Checking python files with bandit' 55 | bandit -r app data lib || failures=$(($failures+1)) 56 | else 57 | fatal 'Please install bandit' 58 | fi 59 | 60 | if which mypy &>/dev/null 61 | then 62 | info 'Linting python files with mypy' 63 | mypy --warn-unused-ignores app data lib || failures=$(($failures+1)) 64 | else 65 | fatal 'Please install mypy' 66 | fi 67 | 68 | if [ $failures -gt 0 ] 69 | then 70 | fatal "Lint failed" 71 | fi 72 | success "Done. Happy coding :)" 73 | -------------------------------------------------------------------------------- /manage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2019 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | if ! which flask &>/dev/null 18 | then 19 | echo -e "\033[91mflask not found. Rerun this script within the virtual environment.\033[m" 20 | exit 1 21 | fi 22 | 23 | FLASK_APP=main flask "$@" 24 | -------------------------------------------------------------------------------- /migrations/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration. -------------------------------------------------------------------------------- /migrations/alembic.ini: -------------------------------------------------------------------------------- 1 | # A generic, single database configuration. 2 | 3 | [alembic] 4 | # template used to generate migration files 5 | # file_template = %%(rev)s_%%(slug)s 6 | 7 | # set to 'true' to run the environment during 8 | # the 'revision' command, regardless of autogenerate 9 | # revision_environment = false 10 | 11 | 12 | # Logging configuration 13 | [loggers] 14 | keys = root,sqlalchemy,alembic 15 | 16 | [handlers] 17 | keys = console 18 | 19 | [formatters] 20 | keys = generic 21 | 22 | [logger_root] 23 | level = WARN 24 | handlers = console 25 | qualname = 26 | 27 | [logger_sqlalchemy] 28 | level = WARN 29 | handlers = 30 | qualname = sqlalchemy.engine 31 | 32 | [logger_alembic] 33 | level = INFO 34 | handlers = 35 | qualname = alembic 36 | 37 | [handler_console] 38 | class = StreamHandler 39 | args = (sys.stderr,) 40 | level = NOTSET 41 | formatter = generic 42 | 43 | [formatter_generic] 44 | format = %(levelname)-5.5s [%(name)s] %(message)s 45 | datefmt = %H:%M:%S 46 | -------------------------------------------------------------------------------- /migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /migrations/versions/1af56ef5ac3c_user_states.py: -------------------------------------------------------------------------------- 1 | """user states 2 | 3 | Revision ID: 1af56ef5ac3c 4 | Revises: f02f9e75f973 5 | Create Date: 2020-08-28 12:38:34.134130 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = "1af56ef5ac3c" 14 | down_revision = "f02f9e75f973" 15 | branch_labels = None 16 | depends_on = None 17 | 18 | 19 | def upgrade(): 20 | # ### commands auto generated by Alembic - please adjust! ### 21 | op.add_column( 22 | "user", 23 | sa.Column( 24 | "state", 25 | sa.Enum("REGISTERED", "ACTIVE", "BLOCKED", name="userstate"), 26 | nullable=False, 27 | ), 28 | ) 29 | # ### end Alembic commands ### 30 | 31 | 32 | def downgrade(): 33 | # ### commands auto generated by Alembic - please adjust! ### 34 | op.drop_column("user", "state") 35 | # ### end Alembic commands ### 36 | -------------------------------------------------------------------------------- /migrations/versions/27a721daab2e_renamed_email_to_login_in_user_table.py: -------------------------------------------------------------------------------- 1 | """renamed email to login in user table 2 | 3 | Revision ID: 27a721daab2e 4 | Revises: 9d370f33f1a0 5 | Create Date: 2020-12-04 16:14:19.390278 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | from sqlalchemy.dialects import mysql 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = "27a721daab2e" 14 | down_revision = "9d370f33f1a0" 15 | branch_labels = None 16 | depends_on = None 17 | 18 | 19 | def upgrade(): 20 | # ### commands auto generated by Alembic - please adjust! ### 21 | op.alter_column( 22 | "user", 23 | "email", 24 | new_column_name="login", 25 | existing_type=sa.String(256), 26 | existing_nullable=False, 27 | ) 28 | # op.drop_index("email", table_name="user") 29 | # op.create_unique_constraint("user_login_uniq", "user", ["login"]) 30 | # op.drop_column("user", "email") 31 | # ### end Alembic commands ### 32 | 33 | 34 | def downgrade(): 35 | # ### commands auto generated by Alembic - please adjust! ### 36 | op.alter_column( 37 | "user", 38 | "login", 39 | new_column_name="email", 40 | existing_type=sa.String(256), 41 | existing_nullable=False, 42 | ) 43 | # op.add_column("user", sa.Column("email", mysql.VARCHAR(length=256), nullable=False)) 44 | # op.drop_constraint("user_login_uniq", "user", type_="unique") 45 | # op.create_index("email", "user", ["email"], unique=True) 46 | # op.drop_column("user", "login") 47 | # ### end Alembic commands ### 48 | -------------------------------------------------------------------------------- /migrations/versions/32ded3390554_adding_table_that_keeps_track_of_open_.py: -------------------------------------------------------------------------------- 1 | """Adding table that keeps track of open source products. 2 | 3 | Revision ID: 32ded3390554 4 | Revises: 82f8f48c6ee6 5 | Create Date: 2019-06-16 12:13:28.964876 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = "32ded3390554" 14 | down_revision = "82f8f48c6ee6" 15 | branch_labels = None 16 | depends_on = None 17 | 18 | 19 | def upgrade(): 20 | # ### commands auto generated by Alembic - please adjust! ### 21 | op.create_table( 22 | "oss_products", 23 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 24 | sa.Column("date_created", sa.DateTime(), nullable=True), 25 | sa.Column("date_modified", sa.DateTime(), nullable=True), 26 | sa.Column("vendor", sa.String(length=255), nullable=False), 27 | sa.Column("product", sa.String(length=255), nullable=False), 28 | sa.PrimaryKeyConstraint("id"), 29 | sa.UniqueConstraint("vendor", "product"), 30 | ) 31 | op.create_index( 32 | "idx_oss_products_main", "oss_products", ["vendor", "product"], unique=True 33 | ) 34 | # ### end Alembic commands ### 35 | 36 | 37 | def downgrade(): 38 | # ### commands auto generated by Alembic - please adjust! ### 39 | op.drop_index("idx_oss_products_main", table_name="oss_products") 40 | op.drop_table("oss_products") 41 | # ### end Alembic commands ### 42 | -------------------------------------------------------------------------------- /migrations/versions/4c879a183a73_makes_vulnerability_resources_fk_non_.py: -------------------------------------------------------------------------------- 1 | """Makes vulnerability_resources FK non-nullable. 2 | 3 | Revision ID: 4c879a183a73 4 | Revises: d694cd137157 5 | Create Date: 2020-10-16 07:28:50.893030 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = "4c879a183a73" 14 | down_revision = "d694cd137157" 15 | branch_labels = None 16 | depends_on = None 17 | 18 | 19 | def upgrade(): 20 | # Make sure the FK on vulnerability_resources can never be null. 21 | op.alter_column( 22 | "vulnerability_resources", 23 | "vulnerability_details_id", 24 | existing_type=sa.Integer(), 25 | nullable=False, 26 | ) 27 | 28 | 29 | def downgrade(): 30 | op.alter_column( 31 | "vulnerability_resources", 32 | "vulnerability_details_id", 33 | existing_type=sa.Integer(), 34 | nullable=True, 35 | ) 36 | -------------------------------------------------------------------------------- /migrations/versions/4d799bc13b95_pii_flags.py: -------------------------------------------------------------------------------- 1 | """pii flags 2 | 3 | Revision ID: 4d799bc13b95 4 | Revises: 1af56ef5ac3c 5 | Create Date: 2020-09-11 14:54:57.844887 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | 11 | # revision identifiers, used by Alembic. 12 | revision = "4d799bc13b95" 13 | down_revision = "1af56ef5ac3c" 14 | branch_labels = None 15 | depends_on = None 16 | 17 | 18 | def upgrade(): 19 | # ### commands auto generated by Alembic - please adjust! ### 20 | op.add_column( 21 | "user", sa.Column("hide_name", sa.Boolean(), nullable=False, default=True) 22 | ) 23 | op.add_column( 24 | "user", sa.Column("hide_picture", sa.Boolean(), nullable=False, default=True) 25 | ) 26 | # ### end Alembic commands ### 27 | 28 | 29 | def downgrade(): 30 | # ### commands auto generated by Alembic - please adjust! ### 31 | op.drop_column("user", "hide_picture") 32 | op.drop_column("user", "hide_name") 33 | # ### end Alembic commands ### 34 | -------------------------------------------------------------------------------- /migrations/versions/5dd1d09f15fe_adding_index_to_created_date_column_for_.py: -------------------------------------------------------------------------------- 1 | """Adding index to created_date column for the vulnerability table and pubished_date for the nvd_jsons table. 2 | 3 | Revision ID: 5dd1d09f15fe 4 | Revises: 32ded3390554 5 | Create Date: 2019-07-03 18:21:52.819263 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = "5dd1d09f15fe" 14 | down_revision = "32ded3390554" 15 | branch_labels = None 16 | depends_on = None 17 | 18 | 19 | def upgrade(): 20 | # ### commands auto generated by Alembic - please adjust! ### 21 | op.create_index( 22 | op.f("ix_vulnerability_date_created"), 23 | "vulnerability", 24 | ["date_created"], 25 | unique=False, 26 | ) 27 | op.create_index( 28 | "idx_nvd_jsons_published_date", 29 | "nvd_jsons", 30 | ["published_date"], 31 | unique=False, 32 | schema="cve", 33 | ) 34 | # ### end Alembic commands ### 35 | 36 | 37 | def downgrade(): 38 | # ### commands auto generated by Alembic - please adjust! ### 39 | op.drop_index("idx_nvd_jsons_published_date", table_name="nvd_jsons", schema="cve") 40 | op.drop_index(op.f("ix_vulnerability_date_created"), table_name="vulnerability") 41 | # ### end Alembic commands ### 42 | -------------------------------------------------------------------------------- /migrations/versions/6704686720fa_invite_codes.py: -------------------------------------------------------------------------------- 1 | """invite codes 2 | 3 | Revision ID: 6704686720fa 4 | Revises: c77061c72a59 5 | Create Date: 2020-11-06 13:17:45.111761 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | 11 | # revision identifiers, used by Alembic. 12 | revision = "6704686720fa" 13 | down_revision = "c77061c72a59" 14 | branch_labels = None 15 | depends_on = None 16 | 17 | 18 | def upgrade(): 19 | # ### commands auto generated by Alembic - please adjust! ### 20 | op.create_table( 21 | "invite_code", 22 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 23 | sa.Column("date_created", sa.DateTime(), nullable=True), 24 | sa.Column("date_modified", sa.DateTime(), nullable=True), 25 | sa.Column("code", sa.String(length=36), nullable=False), 26 | sa.Column("description", sa.String(length=255), nullable=False), 27 | sa.Column("remaining_uses", sa.Integer(), nullable=False), 28 | sa.PrimaryKeyConstraint("id"), 29 | ) 30 | op.create_index(op.f("ix_invite_code_code"), "invite_code", ["code"], unique=True) 31 | op.create_table( 32 | "invite_role", 33 | sa.Column("invite_id", sa.Integer(), nullable=False), 34 | sa.Column("role_id", sa.Integer(), nullable=False), 35 | sa.ForeignKeyConstraint( 36 | ["invite_id"], 37 | ["invite_code.id"], 38 | ), 39 | sa.ForeignKeyConstraint( 40 | ["role_id"], 41 | ["role.id"], 42 | ), 43 | sa.PrimaryKeyConstraint("invite_id", "role_id"), 44 | ) 45 | op.add_column("user", sa.Column("invite_code_id", sa.Integer(), nullable=True)) 46 | op.create_foreign_key( 47 | "user_ibfk_1", "user", "invite_code", ["invite_code_id"], ["id"] 48 | ) 49 | # ### end Alembic commands ### 50 | 51 | 52 | def downgrade(): 53 | # ### commands auto generated by Alembic - please adjust! ### 54 | op.drop_constraint("user_ibfk_1", "user", type_="foreignkey") 55 | op.drop_column("user", "invite_code_id") 56 | op.drop_table("invite_role") 57 | op.drop_index(op.f("ix_invite_code_code"), table_name="invite_code") 58 | op.drop_table("invite_code") 59 | # ### end Alembic commands ### 60 | -------------------------------------------------------------------------------- /migrations/versions/6a577b4c41fe_new_user_state.py: -------------------------------------------------------------------------------- 1 | """new user state 2 | 3 | Revision ID: 6a577b4c41fe 4 | Revises: 6704686720fa 5 | Create Date: 2020-11-24 13:13:25.967425 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | 11 | # revision identifiers, used by Alembic. 12 | revision = "6a577b4c41fe" 13 | down_revision = "6704686720fa" 14 | branch_labels = None 15 | depends_on = None 16 | 17 | 18 | def upgrade(): 19 | op.alter_column( 20 | "user", 21 | "state", 22 | existing_type=sa.Enum("REGISTERED", "ACTIVE", "BLOCKED", name="userstate"), 23 | type_=sa.Enum( 24 | "REGISTERED", "ACTIVE", "BLOCKED", "FIRST_LOGIN", name="userstate" 25 | ), 26 | ) 27 | 28 | 29 | def downgrade(): 30 | op.alter_column( 31 | "user", 32 | "state", 33 | type_=sa.Enum("REGISTERED", "ACTIVE", "BLOCKED", name="userstate"), 34 | existing_type=sa.Enum( 35 | "REGISTERED", "ACTIVE", "BLOCKED", "FIRST_LOGIN", name="userstate" 36 | ), 37 | ) 38 | -------------------------------------------------------------------------------- /migrations/versions/8696079cdbfc_removes_redundant_index_from_oss_.py: -------------------------------------------------------------------------------- 1 | """Removes redundant index from oss_products. 2 | 3 | Revision ID: 8696079cdbfc 4 | Revises: 5dd1d09f15fe 5 | Create Date: 2019-07-27 18:36:47.280273 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = "8696079cdbfc" 14 | down_revision = "5dd1d09f15fe" 15 | branch_labels = None 16 | depends_on = None 17 | 18 | 19 | def upgrade(): 20 | # ### commands auto generated by Alembic - please adjust! ### 21 | op.drop_index("vendor", table_name="oss_products") 22 | op.create_index( 23 | "idx_cpe_vendor_product", 24 | "cpes", 25 | ["vendor", "product"], 26 | unique=False, 27 | schema="cve", 28 | ) 29 | # ### end Alembic commands ### 30 | 31 | 32 | def downgrade(): 33 | # ### commands auto generated by Alembic - please adjust! ### 34 | op.create_index("vendor", "oss_products", ["vendor", "product"], unique=True) 35 | op.drop_index("idx_cpe_vendor_product", table_name="cpes", schema="cve") 36 | # ### end Alembic commands ### 37 | -------------------------------------------------------------------------------- /migrations/versions/9a935d8fb960_updating_the_index_over_cpe_to_cover_.py: -------------------------------------------------------------------------------- 1 | """Updating the index over CPE to cover nvd_json_id to speed up product lookups using index-only scans. 2 | 3 | Revision ID: 9a935d8fb960 4 | Revises: 8696079cdbfc 5 | Create Date: 2019-08-01 11:48:42.277952 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = "9a935d8fb960" 14 | down_revision = "8696079cdbfc" 15 | branch_labels = None 16 | depends_on = None 17 | 18 | 19 | def upgrade(): 20 | # ### commands auto generated by Alembic - please adjust! ### 21 | op.create_index( 22 | "idx_cpe_product_lookup", 23 | "cpes", 24 | ["vendor", "product", "nvd_json_id"], 25 | unique=False, 26 | schema="cve", 27 | ) 28 | op.drop_index("idx_cpe_vendor_product", table_name="cpes", schema="cve") 29 | # ### end Alembic commands ### 30 | 31 | 32 | def downgrade(): 33 | # ### commands auto generated by Alembic - please adjust! ### 34 | op.create_index( 35 | "idx_cpe_vendor_product", 36 | "cpes", 37 | ["vendor", "product"], 38 | unique=False, 39 | schema="cve", 40 | ) 41 | op.drop_index("idx_cpe_product_lookup", table_name="cpes", schema="cve") 42 | # ### end Alembic commands ### 43 | -------------------------------------------------------------------------------- /migrations/versions/9d370f33f1a0_user_login_types.py: -------------------------------------------------------------------------------- 1 | """user login types 2 | 3 | Revision ID: 9d370f33f1a0 4 | Revises: 6a577b4c41fe 5 | Create Date: 2020-11-30 12:58:31.046646 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | from sqlalchemy.dialects import mysql 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = "9d370f33f1a0" 14 | down_revision = "6a577b4c41fe" 15 | branch_labels = None 16 | depends_on = None 17 | 18 | 19 | def upgrade(): 20 | # ### commands auto generated by Alembic - please adjust! ### 21 | op.add_column( 22 | "user", 23 | sa.Column( 24 | "login_type", 25 | sa.Enum("LOCAL", "GOOGLE", "GITHUB", name="logintype"), 26 | nullable=True, 27 | ), 28 | ) 29 | # ### end Alembic commands ### 30 | 31 | 32 | def downgrade(): 33 | # ### commands auto generated by Alembic - please adjust! ### 34 | op.drop_column("user", "login_type") 35 | # ### end Alembic commands ### 36 | -------------------------------------------------------------------------------- /migrations/versions/c10e1faccb1c_adds_a_distinct_vulnerbility_table_.py: -------------------------------------------------------------------------------- 1 | """Adds a distinct vulnerbility table column for keeping track of the initial review_feedback reviewer. 2 | 3 | Revision ID: c10e1faccb1c 4 | Revises: fb11cb6a2398 5 | Create Date: 2020-10-03 09:50:58.363062 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = "c10e1faccb1c" 14 | down_revision = "fb11cb6a2398" 15 | branch_labels = None 16 | depends_on = None 17 | 18 | 19 | def upgrade(): 20 | # ### commands auto generated by Alembic - please adjust! ### 21 | op.add_column( 22 | "vulnerability", sa.Column("feedback_reviewer_id", sa.Integer(), nullable=True) 23 | ) 24 | op.create_foreign_key( 25 | "fk_feedback_reviewer_id", 26 | "vulnerability", 27 | "user", 28 | ["feedback_reviewer_id"], 29 | ["id"], 30 | ) 31 | # ### end Alembic commands ### 32 | 33 | 34 | def downgrade(): 35 | # ### commands auto generated by Alembic - please adjust! ### 36 | op.drop_constraint("fk_feedback_reviewer_id", "vulnerability", type_="foreignkey") 37 | op.drop_column("vulnerability", "feedback_reviewer_id") 38 | # ### end Alembic commands ### 39 | -------------------------------------------------------------------------------- /migrations/versions/c77061c72a59_products.py: -------------------------------------------------------------------------------- 1 | """products 2 | 3 | Revision ID: c77061c72a59 4 | Revises: 4c879a183a73 5 | Create Date: 2020-10-30 17:03:42.379504 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | from sqlalchemy.dialects import mysql 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = "c77061c72a59" 14 | down_revision = "4c879a183a73" 15 | branch_labels = None 16 | depends_on = None 17 | 18 | 19 | def upgrade(): 20 | # ### commands auto generated by Alembic - please adjust! ### 21 | op.create_table( 22 | "product", 23 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 24 | sa.Column("date_created", sa.DateTime(), nullable=True), 25 | sa.Column("date_modified", sa.DateTime(), nullable=True), 26 | sa.Column("vendor", sa.String(length=255), nullable=False), 27 | sa.Column("product", sa.String(length=255), nullable=False), 28 | sa.Column("is_open_source", sa.Boolean(), nullable=True), 29 | sa.PrimaryKeyConstraint("id"), 30 | ) 31 | op.create_index("idx_product_main", "product", ["vendor", "product"], unique=True) 32 | op.create_table( 33 | "vulnerable_products", 34 | sa.Column("vuln_id", sa.Integer(), nullable=False), 35 | sa.Column("product_id", sa.Integer(), nullable=False), 36 | sa.ForeignKeyConstraint( 37 | ["product_id"], 38 | ["product.id"], 39 | ), 40 | sa.ForeignKeyConstraint( 41 | ["vuln_id"], 42 | ["vulnerability.id"], 43 | ), 44 | sa.PrimaryKeyConstraint("vuln_id", "product_id"), 45 | ) 46 | op.drop_index("idx_oss_products_main", table_name="oss_products") 47 | op.drop_table("oss_products") 48 | # ### end Alembic commands ### 49 | 50 | 51 | def downgrade(): 52 | # ### commands auto generated by Alembic - please adjust! ### 53 | op.create_table( 54 | "oss_products", 55 | sa.Column("id", mysql.INTEGER(), autoincrement=True, nullable=False), 56 | sa.Column("date_created", mysql.DATETIME(), nullable=True), 57 | sa.Column("date_modified", mysql.DATETIME(), nullable=True), 58 | sa.Column("vendor", mysql.VARCHAR(length=255), nullable=False), 59 | sa.Column("product", mysql.VARCHAR(length=255), nullable=False), 60 | sa.PrimaryKeyConstraint("id"), 61 | mysql_default_charset="utf8", 62 | mysql_engine="InnoDB", 63 | ) 64 | op.create_index( 65 | "idx_oss_products_main", "oss_products", ["vendor", "product"], unique=True 66 | ) 67 | op.drop_table("vulnerable_products") 68 | op.drop_index("idx_product_main", table_name="product") 69 | op.drop_table("product") 70 | # ### end Alembic commands ### 71 | -------------------------------------------------------------------------------- /migrations/versions/d694cd137157_re_establishes_the_foreign_key_between_.py: -------------------------------------------------------------------------------- 1 | """Re-establishes the foreign key between vulnerability_resources and the vulnerability table. 2 | 3 | Revision ID: d694cd137157 4 | Revises: c10e1faccb1c 5 | Create Date: 2020-10-13 20:58:13.244989 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = "d694cd137157" 14 | down_revision = "c10e1faccb1c" 15 | branch_labels = None 16 | depends_on = None 17 | 18 | 19 | def upgrade(): 20 | # ### commands auto generated by Alembic - please adjust! ### 21 | op.add_column( 22 | "vulnerability_resources", 23 | sa.Column("vulnerability_details_id", sa.Integer(), nullable=True), 24 | ) 25 | op.create_foreign_key( 26 | None, 27 | "vulnerability_resources", 28 | "vulnerability", 29 | ["vulnerability_details_id"], 30 | ["id"], 31 | ) 32 | # ### end Alembic commands ### 33 | 34 | 35 | def downgrade(): 36 | # ### commands auto generated by Alembic - please adjust! ### 37 | op.drop_constraint(None, "vulnerability_resources", type_="foreignkey") 38 | op.drop_column("vulnerability_resources", "vulnerability_details_id") 39 | # ### end Alembic commands ### 40 | -------------------------------------------------------------------------------- /migrations/versions/f02f9e75f973_user_roles.py: -------------------------------------------------------------------------------- 1 | """user roles 2 | 3 | Revision ID: f02f9e75f973 4 | Revises: 13b73f6d1082 5 | Create Date: 2020-06-12 21:54:20.905401 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | from sqlalchemy.dialects import mysql 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = "f02f9e75f973" 14 | down_revision = "13b73f6d1082" 15 | branch_labels = None 16 | depends_on = None 17 | 18 | 19 | def upgrade(): 20 | # ### commands auto generated by Alembic - please adjust! ### 21 | op.create_table( 22 | "role", 23 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 24 | sa.Column("date_created", sa.DateTime(), nullable=True), 25 | sa.Column("date_modified", sa.DateTime(), nullable=True), 26 | sa.Column("name", sa.String(length=256), nullable=False), 27 | sa.PrimaryKeyConstraint("id"), 28 | sa.UniqueConstraint("name"), 29 | ) 30 | op.create_table( 31 | "user_role", 32 | sa.Column("role_id", sa.Integer(), nullable=False), 33 | sa.Column("user_id", sa.Integer(), nullable=False), 34 | sa.ForeignKeyConstraint( 35 | ["role_id"], 36 | ["role.id"], 37 | ), 38 | sa.ForeignKeyConstraint( 39 | ["user_id"], 40 | ["user.id"], 41 | ), 42 | sa.PrimaryKeyConstraint("role_id", "user_id"), 43 | ) 44 | op.alter_column( 45 | "user", "email", existing_type=mysql.VARCHAR(length=256), nullable=False 46 | ) 47 | # ### end Alembic commands ### 48 | 49 | 50 | def downgrade(): 51 | # ### commands auto generated by Alembic - please adjust! ### 52 | op.alter_column( 53 | "user", "email", existing_type=mysql.VARCHAR(length=256), nullable=True 54 | ) 55 | op.drop_table("user_role") 56 | op.drop_table("role") 57 | # ### end Alembic commands ### 58 | -------------------------------------------------------------------------------- /migrations/versions/fb11cb6a2398_updating_review_state_machine_to_.py: -------------------------------------------------------------------------------- 1 | """Updating review state machine to include NEEDS_IMPROVEMENT state. 2 | 3 | Revision ID: fb11cb6a2398 4 | Revises: 4d799bc13b95 5 | Create Date: 2020-09-13 11:03:39.400868 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = "fb11cb6a2398" 14 | down_revision = "4d799bc13b95" 15 | branch_labels = None 16 | depends_on = None 17 | 18 | 19 | def upgrade(): 20 | op.alter_column( 21 | table_name="vulnerability", 22 | column_name="state", 23 | type_=sa.Enum( 24 | "NEW", 25 | "NEEDS_IMPROVEMENT", 26 | "READY", 27 | "IN_REVIEW", 28 | "REVIEWED", 29 | "PUBLISHED", 30 | "ARCHIVED", 31 | name="vulnerabilitystate", 32 | ), 33 | nullable=False, 34 | ) 35 | 36 | 37 | def downgrade(): 38 | op.alter_column( 39 | table_name="vulnerability", 40 | column_name="state", 41 | type_=sa.Enum( 42 | "NEW", 43 | "READY", 44 | "IN_REVIEW", 45 | "REVIEWED", 46 | "PUBLISHED", 47 | "ARCHIVED", 48 | name="vulnerabilitystate", 49 | ), 50 | nullable=False, 51 | ) 52 | -------------------------------------------------------------------------------- /mypy.ini: -------------------------------------------------------------------------------- 1 | [mypy] 2 | plugins = sqlmypy 3 | warn_unused_configs = True 4 | allow_redefinition = True 5 | allow_untyped_globals = True 6 | pretty = True 7 | show_error_codes = True 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vulncode-db", 3 | "version": "1.0.0", 4 | "description": "[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)", 5 | "main": ".eslintrc.js", 6 | "directories": { 7 | "lib": "lib" 8 | }, 9 | "dependencies": { 10 | "eslint-config-google": "^0.12.0", 11 | "eslint": "^5.14.1" 12 | }, 13 | "devDependencies": {}, 14 | "scripts": { 15 | "test": "echo \"Error: no test specified\" && exit 1" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "" 20 | }, 21 | "author": "", 22 | "license": "" 23 | } 24 | -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | markers = 3 | integration: mark test to run only in integration tests 4 | production: mark test which can be run against the production system 5 | mocked-sessions = 6 | data.models.base.db.session 7 | ; data.database.DEFAULT_DATABASE.db.session 8 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | -r deps/requirements.txt -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2019 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | function info() { 17 | echo -e "[\033[94m*\033[0m]" "$@" 18 | } 19 | 20 | if [[ ! -d "migrations/versions" || ! $(ls -A migrations/versions) ]]; then 21 | info "Initializing the database with Alembic. Attention: Alembic will likely not reflect all details of the database." 22 | info "Please make sure to check the migrations/versions/[revision_hash].py against the model definitions in" 23 | info "data/models/*.py" 24 | ./manage.sh db init 25 | ./manage.sh db migrate 26 | ./manage.sh db upgrade 27 | fi 28 | 29 | if [[ $(./manage.sh db current 2>/dev/null | wc -l) -lt 2 ]]; then 30 | info "Initializing application database to newest version." 31 | ./manage.sh db upgrade 32 | fi 33 | 34 | python3 -c "import main; main.check_db_state()" || exit 1 35 | 36 | if which dev_appserver.py &>/dev/null 37 | then 38 | # Use Google's cloud SDK to start this with a local AppEngine instance. 39 | dev_appserver.py "$@" app.yaml 40 | # Optionally, you can start the server under a different port with: 41 | # dev_appserver.py --port=8090 --admin_port=8089 app.yaml 42 | else 43 | # Start without GAE support. 44 | python3 -m main 45 | fi 46 | -------------------------------------------------------------------------------- /static/css/third_party/jstree/32px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/vulncode-db/d7ca0bda764c4011e49a1d88a89b31d2f9aa32c8/static/css/third_party/jstree/32px.png -------------------------------------------------------------------------------- /static/css/third_party/jstree/40px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/vulncode-db/d7ca0bda764c4011e49a1d88a89b31d2f9aa32c8/static/css/third_party/jstree/40px.png -------------------------------------------------------------------------------- /static/css/third_party/jstree/throbber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/vulncode-db/d7ca0bda764c4011e49a1d88a89b31d2f9aa32c8/static/css/third_party/jstree/throbber.gif -------------------------------------------------------------------------------- /static/css/tutorial.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #tutorial-backdrop { 18 | position: fixed; 19 | width: 100%; 20 | height: 100%; 21 | top: 0px; 22 | left: 0px; 23 | background-color: rgba(0,0,0,0.33); 24 | pointer-events: none; 25 | z-index: 2000; 26 | } 27 | 28 | #tutorial-menu { 29 | background-color: #55e; 30 | z-index: 2100; 31 | } 32 | #tutorial-menu ul { 33 | list-style-type: none; 34 | margin: 0px; 35 | } 36 | #tutorial-menu ul li { 37 | border-bottom: 1px solid black; 38 | color: white; 39 | padding: 0.2em; 40 | } 41 | #tutorial-menu ul li:hover { 42 | background-color: white; 43 | color: #55e; 44 | } 45 | 46 | .tutorial-highlight { 47 | /* display:inline-block;*/ 48 | position:relative; 49 | /* z-index: 2000; */ 50 | /* box-shadow: 0px 0px 0px 9999px rgba(0,0,0,.33); */ 51 | /* z-index: 100; */ 52 | } 53 | .tutorial-highlight:after { 54 | content: ''; 55 | position: absolute; 56 | top:0; 57 | left:0; 58 | width: 100%; 59 | height: 100%; 60 | box-shadow: 0px 0px 0px 9999px rgba(0,0,0,.33); 61 | pointer-events: none; 62 | } 63 | 64 | #tutorial-text { 65 | z-index: 2000; 66 | padding: 1em; 67 | border-radius: 5px; 68 | position: fixed; 69 | background-color: white; 70 | } 71 | 72 | #tutorial-toolbar { 73 | position: fixed; 74 | bottom: 0px; 75 | left: 0px; 76 | background-color: white; 77 | border: 1px solid black; 78 | } 79 | -------------------------------------------------------------------------------- /static/css/webfonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/vulncode-db/d7ca0bda764c4011e49a1d88a89b31d2f9aa32c8/static/css/webfonts/fa-brands-400.eot -------------------------------------------------------------------------------- /static/css/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/vulncode-db/d7ca0bda764c4011e49a1d88a89b31d2f9aa32c8/static/css/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /static/css/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/vulncode-db/d7ca0bda764c4011e49a1d88a89b31d2f9aa32c8/static/css/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /static/css/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/vulncode-db/d7ca0bda764c4011e49a1d88a89b31d2f9aa32c8/static/css/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /static/css/webfonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/vulncode-db/d7ca0bda764c4011e49a1d88a89b31d2f9aa32c8/static/css/webfonts/fa-regular-400.eot -------------------------------------------------------------------------------- /static/css/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/vulncode-db/d7ca0bda764c4011e49a1d88a89b31d2f9aa32c8/static/css/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /static/css/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/vulncode-db/d7ca0bda764c4011e49a1d88a89b31d2f9aa32c8/static/css/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /static/css/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/vulncode-db/d7ca0bda764c4011e49a1d88a89b31d2f9aa32c8/static/css/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /static/css/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/vulncode-db/d7ca0bda764c4011e49a1d88a89b31d2f9aa32c8/static/css/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /static/css/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/vulncode-db/d7ca0bda764c4011e49a1d88a89b31d2f9aa32c8/static/css/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /static/css/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/vulncode-db/d7ca0bda764c4011e49a1d88a89b31d2f9aa32c8/static/css/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /static/css/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/vulncode-db/d7ca0bda764c4011e49a1d88a89b31d2f9aa32c8/static/css/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /static/js/lib/Constants.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export const ERROR_MARKER_CLASS = 'errorMarker'; 18 | export const MARKER_HIGHLIGHT_CLASS = 'highlightMarker'; 19 | export const IRRELEVANT_MARKER_CLASS = 'irrelevantMarker'; 20 | export const PATCHED_NODE_CLASS = 'patched_node_class'; 21 | export const VULNERABLE_NODE_CLASS = 'vulnerable_node_class'; 22 | export const VULNERABLE_MARKER_CLASS = 'vulnerableMarker'; 23 | export const SECTION_MARKER_CLASS = 'sectionMarker'; 24 | 25 | 26 | // Go into view only mode if no valid editor URL is present. 27 | export const EDIT_MODE_ACTIVE = window.location.href.includes('/editor'); 28 | -------------------------------------------------------------------------------- /static/js/lib/FileComment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | class FileComment { 18 | constructor( 19 | file, rowFrom, rowTo, text, sortPos = -1, creator = null, 20 | revision = 0) { 21 | this.file = file; 22 | this.row_from = rowFrom; 23 | this.row_to = rowTo; 24 | this.text = text; 25 | this.sort_pos = sortPos; 26 | this.creator = creator; 27 | this.revision = revision; 28 | this.raw_widget = null; 29 | this.raw_section_marker = null; 30 | this.raw_sortable = null; 31 | } 32 | } 33 | 34 | export {FileComment}; 35 | -------------------------------------------------------------------------------- /static/js/lib/FileMarker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | class FileMarker { 18 | constructor( 19 | file, markerClass, rowFrom, rowTo, columnFrom = 0, columnTo = 0) { 20 | this.file = file; 21 | this.class = markerClass; 22 | this.row_from = rowFrom; 23 | this.row_to = rowTo; 24 | this.column_from = columnFrom; 25 | this.column_to = columnTo; 26 | this.raw = null; 27 | } 28 | 29 | set annotation(newAnnotation) { 30 | this._annotation = newAnnotation; 31 | } 32 | 33 | Serialize() { 34 | const data = [ 35 | this.class, this.row_from, this.row_to, this.column_from, this.column_to, 36 | ]; 37 | return data.join('|'); 38 | } 39 | } 40 | 41 | export {FileMarker}; 42 | -------------------------------------------------------------------------------- /static/logos/GitHub-Mark-120px-plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/vulncode-db/d7ca0bda764c4011e49a1d88a89b31d2f9aa32c8/static/logos/GitHub-Mark-120px-plus.png -------------------------------------------------------------------------------- /static/logos/GitHub-Mark-32px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/vulncode-db/d7ca0bda764c4011e49a1d88a89b31d2f9aa32c8/static/logos/GitHub-Mark-32px.png -------------------------------------------------------------------------------- /static/logos/GitHub-Mark-64px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/vulncode-db/d7ca0bda764c4011e49a1d88a89b31d2f9aa32c8/static/logos/GitHub-Mark-64px.png -------------------------------------------------------------------------------- /static/monaco/min/vs/base/browser/ui/codiconLabel/codicon/codicon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/vulncode-db/d7ca0bda764c4011e49a1d88a89b31d2f9aa32c8/static/monaco/min/vs/base/browser/ui/codiconLabel/codicon/codicon.ttf -------------------------------------------------------------------------------- /static/monaco/min/vs/basic-languages/azcli/azcli.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * monaco-languages version: 1.10.0(1b4729c63bdb0d1e06d4e637e5c3977ddeb714dd) 4 | * Released under the MIT license 5 | * https://github.com/Microsoft/monaco-languages/blob/master/LICENSE.md 6 | *-----------------------------------------------------------------------------*/ 7 | define("vs/basic-languages/azcli/azcli",["require","exports"],(function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.conf={comments:{lineComment:"#"}},t.language={defaultToken:"keyword",ignoreCase:!0,tokenPostfix:".azcli",str:/[^#\s]/,tokenizer:{root:[{include:"@comment"},[/\s-+@str*\s*/,{cases:{"@eos":{token:"key.identifier",next:"@popall"},"@default":{token:"key.identifier",next:"@type"}}}],[/^-+@str*\s*/,{cases:{"@eos":{token:"key.identifier",next:"@popall"},"@default":{token:"key.identifier",next:"@type"}}}]],type:[{include:"@comment"},[/-+@str*\s*/,{cases:{"@eos":{token:"key.identifier",next:"@popall"},"@default":"key.identifier"}}],[/@str+\s*/,{cases:{"@eos":{token:"string",next:"@popall"},"@default":"string"}}]],comment:[[/#.*$/,{cases:{"@eos":{token:"comment",next:"@popall"}}}]]}}})); -------------------------------------------------------------------------------- /static/monaco/min/vs/basic-languages/bat/bat.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * monaco-languages version: 1.10.0(1b4729c63bdb0d1e06d4e637e5c3977ddeb714dd) 4 | * Released under the MIT license 5 | * https://github.com/Microsoft/monaco-languages/blob/master/LICENSE.md 6 | *-----------------------------------------------------------------------------*/ 7 | define("vs/basic-languages/bat/bat",["require","exports"],(function(e,s){"use strict";Object.defineProperty(s,"__esModule",{value:!0}),s.conf={comments:{lineComment:"REM"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'}],surroundingPairs:[{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'}],folding:{markers:{start:new RegExp("^\\s*(::\\s*|REM\\s+)#region"),end:new RegExp("^\\s*(::\\s*|REM\\s+)#endregion")}}},s.language={defaultToken:"",ignoreCase:!0,tokenPostfix:".bat",brackets:[{token:"delimiter.bracket",open:"{",close:"}"},{token:"delimiter.parenthesis",open:"(",close:")"},{token:"delimiter.square",open:"[",close:"]"}],keywords:/call|defined|echo|errorlevel|exist|for|goto|if|pause|set|shift|start|title|not|pushd|popd/,symbols:/[=>"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"<",close:">"},{open:"'",close:"'"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"<",close:">"},{open:"'",close:"'"}]},t.language={defaultToken:"",tokenPostfix:".cameligo",ignoreCase:!0,brackets:[{open:"{",close:"}",token:"delimiter.curly"},{open:"[",close:"]",token:"delimiter.square"},{open:"(",close:")",token:"delimiter.parenthesis"},{open:"<",close:">",token:"delimiter.angle"}],keywords:["abs","begin","Bytes","Crypto","Current","else","end","failwith","false","fun","if","in","let","let%entry","let%init","List","list","Map","map","match","match%nat","mod","not","operation","Operation","of","Set","set","sender","source","String","then","true","type","with"],typeKeywords:["int","unit","string","tz"],operators:["=",">","<","<=",">=","<>",":",":=","and","mod","or","+","-","*","/","@","&","^","%","->","<-"],symbols:/[=><:@\^&|+\-*\/\^%]+/,tokenizer:{root:[[/[a-zA-Z_][\w]*/,{cases:{"@keywords":{token:"keyword.$0"},"@default":"identifier"}}],{include:"@whitespace"},[/[{}()\[\]]/,"@brackets"],[/[<>](?!@symbols)/,"@brackets"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/\d*\.\d+([eE][\-+]?\d+)?/,"number.float"],[/\$[0-9a-fA-F]{1,16}/,"number.hex"],[/\d+/,"number"],[/[;,.]/,"delimiter"],[/'([^'\\]|\\.)*$/,"string.invalid"],[/'/,"string","@string"],[/'[^\\']'/,"string"],[/'/,"string.invalid"],[/\#\d+/,"string"]],comment:[[/[^\(\*]+/,"comment"],[/\*\)/,"comment","@pop"],[/\(\*/,"comment"]],string:[[/[^\\']+/,"string"],[/\\./,"string.escape.invalid"],[/'/,{token:"string.quote",bracket:"@close",next:"@pop"}]],whitespace:[[/[ \t\r\n]+/,"white"],[/\(\*/,"comment","@comment"],[/\/\/.*$/,"comment"]]}}})); -------------------------------------------------------------------------------- /static/monaco/min/vs/basic-languages/csp/csp.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * monaco-languages version: 1.10.0(1b4729c63bdb0d1e06d4e637e5c3977ddeb714dd) 4 | * Released under the MIT license 5 | * https://github.com/Microsoft/monaco-languages/blob/master/LICENSE.md 6 | *-----------------------------------------------------------------------------*/ 7 | define("vs/basic-languages/csp/csp",["require","exports"],(function(t,e){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.conf={brackets:[],autoClosingPairs:[],surroundingPairs:[]},e.language={keywords:[],typeKeywords:[],tokenPostfix:".csp",operators:[],symbols:/[=>>","&^","+=","-=","*=","/=","%=","&=","|=","^=","<<=",">>=","&^=","&&","||","<-","++","--","==","<",">","=","!","!=","<=",">=",":=","...","(",")","","]","{","}",",",";",".",":"],symbols:/[=>](?!@symbols)/,"@brackets"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/\d*\d+[eE]([\-+]?\d+)?/,"number.float"],[/\d*\.\d+([eE][\-+]?\d+)?/,"number.float"],[/0[xX][0-9a-fA-F']*[0-9a-fA-F]/,"number.hex"],[/0[0-7']*[0-7]/,"number.octal"],[/0[bB][0-1']*[0-1]/,"number.binary"],[/\d[\d']*/,"number"],[/\d/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"/,"string","@string"],[/`/,"string","@rawstring"],[/'[^\\']'/,"string"],[/(')(@escapes)(')/,["string","string.escape","string"]],[/'/,"string.invalid"]],whitespace:[[/[ \t\r\n]+/,""],[/\/\*\*(?!\/)/,"comment.doc","@doccomment"],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"]],comment:[[/[^\/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],doccomment:[[/[^\/*]+/,"comment.doc"],[/\/\*/,"comment.doc.invalid"],[/\*\//,"comment.doc","@pop"],[/[\/*]/,"comment.doc"]],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,"string","@pop"]],rawstring:[[/[^\`]/,"string"],[/`/,"string","@pop"]]}}})); -------------------------------------------------------------------------------- /static/monaco/min/vs/basic-languages/graphql/graphql.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * monaco-languages version: 1.10.0(1b4729c63bdb0d1e06d4e637e5c3977ddeb714dd) 4 | * Released under the MIT license 5 | * https://github.com/Microsoft/monaco-languages/blob/master/LICENSE.md 6 | *-----------------------------------------------------------------------------*/ 7 | define("vs/basic-languages/graphql/graphql",["require","exports"],(function(e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.conf={comments:{lineComment:"#"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"""',close:'"""',notIn:["string","comment"]},{open:'"',close:'"',notIn:["string","comment"]}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"""',close:'"""'},{open:'"',close:'"'}],folding:{offSide:!0}},n.language={defaultToken:"invalid",tokenPostfix:".gql",keywords:["null","true","false","query","mutation","subscription","extend","schema","directive","scalar","type","interface","union","enum","input","implements","fragment","on"],typeKeywords:["Int","Float","String","Boolean","ID"],directiveLocations:["SCHEMA","SCALAR","OBJECT","FIELD_DEFINITION","ARGUMENT_DEFINITION","INTERFACE","UNION","ENUM","ENUM_VALUE","INPUT_OBJECT","INPUT_FIELD_DEFINITION","QUERY","MUTATION","SUBSCRIPTION","FIELD","FRAGMENT_DEFINITION","FRAGMENT_SPREAD","INLINE_FRAGMENT","VARIABLE_DEFINITION"],operators:["=","!","?",":","&","|"],symbols:/[=!?:&|]+/,escapes:/\\(?:["\\\/bfnrt]|u[0-9A-Fa-f]{4})/,tokenizer:{root:[[/[a-z_][\w$]*/,{cases:{"@keywords":"keyword","@default":"key.identifier"}}],[/[$][\w$]*/,{cases:{"@keywords":"keyword","@default":"argument.identifier"}}],[/[A-Z][\w\$]*/,{cases:{"@typeKeywords":"keyword","@default":"type.identifier"}}],{include:"@whitespace"},[/[{}()\[\]]/,"@brackets"],[/@symbols/,{cases:{"@operators":"operator","@default":""}}],[/@\s*[a-zA-Z_\$][\w\$]*/,{token:"annotation",log:"annotation token: $0"}],[/\d*\.\d+([eE][\-+]?\d+)?/,"number.float"],[/0[xX][0-9a-fA-F]+/,"number.hex"],[/\d+/,"number"],[/[;,.]/,"delimiter"],[/"""/,{token:"string",next:"@mlstring",nextEmbedded:"markdown"}],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"/,{token:"string.quote",bracket:"@open",next:"@string"}]],mlstring:[[/[^"]+/,"string"],['"""',{token:"string",next:"@pop",nextEmbedded:"@pop"}]],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,{token:"string.quote",bracket:"@close",next:"@pop"}]],whitespace:[[/[ \t\r\n]+/,""],[/#.*$/,"comment"]]}}})); -------------------------------------------------------------------------------- /static/monaco/min/vs/basic-languages/ini/ini.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * monaco-languages version: 1.10.0(1b4729c63bdb0d1e06d4e637e5c3977ddeb714dd) 4 | * Released under the MIT license 5 | * https://github.com/Microsoft/monaco-languages/blob/master/LICENSE.md 6 | *-----------------------------------------------------------------------------*/ 7 | define("vs/basic-languages/ini/ini",["require","exports"],(function(e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.conf={comments:{lineComment:"#"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}]},n.language={defaultToken:"",tokenPostfix:".ini",escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,tokenizer:{root:[[/^\[[^\]]*\]/,"metatag"],[/(^\w+)(\s*)(\=)/,["key","","delimiter"]],{include:"@whitespace"},[/\d+/,"number"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/'([^'\\]|\\.)*$/,"string.invalid"],[/"/,"string",'@string."'],[/'/,"string","@string.'"]],whitespace:[[/[ \t\r\n]+/,""],[/^\s*[#;].*$/,"comment"]],string:[[/[^\\"']+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/["']/,{cases:{"$#==$S2":{token:"string",next:"@pop"},"@default":"string"}}]]}}})); -------------------------------------------------------------------------------- /static/monaco/min/vs/basic-languages/java/java.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * monaco-languages version: 1.10.0(1b4729c63bdb0d1e06d4e637e5c3977ddeb714dd) 4 | * Released under the MIT license 5 | * https://github.com/Microsoft/monaco-languages/blob/master/LICENSE.md 6 | *-----------------------------------------------------------------------------*/ 7 | define("vs/basic-languages/java/java",["require","exports"],(function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.conf={wordPattern:/(-?\d*\.\d\w*)|([^\`\~\!\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,comments:{lineComment:"//",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"},{open:"<",close:">"}],folding:{markers:{start:new RegExp("^\\s*//\\s*(?:(?:#?region\\b)|(?:))")}}},t.language={defaultToken:"",tokenPostfix:".java",keywords:["abstract","continue","for","new","switch","assert","default","goto","package","synchronized","boolean","do","if","private","this","break","double","implements","protected","throw","byte","else","import","public","throws","case","enum","instanceof","return","transient","catch","extends","int","short","try","char","final","interface","static","void","class","finally","long","strictfp","volatile","const","float","native","super","while","true","false"],operators:["=",">","<","!","~","?",":","==","<=",">=","!=","&&","||","++","--","+","-","*","/","&","|","^","%","<<",">>",">>>","+=","-=","*=","/=","&=","|=","^=","%=","<<=",">>=",">>>="],symbols:/[=>](?!@symbols)/,"@brackets"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/@\s*[a-zA-Z_\$][\w\$]*/,"annotation"],[/(@digits)[eE]([\-+]?(@digits))?[fFdD]?/,"number.float"],[/(@digits)\.(@digits)([eE][\-+]?(@digits))?[fFdD]?/,"number.float"],[/0[xX](@hexdigits)[Ll]?/,"number.hex"],[/0(@octaldigits)[Ll]?/,"number.octal"],[/0[bB](@binarydigits)[Ll]?/,"number.binary"],[/(@digits)[fFdD]/,"number.float"],[/(@digits)[lL]?/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"/,"string","@string"],[/'[^\\']'/,"string"],[/(')(@escapes)(')/,["string","string.escape","string"]],[/'/,"string.invalid"]],whitespace:[[/[ \t\r\n]+/,""],[/\/\*\*(?!\/)/,"comment.doc","@javadoc"],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"]],comment:[[/[^\/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],javadoc:[[/[^\/*]+/,"comment.doc"],[/\/\*/,"comment.doc.invalid"],[/\*\//,"comment.doc","@pop"],[/[\/*]/,"comment.doc"]],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,"string","@pop"]]}}})); -------------------------------------------------------------------------------- /static/monaco/min/vs/basic-languages/lua/lua.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * monaco-languages version: 1.10.0(1b4729c63bdb0d1e06d4e637e5c3977ddeb714dd) 4 | * Released under the MIT license 5 | * https://github.com/Microsoft/monaco-languages/blob/master/LICENSE.md 6 | *-----------------------------------------------------------------------------*/ 7 | define("vs/basic-languages/lua/lua",["require","exports"],(function(e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.conf={comments:{lineComment:"--",blockComment:["--[[","]]"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}]},n.language={defaultToken:"",tokenPostfix:".lua",keywords:["and","break","do","else","elseif","end","false","for","function","goto","if","in","local","nil","not","or","repeat","return","then","true","until","while"],brackets:[{token:"delimiter.bracket",open:"{",close:"}"},{token:"delimiter.array",open:"[",close:"]"},{token:"delimiter.parenthesis",open:"(",close:")"}],operators:["+","-","*","/","%","^","#","==","~=","<=",">=","<",">","=",";",":",",",".","..","..."],symbols:/[=>\/\?\s]+)/g,comments:{blockComment:["###","###"],lineComment:"#"},folding:{markers:{start:new RegExp("^\\s*#region\\b"),end:new RegExp("^\\s*#endregion\\b")}}},t.language={defaultToken:"",ignoreCase:!1,tokenPostfix:".mips",regEx:/\/(?!\/\/)(?:[^\/\\]|\\.)*\/[igm]*/,keywords:[".data",".text","syscall","trap","add","addu","addi","addiu","and","andi","div","divu","mult","multu","nor","or","ori","sll","slv","sra","srav","srl","srlv","sub","subu","xor","xori","lhi","lho","lhi","llo","slt","slti","sltu","sltiu","beq","bgtz","blez","bne","j","jal","jalr","jr","lb","lbu","lh","lhu","lw","li","la","sb","sh","sw","mfhi","mflo","mthi","mtlo","move"],symbols:/[\.,\:]+/,escapes:/\\(?:[abfnrtv\\"'$]|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,tokenizer:{root:[[/\$[a-zA-Z_]\w*/,"variable.predefined"],[/[.a-zA-Z_]\w*/,{cases:{this:"variable.predefined","@keywords":{token:"keyword.$0"},"@default":""}}],[/[ \t\r\n]+/,""],[/#.*$/,"comment"],["///",{token:"regexp",next:"@hereregexp"}],[/^(\s*)(@regEx)/,["","regexp"]],[/(\,)(\s*)(@regEx)/,["delimiter","","regexp"]],[/(\:)(\s*)(@regEx)/,["delimiter","","regexp"]],[/@symbols/,"delimiter"],[/\d+[eE]([\-+]?\d+)?/,"number.float"],[/\d+\.\d+([eE][\-+]?\d+)?/,"number.float"],[/0[xX][0-9a-fA-F]+/,"number.hex"],[/0[0-7]+(?!\d)/,"number.octal"],[/\d+/,"number"],[/[,.]/,"delimiter"],[/"""/,"string",'@herestring."""'],[/'''/,"string","@herestring.'''"],[/"/,{cases:{"@eos":"string","@default":{token:"string",next:'@string."'}}}],[/'/,{cases:{"@eos":"string","@default":{token:"string",next:"@string.'"}}}]],string:[[/[^"'\#\\]+/,"string"],[/@escapes/,"string.escape"],[/\./,"string.escape.invalid"],[/\./,"string.escape.invalid"],[/#{/,{cases:{'$S2=="':{token:"string",next:"root.interpolatedstring"},"@default":"string"}}],[/["']/,{cases:{"$#==$S2":{token:"string",next:"@pop"},"@default":"string"}}],[/#/,"string"]],herestring:[[/("""|''')/,{cases:{"$1==$S2":{token:"string",next:"@pop"},"@default":"string"}}],[/[^#\\'"]+/,"string"],[/['"]+/,"string"],[/@escapes/,"string.escape"],[/\./,"string.escape.invalid"],[/#{/,{token:"string.quote",next:"root.interpolatedstring"}],[/#/,"string"]],comment:[[/[^#]+/,"comment"],[/#/,"comment"]],hereregexp:[[/[^\\\/#]+/,"regexp"],[/\\./,"regexp"],[/#.*$/,"comment"],["///[igm]*",{token:"regexp",next:"@pop"}],[/\//,"regexp"]]}}})); -------------------------------------------------------------------------------- /static/monaco/min/vs/basic-languages/objective-c/objective-c.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * monaco-languages version: 1.10.0(1b4729c63bdb0d1e06d4e637e5c3977ddeb714dd) 4 | * Released under the MIT license 5 | * https://github.com/Microsoft/monaco-languages/blob/master/LICENSE.md 6 | *-----------------------------------------------------------------------------*/ 7 | define("vs/basic-languages/objective-c/objective-c",["require","exports"],(function(e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.conf={comments:{lineComment:"//",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}]},n.language={defaultToken:"",tokenPostfix:".objective-c",keywords:["#import","#include","#define","#else","#endif","#if","#ifdef","#ifndef","#ident","#undef","@class","@defs","@dynamic","@encode","@end","@implementation","@interface","@package","@private","@protected","@property","@protocol","@public","@selector","@synthesize","__declspec","assign","auto","BOOL","break","bycopy","byref","case","char","Class","const","copy","continue","default","do","double","else","enum","extern","FALSE","false","float","for","goto","if","in","int","id","inout","IMP","long","nil","nonatomic","NULL","oneway","out","private","public","protected","readwrite","readonly","register","return","SEL","self","short","signed","sizeof","static","struct","super","switch","typedef","TRUE","true","union","unsigned","volatile","void","while"],decpart:/\d(_?\d)*/,decimal:/0|@decpart/,tokenizer:{root:[{include:"@comments"},{include:"@whitespace"},{include:"@numbers"},{include:"@strings"},[/[,:;]/,"delimiter"],[/[{}\[\]()<>]/,"@brackets"],[/[a-zA-Z@#]\w*/,{cases:{"@keywords":"keyword","@default":"identifier"}}],[/[<>=\\+\\-\\*\\/\\^\\|\\~,]|and\\b|or\\b|not\\b]/,"operator"]],whitespace:[[/\s+/,"white"]],comments:[["\\/\\*","comment","@comment"],["\\/\\/+.*","comment"]],comment:[["\\*\\/","comment","@pop"],[".","comment"]],numbers:[[/0[xX][0-9a-fA-F]*(_?[0-9a-fA-F])*/,"number.hex"],[/@decimal((\.@decpart)?([eE][\-+]?@decpart)?)[fF]*/,{cases:{"(\\d)*":"number",$0:"number.float"}}]],strings:[[/'$/,"string.escape","@popall"],[/'/,"string.escape","@stringBody"],[/"$/,"string.escape","@popall"],[/"/,"string.escape","@dblStringBody"]],stringBody:[[/[^\\']+$/,"string","@popall"],[/[^\\']+/,"string"],[/\\./,"string"],[/'/,"string.escape","@popall"],[/\\$/,"string"]],dblStringBody:[[/[^\\"]+$/,"string","@popall"],[/[^\\"]+/,"string"],[/\\./,"string"],[/"/,"string.escape","@popall"],[/\\$/,"string"]]}}})); -------------------------------------------------------------------------------- /static/monaco/min/vs/basic-languages/pascaligo/pascaligo.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * monaco-languages version: 1.10.0(1b4729c63bdb0d1e06d4e637e5c3977ddeb714dd) 4 | * Released under the MIT license 5 | * https://github.com/Microsoft/monaco-languages/blob/master/LICENSE.md 6 | *-----------------------------------------------------------------------------*/ 7 | define("vs/basic-languages/pascaligo/pascaligo",["require","exports"],(function(e,o){"use strict";Object.defineProperty(o,"__esModule",{value:!0}),o.conf={comments:{lineComment:"//",blockComment:["(*","*)"]},brackets:[["{","}"],["[","]"],["(",")"],["<",">"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"<",close:">"},{open:"'",close:"'"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"<",close:">"},{open:"'",close:"'"}]},o.language={defaultToken:"",tokenPostfix:".pascaligo",ignoreCase:!0,brackets:[{open:"{",close:"}",token:"delimiter.curly"},{open:"[",close:"]",token:"delimiter.square"},{open:"(",close:")",token:"delimiter.parenthesis"},{open:"<",close:">",token:"delimiter.angle"}],keywords:["begin","block","case","const","else","end","fail","for","from","function","if","is","nil","of","remove","return","skip","then","type","var","while","with","option","None","transaction"],typeKeywords:["bool","int","list","map","nat","record","string","unit","address","map","mtz","xtz"],operators:["=",">","<","<=",">=","<>",":",":=","and","mod","or","+","-","*","/","@","&","^","%"],symbols:/[=><:@\^&|+\-*\/\^%]+/,tokenizer:{root:[[/[a-zA-Z_][\w]*/,{cases:{"@keywords":{token:"keyword.$0"},"@default":"identifier"}}],{include:"@whitespace"},[/[{}()\[\]]/,"@brackets"],[/[<>](?!@symbols)/,"@brackets"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/\d*\.\d+([eE][\-+]?\d+)?/,"number.float"],[/\$[0-9a-fA-F]{1,16}/,"number.hex"],[/\d+/,"number"],[/[;,.]/,"delimiter"],[/'([^'\\]|\\.)*$/,"string.invalid"],[/'/,"string","@string"],[/'[^\\']'/,"string"],[/'/,"string.invalid"],[/\#\d+/,"string"]],comment:[[/[^\(\*]+/,"comment"],[/\*\)/,"comment","@pop"],[/\(\*/,"comment"]],string:[[/[^\\']+/,"string"],[/\\./,"string.escape.invalid"],[/'/,{token:"string.quote",bracket:"@close",next:"@pop"}]],whitespace:[[/[ \t\r\n]+/,"white"],[/\(\*/,"comment","@comment"],[/\/\/.*$/,"comment"]]}}})); -------------------------------------------------------------------------------- /static/monaco/min/vs/basic-languages/r/r.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * monaco-languages version: 1.10.0(1b4729c63bdb0d1e06d4e637e5c3977ddeb714dd) 4 | * Released under the MIT license 5 | * https://github.com/Microsoft/monaco-languages/blob/master/LICENSE.md 6 | *-----------------------------------------------------------------------------*/ 7 | define("vs/basic-languages/r/r",["require","exports"],(function(e,o){"use strict";Object.defineProperty(o,"__esModule",{value:!0}),o.conf={comments:{lineComment:"#"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'}]},o.language={defaultToken:"",tokenPostfix:".r",roxygen:["@param","@return","@name","@rdname","@examples","@include","@docType","@S3method","@TODO","@aliases","@alias","@assignee","@author","@callGraphDepth","@callGraph","@callGraphPrimitives","@concept","@exportClass","@exportMethod","@exportPattern","@export","@formals","@format","@importClassesFrom","@importFrom","@importMethodsFrom","@import","@keywords","@method","@nord","@note","@references","@seealso","@setClass","@slot","@source","@title","@usage"],constants:["NULL","FALSE","TRUE","NA","Inf","NaN ","NA_integer_","NA_real_","NA_complex_","NA_character_ ","T","F","LETTERS","letters","month.abb","month.name","pi","R.version.string"],keywords:["break","next","return","if","else","for","in","repeat","while","array","category","character","complex","double","function","integer","list","logical","matrix","numeric","vector","data.frame","factor","library","require","attach","detach","source"],special:["\\n","\\r","\\t","\\b","\\a","\\f","\\v","\\'",'\\"',"\\\\"],brackets:[{open:"{",close:"}",token:"delimiter.curly"},{open:"[",close:"]",token:"delimiter.bracket"},{open:"(",close:")",token:"delimiter.parenthesis"}],tokenizer:{root:[{include:"@numbers"},{include:"@strings"},[/[{}\[\]()]/,"@brackets"],{include:"@operators"},[/#'/,"comment.doc","@roxygen"],[/(^#.*$)/,"comment"],[/\s+/,"white"],[/[,:;]/,"delimiter"],[/@[a-zA-Z]\w*/,"tag"],[/[a-zA-Z]\w*/,{cases:{"@keywords":"keyword","@constants":"constant","@default":"identifier"}}]],roxygen:[[/@\w+/,{cases:{"@roxygen":"tag","@eos":{token:"comment.doc",next:"@pop"},"@default":"comment.doc"}}],[/\s+/,{cases:{"@eos":{token:"comment.doc",next:"@pop"},"@default":"comment.doc"}}],[/.*/,{token:"comment.doc",next:"@pop"}]],numbers:[[/0[xX][0-9a-fA-F]+/,"number.hex"],[/-?(\d*\.)?\d+([eE][+\-]?\d+)?/,"number"]],operators:[[/<{1,2}-/,"operator"],[/->{1,2}/,"operator"],[/%[^%\s]+%/,"operator"],[/\*\*/,"operator"],[/%%/,"operator"],[/&&/,"operator"],[/\|\|/,"operator"],[/<>/,"operator"],[/[-+=&|!<>^~*/:$]/,"operator"]],strings:[[/'/,"string.escape","@stringBody"],[/"/,"string.escape","@dblStringBody"]],stringBody:[[/\\./,{cases:{"@special":"string","@default":"error-token"}}],[/'/,"string.escape","@popall"],[/./,"string"]],dblStringBody:[[/\\./,{cases:{"@special":"string","@default":"error-token"}}],[/"/,"string.escape","@popall"],[/./,"string"]]}}})); -------------------------------------------------------------------------------- /static/monaco/min/vs/basic-languages/sb/sb.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * monaco-languages version: 1.10.0(1b4729c63bdb0d1e06d4e637e5c3977ddeb714dd) 4 | * Released under the MIT license 5 | * https://github.com/Microsoft/monaco-languages/blob/master/LICENSE.md 6 | *-----------------------------------------------------------------------------*/ 7 | define("vs/basic-languages/sb/sb",["require","exports"],(function(e,o){"use strict";Object.defineProperty(o,"__esModule",{value:!0}),o.conf={comments:{lineComment:"'"},brackets:[["(",")"],["[","]"],["If","EndIf"],["While","EndWhile"],["For","EndFor"],["Sub","EndSub"]],autoClosingPairs:[{open:'"',close:'"',notIn:["string","comment"]},{open:"(",close:")",notIn:["string","comment"]},{open:"[",close:"]",notIn:["string","comment"]}]},o.language={defaultToken:"",tokenPostfix:".sb",ignoreCase:!0,brackets:[{token:"delimiter.array",open:"[",close:"]"},{token:"delimiter.parenthesis",open:"(",close:")"},{token:"keyword.tag-if",open:"If",close:"EndIf"},{token:"keyword.tag-while",open:"While",close:"EndWhile"},{token:"keyword.tag-for",open:"For",close:"EndFor"},{token:"keyword.tag-sub",open:"Sub",close:"EndSub"}],keywords:["Else","ElseIf","EndFor","EndIf","EndSub","EndWhile","For","Goto","If","Step","Sub","Then","To","While"],tagwords:["If","Sub","While","For"],operators:[">","<","<>","<=",">=","And","Or","+","-","*","/","="],identifier:/[a-zA-Z_][\w]*/,symbols:/[=><:+\-*\/%\.,]+/,escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,tokenizer:{root:[{include:"@whitespace"},[/(@identifier)(?=[.])/,"type"],[/@identifier/,{cases:{"@keywords":{token:"keyword.$0"},"@operators":"operator","@default":"variable.name"}}],[/([.])(@identifier)/,{cases:{$2:["delimiter","type.member"],"@default":""}}],[/\d*\.\d+/,"number.float"],[/\d+/,"number"],[/[()\[\]]/,"@brackets"],[/@symbols/,{cases:{"@operators":"operator","@default":"delimiter"}}],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"/,"string","@string"]],whitespace:[[/[ \t\r\n]+/,""],[/(\').*$/,"comment"]],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"C?/,"string","@pop"]]}}})); -------------------------------------------------------------------------------- /static/monaco/min/vs/basic-languages/scheme/scheme.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * monaco-languages version: 1.10.0(1b4729c63bdb0d1e06d4e637e5c3977ddeb714dd) 4 | * Released under the MIT license 5 | * https://github.com/Microsoft/monaco-languages/blob/master/LICENSE.md 6 | *-----------------------------------------------------------------------------*/ 7 | define("vs/basic-languages/scheme/scheme",["require","exports"],(function(e,o){"use strict";Object.defineProperty(o,"__esModule",{value:!0}),o.conf={comments:{lineComment:";",blockComment:["#|","|#"]},brackets:[["(",")"],["{","}"],["[","]"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'}]},o.language={defaultToken:"",ignoreCase:!0,tokenPostfix:".scheme",brackets:[{open:"(",close:")",token:"delimiter.parenthesis"},{open:"{",close:"}",token:"delimiter.curly"},{open:"[",close:"]",token:"delimiter.square"}],keywords:["case","do","let","loop","if","else","when","cons","car","cdr","cond","lambda","lambda*","syntax-rules","format","set!","quote","eval","append","list","list?","member?","load"],constants:["#t","#f"],operators:["eq?","eqv?","equal?","and","or","not","null?"],tokenizer:{root:[[/#[xXoObB][0-9a-fA-F]+/,"number.hex"],[/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?/,"number.float"],[/(?:\b(?:(define|define-syntax|define-macro))\b)(\s+)((?:\w|\-|\!|\?)*)/,["keyword","white","variable"]],{include:"@whitespace"},{include:"@strings"},[/[a-zA-Z_#][a-zA-Z0-9_\-\?\!\*]*/,{cases:{"@keywords":"keyword","@constants":"constant","@operators":"operators","@default":"identifier"}}]],comment:[[/[^\|#]+/,"comment"],[/#\|/,"comment","@push"],[/\|#/,"comment","@pop"],[/[\|#]/,"comment"]],whitespace:[[/[ \t\r\n]+/,"white"],[/#\|/,"comment","@comment"],[/;.*$/,"comment"]],strings:[[/"$/,"string","@popall"],[/"(?=.)/,"string","@multiLineString"]],multiLineString:[[/[^\\"]+$/,"string","@popall"],[/[^\\"]+/,"string"],[/\\./,"string.escape"],[/"/,"string","@popall"],[/\\$/,"string"]]}}})); -------------------------------------------------------------------------------- /static/monaco/min/vs/basic-languages/shell/shell.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * monaco-languages version: 1.10.0(1b4729c63bdb0d1e06d4e637e5c3977ddeb714dd) 4 | * Released under the MIT license 5 | * https://github.com/Microsoft/monaco-languages/blob/master/LICENSE.md 6 | *-----------------------------------------------------------------------------*/ 7 | define("vs/basic-languages/shell/shell",["require","exports"],(function(e,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.conf={comments:{lineComment:"#"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"},{open:"`",close:"`"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"},{open:"`",close:"`"}]},r.language={defaultToken:"",ignoreCase:!0,tokenPostfix:".shell",brackets:[{token:"delimiter.bracket",open:"{",close:"}"},{token:"delimiter.parenthesis",open:"(",close:")"},{token:"delimiter.square",open:"[",close:"]"}],keywords:["if","then","do","else","elif","while","until","for","in","esac","fi","fin","fil","done","exit","set","unset","export","function"],builtins:["ab","awk","bash","beep","cat","cc","cd","chown","chmod","chroot","clear","cp","curl","cut","diff","echo","find","gawk","gcc","get","git","grep","hg","kill","killall","ln","ls","make","mkdir","openssl","mv","nc","node","npm","ping","ps","restart","rm","rmdir","sed","service","sh","shopt","shred","source","sort","sleep","ssh","start","stop","su","sudo","svn","tee","telnet","top","touch","vi","vim","wall","wc","wget","who","write","yes","zsh"],symbols:/[=>"]],autoClosingPairs:[{open:'"',close:'"',notIn:["string","comment"]},{open:"{",close:"}",notIn:["string","comment"]},{open:"[",close:"]",notIn:["string","comment"]},{open:"(",close:")",notIn:["string","comment"]}]},t.language={defaultToken:"",tokenPostfix:".aes",brackets:[{token:"delimiter.curly",open:"{",close:"}"},{token:"delimiter.parenthesis",open:"(",close:")"},{token:"delimiter.square",open:"[",close:"]"},{token:"delimiter.angle",open:"<",close:">"}],keywords:["contract","library","entrypoint","function","stateful","state","hash","signature","tuple","list","address","string","bool","int","record","datatype","type","option","oracle","oracle_query","Call","Bits","Bytes","Oracle","String","Crypto","Address","Auth","Chain","None","Some","bits","bytes","event","let","map","private","public","true","false","var","if","else","throw"],operators:["=",">","<","!","~","?","::",":","==","<=",">=","!=","&&","||","++","--","+","-","*","/","&","|","^","%","<<",">>",">>>","+=","-=","*=","/=","&=","|=","^=","%=","<<=",">>=",">>>="],symbols:/[=>](?!@symbols)/,"@brackets"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/\d*\d+[eE]([\-+]?\d+)?(@floatsuffix)/,"number.float"],[/\d*\.\d+([eE][\-+]?\d+)?(@floatsuffix)/,"number.float"],[/0[xX][0-9a-fA-F']*[0-9a-fA-F](@integersuffix)/,"number.hex"],[/0[0-7']*[0-7](@integersuffix)/,"number.octal"],[/0[bB][0-1']*[0-1](@integersuffix)/,"number.binary"],[/\d[\d']*\d(@integersuffix)/,"number"],[/\d(@integersuffix)/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"/,"string","@string"],[/'[^\\']'/,"string"],[/(')(@escapes)(')/,["string","string.escape","string"]],[/'/,"string.invalid"]],whitespace:[[/[ \t\r\n]+/,""],[/\/\*\*(?!\/)/,"comment.doc","@doccomment"],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"]],comment:[[/[^\/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],doccomment:[[/[^\/*]+/,"comment.doc"],[/\*\//,"comment.doc","@pop"],[/[\/*]/,"comment.doc"]],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,"string","@pop"]]}}})); -------------------------------------------------------------------------------- /static/monaco/min/vs/basic-languages/xml/xml.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * monaco-languages version: 1.10.0(1b4729c63bdb0d1e06d4e637e5c3977ddeb714dd) 4 | * Released under the MIT license 5 | * https://github.com/Microsoft/monaco-languages/blob/master/LICENSE.md 6 | *-----------------------------------------------------------------------------*/ 7 | define("vs/basic-languages/xml/xml",["require","exports"],(function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.conf={comments:{blockComment:["\x3c!--","--\x3e"]},brackets:[["<",">"]],autoClosingPairs:[{open:"<",close:">"},{open:"'",close:"'"},{open:'"',close:'"'}],surroundingPairs:[{open:"<",close:">"},{open:"'",close:"'"},{open:'"',close:'"'}]},t.language={defaultToken:"",tokenPostfix:".xml",ignoreCase:!0,qualifiedName:/(?:[\w\.\-]+:)?[\w\.\-]+/,tokenizer:{root:[[/[^<&]+/,""],{include:"@whitespace"},[/(<)(@qualifiedName)/,[{token:"delimiter"},{token:"tag",next:"@tag"}]],[/(<\/)(@qualifiedName)(\s*)(>)/,[{token:"delimiter"},{token:"tag"},"",{token:"delimiter"}]],[/(<\?)(@qualifiedName)/,[{token:"delimiter"},{token:"metatag",next:"@tag"}]],[/(<\!)(@qualifiedName)/,[{token:"delimiter"},{token:"metatag",next:"@tag"}]],[/<\!\[CDATA\[/,{token:"delimiter.cdata",next:"@cdata"}],[/&\w+;/,"string.escape"]],cdata:[[/[^\]]+/,""],[/\]\]>/,{token:"delimiter.cdata",next:"@pop"}],[/\]/,""]],tag:[[/[ \t\r\n]+/,""],[/(@qualifiedName)(\s*=\s*)("[^"]*"|'[^']*')/,["attribute.name","","attribute.value"]],[/(@qualifiedName)(\s*=\s*)("[^">?\/]*|'[^'>?\/]*)(?=[\?\/]\>)/,["attribute.name","","attribute.value"]],[/(@qualifiedName)(\s*=\s*)("[^">]*|'[^'>]*)/,["attribute.name","","attribute.value"]],[/@qualifiedName/,"attribute.name"],[/\?>/,{token:"delimiter",next:"@pop"}],[/(\/)(>)/,[{token:"tag"},{token:"delimiter",next:"@pop"}]],[/>/,{token:"delimiter",next:"@pop"}]],whitespace:[[/[ \t\r\n]+/,""],[//,{token:"comment",next:"@pop"}],[/ 36 | {% for category, message in messages %} 37 | 42 | {% endfor %} 43 | {% endif %} 44 | {% endwith %} 45 | 46 | 47 | 48 | {% block main_content %} 49 | {% endblock %} 50 | 51 | 52 | {% include 'footer.html' %} 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /templates/base_nonav.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {% block title %}Home{% endblock %} - Vulncode-DB 8 | {% include 'header.html' %} 9 | 10 | 11 | 12 |
13 |
14 | {% with messages = get_flashed_messages(with_categories=true) %} 15 | 16 |
17 |
18 |
19 |
20 | {% if config.MAINTENANCE_MODE %} 21 | 24 | {% endif %} 25 | {% if messages %} 26 | 27 | {% for category, message in messages %} 28 | 33 | {% endfor %} 34 | {% endif %} 35 | {% endwith %} 36 |
37 |
38 | 39 | {% block main_content %} 40 | {% endblock %} 41 |
42 | 43 | {% include 'footer.html' %} 44 |
45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /templates/editor/editor_container.html: -------------------------------------------------------------------------------- 1 | {% set vuln_view = vulnerability_details.vulnerability_view %} 2 | {% set master_commit = vuln_view.master_commit %} 3 | 13 |
14 |
15 | 18 | 21 | 24 | 27 |
-------------------------------------------------------------------------------- /templates/editor/file_tree.html: -------------------------------------------------------------------------------- 1 | {% set vcdb_id = vulnerability_details.id %} 2 | {% set vuln_view = vulnerability_details.vulnerability_view %} 3 | {% set tree_url = vulnerability_details.tree_url %} 4 | {% set master_commit = vuln_view.master_commit %} 5 | {% set commit_hash = master_commit.commit_hash %} 6 | {% if vuln_view.annotated %} 7 | Goto simplified view 8 | {% endif %} 9 | 10 |

11 | 12 | {{ master_commit.repo_name }} 13 | 14 | - Tree: {{ commit_hash[:10] }} 15 |

16 |

(? files)

17 | 18 |
Filter Settings
19 |
20 |
21 | 22 | 23 |
24 |
25 | 26 | 27 |
28 |
29 | 30 | 31 |
32 |
33 | 34 | 35 |
36 |
37 |
38 |
Files
39 |
40 |
41 | -------------------------------------------------------------------------------- /templates/editor/metadata_edit.html: -------------------------------------------------------------------------------- 1 | Metadata 2 | 3 |
4 |

5 | Editor 6 |

7 | {# TODO: Should we display this in the first place? 8 | Marked lines: 9 |

(current file)

10 |
11 |
12 | #} 13 | Patched area: 14 | 20 | 21 |
22 | Sections: 23 | 29 |
30 |
    31 |
32 |
33 |
34 | Editor control keys: 35 |
    36 |
  • v: mark/unmark section as vulnerable
  • 37 |
  • i: mark/unmark section as irrelevant
  • 38 |
  • c: add comment to currently selected line
  • 39 |
40 |
41 | 42 | {% if config.DEMO_MODE and not g.user %} 43 | 44 | {% else %} 45 | 46 | {% endif %} 47 |
48 | -------------------------------------------------------------------------------- /templates/editor/metadata_view.html: -------------------------------------------------------------------------------- 1 | Navigation 2 | 3 |
4 | {# TODO: Should we display this in the first place? 5 | Marked lines: 6 |

(current file)

7 |
8 |
9 | #} 10 | Patch data: 11 |

(on by default)

12 |
13 | 14 | 15 |
16 |
17 | 18 | Patched area: 19 | 25 | 26 | {% set vuln_view = vulnerability_details.vulnerability_view %} 27 | {% set master_commit = vuln_view.master_commit %} 28 | {% if master_commit and master_commit.comments|length > 0 %} 29 |
30 | Sections: 31 | 37 |
38 |
    39 |
40 |
41 | {% endif %} 42 |
43 | -------------------------------------------------------------------------------- /templates/error_generic.html: -------------------------------------------------------------------------------- 1 | {% extends "base_nonav.html" %} 2 | {% block main_content %} 3 |
4 |
5 |
6 |
7 |

{{ error_name }}

8 | {% if config.DEBUG %} 9 | 12 |
{{ traceback|highlight('pytb') }}
13 | {% endif %} 14 |
15 |
16 |
17 |
18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /templates/footer.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 | 6 | 7 | 15 | 16 | 17 |
18 | 19 | 33 |
34 | 35 | {% if vulnerability_details %} 36 | 44 | {% endif %} 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 58 | 59 | {# TODO: This is currently disabled. Enable it again once it becomes useful. 60 | 61 | 62 | #} 63 | -------------------------------------------------------------------------------- /templates/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 45 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block main_content %} 3 |
4 |
5 | {% include 'index_vuln_list.html' %} 6 |
7 |
8 | {% endblock %} -------------------------------------------------------------------------------- /templates/index_vuln_list.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

5 | 6 |
7 | 8 | {# 9 |
10 | 11 | {% macro print_key_value_row(key, value) -%} 12 | 13 | {%- endmacro %} 14 | {{print_key_value_row("Loaded CVE-entries", vcdb.number_cve_entries)}} 15 | {{print_key_value_row("Entries with a known patch link", vcdb.number_cve_with_patches | string + ' (%0.2f%%)' % (vcdb.number_cve_with_patches / vcdb.number_cve_entries * 100))}} 16 |
{{key}}{{value}}
17 |
18 | #} 19 | {% include 'list_vuln_entries.html' %} 20 | 21 | {# 22 | This part won't be used until public contributions are enabled. 23 |
24 |

TOP 10 contributors

25 |
26 | 27 | 28 | 29 | 30 | 31 | 32 | {% for user, num_comments, num_markers in vcdb.top_contributors %} 33 | 34 | 35 | 36 | 37 | 38 | {% endfor %} 39 |
#User# Annotations
{{ loop.index }}@{{ user.name }}{{ num_comments + num_markers }}
40 |
41 |
42 | #} 43 | 44 |
45 |
46 | -------------------------------------------------------------------------------- /templates/list_vuln_entries.html: -------------------------------------------------------------------------------- 1 | {% from 'macros/generate_vuln_table.html' import display_vuln_table, default_vuln_columns_full %} 2 | {% from 'macros/pagination.html' import display_vuln_pagination, display_nvd_pagination %} 3 |
4 | {% set columns = ['date', 'id', 'summary', 'products', 'score', 'patch'] %} 5 | Main entries ~{{vcdb.vcdb_pagination.total}} : 6 | {{ display_vuln_table(vcdb.vcdb_pagination.rows, 'vcdb', default_vuln_columns_full ) }} 7 | {{ display_nvd_pagination(vcdb.vcdb_pagination, 'vcdb', vcdb.keyword) }} 8 | Remaining NVD entries (unprocessed / no code available): ~{{vcdb.nvd_pagination.total}} : 9 | {{ display_vuln_table(vcdb.nvd_pagination.rows, 'nvd') }} 10 | {{ display_nvd_pagination(vcdb.nvd_pagination, 'nvd', vcdb.keyword) }} 11 |
12 | 13 | -------------------------------------------------------------------------------- /templates/local_login.html: -------------------------------------------------------------------------------- 1 | {% extends "login.html" %} 2 | {% block login_extra %} 3 | Please choose the admin (specified as APPLICATION_ADMINS in app.yaml) or other roles for login:
4 | {% if users|length == 0 %} 5 | Please add APPLICATION_ADMINS to your app.yaml and restart the application. 6 | {% else %} 7 | {% for user in users %} 8 | - {{user}}
9 | {% endfor %} 10 | - user@vulncode-db.com
11 | - reviewer@vulncode-db.com
12 |
13 | 14 |

Normal OAuth

15 | (make sure to set OAUTH_CONSUMER_KEY and OAUTH_CONSUMER_SECRET in app.yaml)
16 | {% endif %} 17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /templates/macros/pagination.html: -------------------------------------------------------------------------------- 1 | {% macro display_vuln_pagination(pagination, table_id, keyword) %} 2 | {% set base_url_params = {"keyword":keyword, "_anchor":table_id + "_tbl"} %} 3 | 4 | {% set page_num = table_id + '_p' %} 5 | 41 | {% endmacro %} 42 | 43 | {% macro display_nvd_pagination(pagination, table_id, keyword) %} 44 | {% set base_url_params = {"keyword":keyword, "_anchor":table_id + "_tbl"} %} 45 | {% set page_num = table_id + '_p' %} 46 | {% set pagination_url_params = base_url_params %} 47 | 60 | {% endmacro %} 61 | -------------------------------------------------------------------------------- /templates/macros/products.html: -------------------------------------------------------------------------------- 1 | {% macro print_product_links(products) -%} 2 | {% for (vendor, product) in products %} 3 | {{ product|title }}{% if loop.index0 < products|length - 1 %},{% endif %} 4 | {% endfor %} 5 | {% endmacro %} -------------------------------------------------------------------------------- /templates/macros/text_format.html: -------------------------------------------------------------------------------- 1 | {% macro print_link(value) -%} 2 | {% if value is string and value.startswith('http') %} 3 | {{ value }} 4 | {% elif value is iterable and value is not string and value|length > 0 %} 5 | {{ print_link(value[0]) }} 6 | {% else %} 7 | {{ value }} 8 | {% endif %} 9 | {%- endmacro %} 10 | 11 | 12 | {% macro print_cwes(cwes) -%} 13 | {% if cwes is iterable and cwes|length > 0 %} 14 | {% set data = [] %} 15 | {% for cwe in cwes %} 16 | {{ cwe.cwe_name or "?" }} ({{ cwe.cwe_id }})
18 | {% endfor %} 19 | {% endif %} 20 | {% endmacro %} 21 | 22 | {% macro print_formatted(data, expand_label) -%} 23 | {% if data is iterable and data is not string and data|length > 1 %} 24 | {% set max_limit = 5 %} 25 | 26 | {% for entry in data %} 27 | {% if loop.index0 < max_limit %} 28 | • {{ print_link(entry) }}
29 | {% endif %} 30 | {% endfor %} 31 | 32 | {% if data|length > max_limit %} 33 | {% set remaining = data|length - max_limit %} 34 |
35 | 36 | 37 | More/Less ({{ remaining }}) 38 | 39 |
40 |
41 | {% endif %} 42 | 43 | {% for entry in data %} 44 | {% if loop.index0 >= max_limit %} 45 | • {{ print_link(entry) }}
46 | {% endif %} 47 | {% endfor %} 48 | 49 | {% if data|length > max_limit %} 50 |
51 | {% endif %} 52 | 53 | {% else %} 54 | {{ print_link(data) }} 55 | {% endif %} 56 | {% endmacro %} -------------------------------------------------------------------------------- /templates/macros/user.html: -------------------------------------------------------------------------------- 1 | {% macro print_user(user, class=None) %} 2 | {{ user.name }} 3 | {% endmacro %} 4 | -------------------------------------------------------------------------------- /templates/maintenance.html: -------------------------------------------------------------------------------- 1 | {% extends "base_nonav.html" %} 2 | {% block main_content %} 3 |
4 |
5 |
6 |
7 |

8 | Under maintenance.
Please come back soon. 9 |

10 |
11 |
12 |
13 |
14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /templates/nvd_view.html: -------------------------------------------------------------------------------- 1 | 2 | NVD Data 3 | (More 4 | Details) 5 | 6 |
7 | {% macro print_formatted(data) -%} 8 | {% if data is iterable and data is not string %} 9 | {% for entry in data %} 10 | {% if entry.startswith('http') %} 11 | • 12 | {{ entry }} 13 | {% else %} 14 | • {{ entry }} 15 | {% endif %} 16 |
17 | {% endfor %} 18 | {% else %} 19 | {% if data.startswith('http') %} 20 | {{ data }} 21 | {% else %} 22 | {{ data }} 23 | {% endif %} 24 | {% endif %} 25 | {%- endmacro %} 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | {% set products = nvd_data.get_products() %} 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 53 | 54 | 55 | 56 | 57 | 58 |
Summary{{ nvd_data.summary }}
Products{{ (products and print_formatted(nvd_data.get_products())) or "N/A" }}
Score{{ '%0.1f' % nvd_data.score }}
CWE ID{{ nvd_data.cwe_id }}
Patches 47 | {% if nvd_data.has_patch() %} 48 | {{ print_formatted(nvd_data.get_patches()) }} 49 | {% else %} 50 | Unknown 51 | {% endif %} 52 |
Links{{ print_formatted(nvd_data.get_links()) }}
59 |
-------------------------------------------------------------------------------- /templates/product/view.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block title %}{{ product|title }}{% endblock %} 3 | {% block main_content %} 4 |
5 |
6 |
7 |
8 |
9 | Product: 10 |

11 | {{ product|title }} 12 |

13 | ({{ vendor|title }}) 14 |
15 | 16 |
17 | 18 | 19 | 20 | 29 | 30 | 31 | 32 | 35 | 36 |
Repositories 21 | {% if repo_urls|length == 0 %} 22 |

Unknown:

23 |

This might be proprietary software.

24 | {% else %} 25 | {% from 'macros/text_format.html' import print_formatted %} 26 | {{ print_formatted(repo_urls, 'products') }} 27 | {% endif %} 28 |
#Vulnerabilities 33 | {{ number_vulns }} 34 |
37 |
38 | {% set columns = ['date', 'id', 'summary', 'products', 'score', 'patch', 'annotated'] %} 39 | {% from 'macros/generate_vuln_table.html' import display_vuln_table, default_vuln_columns_full %} 40 | {% from 'macros/pagination.html' import display_nvd_pagination %} 41 |
42 | {{ display_vuln_table(product_vulns.rows, 'product', default_vuln_columns_full) }} 43 | {{ display_nvd_pagination(product_vulns, 'product', '') }} 44 |
45 | 46 |
47 |
48 |
49 |
50 | {% endblock %} -------------------------------------------------------------------------------- /templates/profile/edit_proposal.html: -------------------------------------------------------------------------------- 1 | {% import "bootstrap/wtf.html" as wtf %} 2 | {# TODO: Consider using "custom_bootstrap_form.html" for customizations here. #} 3 | 4 | {% extends "base.html" %} 5 | {% block main_content %} 6 |
7 |
8 | {% set vuln_view = vulnerability_details.vulnerability_view %} 9 |

Edit proposal

10 |
11 |
12 |
13 |
14 | {% set edit_mode = true %} 15 | {% if vuln_view.needs_improvement() %} 16 |
17 |
18 | {% include 'review/feedback_card.html' %} 19 | Please address the feedback and resubmit the proposal. 20 |
21 |
22 | {% endif %} 23 | {% include 'vulnerability/info.html' %} 24 |
25 |
26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /templates/profile/index.html: -------------------------------------------------------------------------------- 1 | {% import "bootstrap/wtf.html" as wtf %} 2 | {% from 'macros/generate_vuln_table.html' import display_vuln_column %} 3 | 4 | {% extends "base.html" %} 5 | 6 | 7 | {% block main_content %} 8 |
9 |
10 |

My Profile

11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | 19 | {{user.login}} 20 | Only you can see this. 21 | Provider: {{ user.login_type | title }} 22 |
23 |
24 | {{ form.hidden_tag() }} 25 | {{ wtf.form_errors(form, hiddens="only") }} 26 | {% for field in form.non_hidden_fields %} 27 | {{ wtf.form_field(field) }} 28 | {% endfor %} 29 | 30 | 31 | See public version 32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | Public Appearance 40 |
41 |
42 | {% if user.avatar %} 43 | profile picture 44 | {% endif %} 45 | {{ user.name }} 46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |

Contributions

55 |
    56 | {%- for vuln in vulns %} 57 |
  • 58 | {{ vuln.cve_id }} 59 | ({{ display_vuln_column(vuln, 'state') }}) 60 |
  • 61 | {% endfor %} 62 |
63 |
64 |
65 |
66 |
67 | {% endblock main_content %} 68 | -------------------------------------------------------------------------------- /templates/profile/profile_viewer.html: -------------------------------------------------------------------------------- 1 | {% import "bootstrap/wtf.html" as wtf %} 2 | {% from 'macros/generate_vuln_table.html' import display_vuln_column %} 3 | 4 | {% extends "base.html" %} 5 | 6 | 7 | {% block main_content %} 8 |
9 |
10 |

{{ user.name }}'s Profile

11 |
12 |
13 |
14 |
15 |
16 |
17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 |
Name:{{ user.name }}
25 |
26 |
27 |
28 |
29 | {% if user.avatar %} 30 |
31 |
32 |
33 | profile picture 34 |
35 |
36 |
37 | {% endif %} 38 |
39 |
40 |
41 |
42 |
43 |

Contributions

44 |
    45 | {%- for vuln in vulns %} 46 |
  • 47 | {{ vuln.cve_id }} 48 | ({{ display_vuln_column(vuln, 'state') }}) 49 |
  • 50 | {% endfor %} 51 |
52 |
53 |
54 |
55 |
56 | {% endblock main_content %} 57 | -------------------------------------------------------------------------------- /templates/profile/proposals_view.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block main_content %} 3 | 4 | {% if not proposal_vulns.rows and not proposal_vulns_processed.rows %} 5 |
6 |
7 |
8 |
9 |
Looking for a way to create a proposal?
10 |
11 | You can create a new proposal by doing the following: 12 | 13 |
    14 |
  1. Search for/Choose an entry you would like to change on the start page. 15 |
  2. Press the Propose Changes button
  3. 16 |
  4. Do your changes
  5. 17 |
  6. Press the Propose Change button
  7. 18 |
19 |

Done! Now a reviewer will take a look at your changes 20 | and approve them or might give you feedback if there is 21 | something to improve.

22 |
23 |
24 |
25 |
26 |
27 | {% endif %} 28 |
29 |
30 |

My proposals

31 |
32 |
33 |
34 |
35 |
36 |
37 | {% from 'macros/generate_vuln_table.html' import display_vuln_table %} 38 | {% from 'macros/pagination.html' import display_nvd_pagination %} 39 |
40 |

Pending proposals

41 |
42 | {% set vuln_columns = ['date', 'id', 'summary', 'products', 'state'] %} 43 |
44 | {{ display_vuln_table(proposal_vulns.rows, 'proposal', vuln_columns, 'vuln.vuln_review') }} 45 | {{ display_nvd_pagination(proposal_vulns, 'proposal', '') }} 46 |
47 | 48 |
49 |

Processed proposals

50 |
51 | {% set vuln_columns = ['date', 'id', 'summary', 'products', 'state'] %} 52 |
53 | {{ display_vuln_table(proposal_vulns_processed.rows, 'proposal_processed', vuln_columns, 'vuln.vuln_review') }} 54 | {{ display_nvd_pagination(proposal_vulns_processed, 'proposal_processed', '') }} 55 |
56 |
57 |
58 |
59 |
60 | {% endblock %} 61 | -------------------------------------------------------------------------------- /templates/review/feedback_card.html: -------------------------------------------------------------------------------- 1 | {% from 'macros/user.html' import print_user %} 2 |
Review feedback
3 |
4 |
5 |
6 |
{{ vuln_view.date_modified }} by {{ print_user(vuln_view.feedback_reviewer) }}
7 | {{ vuln_view.review_feedback }} 8 |
9 |
10 |
11 | -------------------------------------------------------------------------------- /templates/review/list.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block main_content %} 3 |
4 |
5 |

Review

6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |

Pending proposals

14 |
15 | {% set vuln_columns = ['date', 'id', 'summary', 'products', 'state', 'creator'] %} 16 | 17 | {% from 'macros/generate_vuln_table.html' import display_vuln_table %} 18 | {% from 'macros/pagination.html' import display_nvd_pagination %} 19 |
20 | {{ display_vuln_table(review_vulns.rows, 'review', vuln_columns, 'vuln.vuln_review') }} 21 | {{ display_nvd_pagination(review_vulns, 'review', '') }} 22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |

Finished reviews

33 |
34 | {% set vuln_columns = ['date', 'id', 'summary', 'products', 'state', 'creator'] %} 35 | 36 | {% from 'macros/generate_vuln_table.html' import display_vuln_table %} 37 | {% from 'macros/pagination.html' import display_nvd_pagination %} 38 |
39 | {{ display_vuln_table(reviewed_vulns.rows, 'reviewed', vuln_columns, 'vuln.vuln_review') }} 40 | {{ display_nvd_pagination(reviewed_vulns, 'reviewed', '') }} 41 |
42 |
43 |
44 |
45 |
46 | {% endblock %} 47 | -------------------------------------------------------------------------------- /templates/terms.html: -------------------------------------------------------------------------------- 1 | {% import "bootstrap/wtf.html" as wtf %} 2 | 3 | {% extends "base_nonav.html" %} 4 | {% block main_content %} 5 |
6 |
7 |
8 |
9 | 10 |
11 | {{ form.hidden_tag() }} 12 | {{ wtf.form_errors(form, hiddens="only") }} 13 | {{ wtf.form_field(form.terms) }} 14 | {# { wtf.form_field(form.conditions) } #} 15 | 16 | 17 | 18 |
19 |
20 |
21 |
22 |
23 | {% endblock %} 24 | -------------------------------------------------------------------------------- /templates/vulnerability/code_editor.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block main_content %} 3 | {% if config.DEMO_MODE %} 4 |
5 |
6 | 10 |
11 |
12 | {% endif %} 13 | 14 |
15 |
16 | {% include 'vulnerability/info.html' %} 17 |
18 |
19 | 20 |
21 |
22 |
23 |
24 | {% include 'editor/file_tree.html' %} 25 |
26 |
27 |
28 | 29 |
30 |
31 |
32 | {% include 'editor/editor_container.html' %} 33 |
34 |
35 |
36 | 37 |
38 |
39 |
40 | {% include 'editor/metadata_edit.html' %} 41 |
42 |
43 |
44 |
45 | 46 | 47 | {% endblock %} -------------------------------------------------------------------------------- /templates/vulnerability/create.html: -------------------------------------------------------------------------------- 1 | {% import "bootstrap/wtf.html" as wtf %} 2 | 3 | {% extends "base.html" %} 4 | {% block main_content %} 5 | 6 | 7 |
8 |
9 |

Add a new vulnerability

10 |
11 |
12 | 13 |
14 |
15 |
16 |
17 | 18 |
19 | {{ form.hidden_tag() }} 20 | {{ wtf.form_errors(form, hiddens="only") }} 21 | 22 |

Commit Links

23 |
24 | {% for l in form.commits %} 25 | {{ wtf.form_field(l.form.commit_link) }} 26 | {{ wtf.form_field(l.form.repo_name) }} 27 | {{ wtf.form_field(l.form.repo_url) }} 28 | {{ wtf.form_field(l.form.commit_hash) }} 29 | {% endfor %} 30 |
31 | 32 |

Description

33 | {{ wtf.form_field(form.comment) }} 34 | TODO: Add CVE ID field back here! 35 | {# 36 | {{ wtf.form_field(form.cve_id) }} 37 | #} 38 | 39 | {# TODO: Enable this once custom resource links are supported again. 40 |

Misc

41 |
42 | {% for l in form.resources %} 43 | {{ wtf.form_field(l.form.link) }} 44 | {% endfor %} 45 |
46 | #} 47 | 48 | {{ wtf.form_field(form.submit, button_map={'submit':'primary'}) }} 49 |
50 | 51 | {% if vulnerability_details.vulnerability_view %} 52 |
54 | {{ form.hidden_tag() }} 55 | 56 | 57 |
58 | {% endif %} 59 | {# 60 | {{wtf.quick_form(form, 61 | button_map={'submit':'primary'}, 62 | extra_classes="w-100", 63 | form_type="basic" 64 | )}} 65 | #} 66 |
67 |
68 |
69 | 70 |
71 | {% include 'vulnerability/info.html' %} 72 |
73 |
74 | 75 | 76 | 77 | {% endblock %} 78 | -------------------------------------------------------------------------------- /templates/vulnerability/delete.html: -------------------------------------------------------------------------------- 1 | {% import "bootstrap/wtf.html" as wtf %} 2 | {# TODO: Consider using "custom_bootstrap_form.html" for customizations here. #} 3 | 4 | {% extends "base.html" %} 5 | 6 | {% set entry_type="proposal" if vuln_view.state.name in ['NEW', 'NEEDS_IMPROVEMENT', 'READY'] else "entry" %} 7 | 8 | {% block main_content %} 9 |
10 |
11 |

Delete entry

12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | 20 |

21 | Please confirm that you would like to delete the {{ entry_type}} for {{ vuln_view.id }} 22 |

23 | 24 | 25 |
26 |
27 |
28 |
29 |
30 | {% endblock %} 31 | -------------------------------------------------------------------------------- /templates/vulnerability/edit.html: -------------------------------------------------------------------------------- 1 | {% import "bootstrap/wtf.html" as wtf %} 2 | {# TODO: Consider using "custom_bootstrap_form.html" for customizations here. #} 3 | 4 | {% extends "base.html" %} 5 | {% block main_content %} 6 |
7 |
8 |

Propose changes

9 |
10 |
11 |
12 |
13 | {% set edit_mode = true %} 14 | {% include 'vulnerability/info.html' %} 15 |
16 |
17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /templates/vulnerability/embedded.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | {% include 'vulnerability/snippet.html' %} 58 | 59 | 64 | 65 | 66 | 67 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /templates/vulnerability/forms/code_location.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 11 |
12 |
13 | 14 |
15 | {% set commit_link = '' %} 16 | {% if form.commits|length > 0 and form.commits[0].data.commit_link %} 17 | {% set commit_link = form.commits[0].data.commit_link %} 18 | {% endif %} 19 | 20 |
21 | 22 | 27 | 28 | {# -- Git repository link support is TBD 29 | 43 | #} 44 |
45 |
46 | Show/hide examples 47 |
48 | 53 |
54 | 55 | 56 | -------------------------------------------------------------------------------- /templates/vulnerability/forms/product_search.html: -------------------------------------------------------------------------------- 1 | 50 | 51 |
52 | 53 | {# // https://github.com/mdn/interactive-examples/issues/887 and https://bugs.chromium.org/p/chromium/issues/detail?id=336876 #} 54 | 55 | 56 | 57 | 58 | 59 | 84 | -------------------------------------------------------------------------------- /templates/vulnerability/snippet.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 18 | 19 |
20 | 21 | 31 |
-------------------------------------------------------------------------------- /templates/vulnerability/view.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% set vuln_view = vulnerability_details.vulnerability_view %} 4 | {% if vuln_view %} 5 | {% block title %}{% set vuln_view = vulnerability_details.vulnerability_view %}{{ vuln_view.id }}{% endblock %} 6 | {% endif %} 7 | 8 | {% block main_content %} 9 |
10 |
11 | {% include 'vulnerability/info.html' %} 12 |
13 |
14 | 15 | {% if vulnerability_details.vulnerability_view %} 16 | {% block vulnerability_content %} 17 | {% endblock %} 18 | {% endif %} 19 | 20 | {% endblock %} 21 | -------------------------------------------------------------------------------- /templates/vulnerability/view_details.html: -------------------------------------------------------------------------------- 1 | {% extends "vulnerability/view.html" %} 2 | {% block vulnerability_content %} 3 | {% set vcdb_id = vulnerability_details.id %} 4 | {% set vuln_view = vulnerability_details.vulnerability_view %} 5 | {% set master_commit = vuln_view.master_commit %} 6 | {% if master_commit %} 7 |
8 |
9 |
10 |
11 | {% include 'editor/file_tree.html' %} 12 |
13 |
14 |
15 | 16 |
17 |
18 |
19 | {% include 'editor/editor_container.html' %} 20 |
21 |
22 |
23 | 24 |
25 |
26 |
27 | {% include 'editor/metadata_view.html' %} 28 |
29 |
30 |
31 |
32 | {% endif %} 33 | {% endblock %} 34 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /tests/app_tests/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /tests/app_tests/api/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /tests/app_tests/api/v1/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /tests/app_tests/auth/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /tests/app_tests/frontend/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /tests/app_tests/frontend/test_routes.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | import pytest 15 | 16 | 17 | @pytest.mark.integration 18 | @pytest.mark.production 19 | def test_index(client): 20 | resp = client.get("/") 21 | assert resp.status_code == 200 22 | 23 | 24 | @pytest.mark.integration 25 | @pytest.mark.production 26 | def test_list_entries(client): 27 | resp = client.get("/list_entries") 28 | assert resp.status_code == 200 29 | 30 | 31 | @pytest.mark.integration 32 | @pytest.mark.production 33 | def test_maintenance(client): 34 | resp = client.get("/maintenance") 35 | assert resp.status_code == 200 36 | assert b"Under maintenance" in resp.data 37 | 38 | 39 | @pytest.mark.integration 40 | @pytest.mark.production 41 | def test_static(client): 42 | resp = client.get("/static/js/main.js") 43 | assert resp.status_code == 200 44 | assert b"Copyright 2019 Google LLC" in resp.data 45 | 46 | 47 | @pytest.mark.integration 48 | @pytest.mark.production 49 | def test_static_not_found(client): 50 | resp = client.get("/static/js/foo.bar") 51 | assert resp.status_code == 404 52 | 53 | 54 | @pytest.mark.integration 55 | @pytest.mark.production 56 | def test_static_path_traversal(client): 57 | path = "../" * 100 58 | resp = client.get("/static/" + path + "etc/passwd") 59 | assert resp.status_code == 404 60 | -------------------------------------------------------------------------------- /tests/app_tests/product/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /tests/app_tests/product/test_routes.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | import pytest 15 | 16 | 17 | @pytest.mark.integration 18 | def test_existing_product_with_vulns(client): 19 | resp = client.get("/product/Vendor 1/Product 1") 20 | assert b"Vendor 1" in resp.data 21 | assert b"Product 1" in resp.data 22 | assert b"No results found" not in resp.data 23 | assert b"Annotated" in resp.data 24 | 25 | 26 | @pytest.mark.integration 27 | def test_existing_product_without_vulns(client): 28 | resp = client.get("/product/Vendor 11/Product 1") 29 | assert b"Vendor 11" in resp.data 30 | assert b"Product 1" in resp.data 31 | assert b"No results found" not in resp.data 32 | assert b"Annotated" in resp.data 33 | 34 | 35 | @pytest.mark.integration 36 | def test_non_existing_product(client): 37 | resp = client.get("/product/Vendor 1/No Product") 38 | assert b"Vendor 1" in resp.data 39 | assert b"No Product" in resp.data 40 | assert b"No results found" in resp.data 41 | 42 | 43 | @pytest.mark.integration 44 | def test_non_existing_vendor(client): 45 | resp = client.get("/product/No Vendor/Product 1") 46 | assert b"No Vendor" in resp.data 47 | assert b"Product 1" in resp.data 48 | assert b"No results found" in resp.data 49 | -------------------------------------------------------------------------------- /tests/app_tests/profile/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /tests/app_tests/profile/test_routes.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | import pytest 15 | 16 | from app.auth.routes import oauth 17 | from tests.conftest import as_user 18 | from tests.conftest import regular_user_info 19 | 20 | 21 | @pytest.mark.integration 22 | def test_show_proposals(client): 23 | # TODO: Add proper tests here. 24 | pass 25 | -------------------------------------------------------------------------------- /tests/app_tests/vulnerability/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /tests/app_tests/vulnerability/views/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /tests/data_tests/models/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /tests/data_tests/test_utils.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | from data.utils import populate_models 15 | 16 | 17 | def test_populate_models_returns_empty_array_on_unknown_module(): 18 | assert populate_models("this_module_does_not_exist") == [] 19 | 20 | 21 | def test_populate_models_returns_empty_array_on_invalid_modules(): 22 | assert populate_models("sys") == [] 23 | assert populate_models("lib") == [] 24 | assert populate_models("data") == [] 25 | 26 | 27 | def test_populate_models_returns_models(): 28 | models = populate_models("data.models") 29 | assert len(models) > 0 30 | assert "Vulnerability" in models 31 | assert "Nvd" in models 32 | -------------------------------------------------------------------------------- /tests/lib_tests/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /tests/misc_tests/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /tests/misc_tests/test_crawl_patches.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | import pytest 15 | import os 16 | 17 | 18 | @pytest.mark.integration 19 | def test_crawl_patches(client): 20 | # TODO: Add a rudimentary crawl_patches.py test here. 21 | pass 22 | -------------------------------------------------------------------------------- /tests/run_integration_tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | BASEDIR="$( cd "$( dirname "$0" )" && pwd )" 5 | export COOKIE_SECRET_KEY="${COOKIE_SECRET_KEY:-no so secret}" 6 | 7 | if [[ ! "${BASEDIR}" == "/app/tests" && -z "${SQLALCHEMY_DATABASE_URI}" && -z "${MYSQL_HOST}" ]]; then 8 | echo "[!] The tests currently require a MySQL backend." 9 | echo "[!] Please execute this instead through Docker with:" 10 | echo -e "\tdocker/docker-admin.sh test" 11 | echo "[!] or set SQLALCHEMY_DATABASE_URI or MYSQL_HOST" 12 | exit 13 | fi 14 | 15 | export SQLALCHEMY_DATABASE_URI="${SQLALCHEMY_DATABASE_URI:-mysql+mysqldb://${MYSQL_USER:-root}:${MYSQL_PWD:-test_db_pass}@${MYSQL_HOST}:${MYSQL_PORT:-3306}/main}" 16 | 17 | # Make sure we are in the project root directory before executing the test runner. 18 | cd ${BASEDIR}/../ 19 | 20 | # More pytest options: 21 | # -s: To disable stdout capturing / to always show stdout. 22 | # -k "keyword": Filter tests for a specific keyword. 23 | 24 | if [ "${TEST_FILTER}" != "" ] 25 | then 26 | TEST_ARGS="${TEST_ARGS} -k ${TEST_FILTER}" 27 | fi 28 | args=( $TEST_ARGS ) 29 | 30 | pytest -vv \ 31 | --cov-config=.coveragerc \ 32 | --cov-report html \ 33 | --cov=app \ 34 | --cov=lib \ 35 | --cov=data \ 36 | --cov=templates \ 37 | --log-level=DEBUG \ 38 | --color=yes \ 39 | "${args[@]}" \ 40 | tests 41 | -------------------------------------------------------------------------------- /tests/run_production_tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | BASEDIR="$( cd "$( dirname "$0" )" && pwd )" 5 | 6 | # TODO: Remove the database dependency once the pytest fixture issue in conftest.py was resolved. 7 | if [[ ! "${BASEDIR}" == "/app/tests" ]]; then 8 | echo "[!] The tests currently require a MySQL backend." 9 | echo "[!] Please execute this instead through Docker with:" 10 | echo -e "\tdocker/docker-admin.sh test" 11 | exit 12 | fi 13 | 14 | # Make sure we are in the project root directory before executing the test runner. 15 | cd ${BASEDIR}/../ 16 | 17 | pytest -vv \ 18 | --cov-config=.coveragerc \ 19 | --cov-report html \ 20 | --cov=app \ 21 | --cov=lib \ 22 | --cov=data \ 23 | --cov=templates \ 24 | --log-level=DEBUG \ 25 | --color=yes \ 26 | -m 'production' \ 27 | tests 28 | -------------------------------------------------------------------------------- /tests/run_unit_tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | BASEDIR="$( cd "$( dirname "$0" )" && pwd )" 5 | 6 | # Make sure we are in the project root directory before executing the test runner. 7 | cd ${BASEDIR}/../ 8 | 9 | export COOKIE_SECRET_KEY=not-so-secret 10 | 11 | pytest \ 12 | --cov-config=.coveragerc \ 13 | --cov-report html \ 14 | --cov=app \ 15 | --cov=lib \ 16 | --cov=data \ 17 | --color=yes \ 18 | -m 'not integration' \ 19 | tests "$@" 20 | --------------------------------------------------------------------------------