├── .gitignore ├── LICENSE ├── README.md ├── bash ├── api.sh ├── src │ ├── api-git.sh │ ├── api-svn.sh │ ├── api-veracode.sh │ ├── legacy-version.sh │ ├── veracode-format.sh │ ├── veracode-tools.sh │ └── veracode-utils.sh └── test │ ├── test-api.sh │ └── test-veracode-api.sh ├── node ├── create-reports.coffee ├── package.json ├── src │ ├── Chart-Engine.coffee │ ├── Veracode-Scan-Charts.coffee │ ├── Veracode-Scan-Report.coffee │ ├── Veracode-Usage-Reports.coffee │ ├── bar_chart.png │ ├── chart.png │ ├── models │ │ └── Usage-Report.model.coffee │ └── test.md ├── test │ ├── Chart-Engine.test.coffee │ ├── Veracode-Scan-Report.test.coffee │ ├── Veracode-Usage-Reports.test.coffee │ ├── Veracode_Scan_Charts.test.coffee │ ├── chart.png │ └── models │ │ └── Usage-Report.model.test.coffee └── wallaby.js └── test-bash.sh /.gitignore: -------------------------------------------------------------------------------- 1 | repos 2 | node/node_modules 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # veracode-API 2 | API to access Veracode REST API and veracode-ui issues 3 | 4 | The current version of the API is bash based, but the idea is to rewrite parts of it in Node or Python. 5 | 6 | ### Example of scan file 7 | 8 | * For Java/Maven based app 9 | 10 | ```bash 11 | #!/usr/bin/env bash 12 | 13 | . ./scan/api-veracode-xyz.sh 14 | 15 | PROJECT=xxxxx 16 | REPO_NAME=aaaa-bbbb-ccc 17 | APP_ID=123456 18 | 19 | function build_Files { 20 | build_Dependency "aaaa-common" "1.6.2" 21 | build_Dependency "aaaa-bbbb-security" "1.9" 22 | 23 | mvn install -DskipTests -Dcheckstyle.skip=true 24 | } 25 | 26 | function zip_Targets { 27 | rm $TARGET_FILE 28 | zip -r $TARGET_FILE ./target/aaaa-bbbb-ccc-1.0.0-SNAPSHOT.jar 29 | } 30 | 31 | setup 32 | clone 33 | build_Files 34 | zip_Targets 35 | trigger_Scan 36 | ``` 37 | 38 | * for NodeJS project 39 | 40 | ```bash 41 | 42 | #!/usr/bin/env bash 43 | 44 | . ./scan/api-veracode-xyz.sh 45 | 46 | PROJECT=xxx 47 | REPO_NAME=aaaaa 48 | APP_ID=12345 49 | 50 | 51 | function zip_Targets { 52 | rm $TARGET_FILE 53 | zip -r $TARGET_FILE server.js 54 | zip -r $TARGET_FILE app server shared 55 | } 56 | 57 | setup 58 | clone 59 | zip_Targets 60 | trigger_Scan 61 | ``` 62 | 63 | 64 | ### using veracode api as REPL 65 | 66 | * install it on cmd line: ```cd ./api/bash/;. api.sh; cd ../..``` 67 | * set veracode credentials: ```export API_USERNAME=xxx.xx@xxxx.xx.xxx``` and ```export API_PASSWORD=xxxx``` 68 | * list of current veracode apps: ```veracode-app-list``` 69 | 70 | current list of commands 71 | 72 | ``` 73 | veracode-api-invoke-v5 veracode-app-build-begin-prescan 74 | veracode-app-build-info veracode-app-info 75 | veracode-create-app veracode-api-invoke-F 76 | veracode-app-build-begin-scan veracode-app-build-prescan-results 77 | veracode-app-list veracode-app-build 78 | veracode-app-build-in-sandbox veracode-app-upload-file 79 | veracode-app-sandboxes 80 | ``` 81 | 82 | **Common actions/workflows**: 83 | 84 | * get list of apps: ```veracode-apps``` 85 | * format result 86 | * get app info: ```format-xml "$(veracode-app-info {app_id})"``` 87 | * invoke method directly: 88 | * ```format-xml "$(veracode-api-invoke-v5 getprescanresults app_id={app_id})"``` 89 | * ```format-xml "$(veracode-api-invoke-v5 getbuildlist app_id={app_id})"``` 90 | * ```format-xml "$(veracode-api-invoke-v5 getbuilddetails app_id={app_id})"``` 91 | * ```format-xml "$(veracode-api-invoke-v4 getappbuilds)"``` 92 | 93 | 94 | ### Resources 95 | 96 | * API Automation script - https://github.com/aparsons/veracode (in bash) 97 | * Other authomation scripts - https://github.com/OnLineStrategies/veracode-scripts (in phython) 98 | * Jenkins plugin - https://github.com/mbockus/veracode-scanner 99 | 100 | -------------------------------------------------------------------------------- /bash/api.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . ./src/api-git.sh 3 | . ./src/api-svn.sh 4 | 5 | . ./src/api-veracode.sh 6 | . ./src/veracode-format.sh 7 | . ./src/veracode-tools.sh 8 | . ./src/veracode-utils.sh 9 | -------------------------------------------------------------------------------- /bash/src/api-git.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Emails the reports 4 | 5 | function git-clone { 6 | git clone $1 $2 7 | } 8 | 9 | # This will clone if the repo doesn't exist, or pull it if it exists 10 | function git-clone-or-pull { 11 | if ! [[ -d "$2" ]]; then 12 | echo "> Cloning $1 into folder $2" 13 | git clone $1 $2 14 | else 15 | local current_Folder=`pwd` 16 | echo current_Folder is $current_Folder 17 | cd $2 18 | echo "> Pulling $1 located at folder $2" 19 | git pull 20 | cd $current_Folder 21 | fi 22 | } 23 | 24 | function git-version { 25 | git version 26 | } 27 | -------------------------------------------------------------------------------- /bash/src/api-svn.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Emails the reports 4 | 5 | function svn-checkout { 6 | svn checkout $1 $2 7 | } 8 | 9 | # This will checkout if the repo doesn't exist, or update it if it exists 10 | function svn-checkout-or-update { 11 | if ! [[ -d "$2" ]]; then 12 | echo "> Checking $1 into folder $2" 13 | svn checkout $1 $2 14 | else 15 | local current_Folder=`pwd` 16 | echo current_Folder is $current_Folder 17 | cd $2 18 | echo "> Updating $1 located at folder $2" 19 | svn update 20 | cd $current_Folder 21 | fi 22 | } 23 | 24 | function svn-version { 25 | svn --version 26 | } 27 | -------------------------------------------------------------------------------- /bash/src/api-veracode.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # command line api 4 | 5 | function veracode-app-builds { 6 | raw_xml=$(veracode-api-invoke-v4 getappbuilds) 7 | 8 | format-veracode-app-builds "$raw_xml" 9 | } 10 | 11 | function veracode-app-create { 12 | local appName="$1" 13 | raw_xml=$(veracode-api-invoke-v5 createapp app_name="$appName&business_criticality=Very+High") 14 | format-veracode-app-create "$raw_xml" 15 | } 16 | 17 | function veracode-app-delete { 18 | local id_or_name="$1" 19 | 20 | local raw_xml=$(veracode-api-invoke-v5 deleteapp app_id="$id_or_name") # try do delete as if $id_or_name is an id 21 | 22 | if [[ $raw_xml =~ .*\No.app_id.parameter.specified\.* ]] ; then # if we get an No app_id parameter specified error message 23 | local app_id=$(veracode-app-id "$id_or_name") # try to resolve the name to an id 24 | raw_xml=$(veracode-api-invoke-v5 deleteapp app_id="$app_id") # try to delete is with the resolved id 25 | fi 26 | format-veracode-app-delete "$raw_xml" 27 | 28 | 29 | } 30 | 31 | function veracode-app-id { 32 | local app_Name=$1 33 | local data="$(veracode-api-invoke-v5 getapplist)" # get data using curl 34 | get-value-from-string "$data" "$app_Name" 2 # call get-value-from-string method 35 | } 36 | 37 | function veracode-app-id-create-if-required { 38 | local app_name=$1 39 | app_id=$(veracode-app-id "$app_name") # try to get the id 40 | if [[ "$app_id" != "" ]]; then # if we got a value back 41 | echo "$app_id" # it means it existed, so we just need to echo its value 42 | else # if not, we need to created it 43 | veracode-create-app $app_name # note: veracode-create-app will echo the new app id 44 | 45 | fi 46 | } 47 | 48 | function veracode-app-ids { 49 | raw_xml=$(veracode-api-invoke-v5 getapplist) 50 | format-veracode-app-ids "$raw_xml" 51 | } 52 | 53 | function veracode-app-info { 54 | local appId="$1" 55 | veracode-api-invoke-v5 getappinfo app_id="$appId" 56 | } 57 | 58 | function veracode-app-list { 59 | raw_xml=$(veracode-api-invoke-v5 getapplist) 60 | format-veracode-app-list "$raw_xml" 61 | } 62 | 63 | function veracode-app-names { 64 | raw_xml=$(veracode-api-invoke-v5 getapplist) 65 | format-veracode-app-names "$raw_xml" 66 | } 67 | 68 | 69 | function veracode-app-sandboxes { 70 | local appId="$1" 71 | veracode-api-invoke-v5 getsandboxlist app_id="$appId" 72 | } 73 | 74 | 75 | function veracode-app-build { 76 | local appId="$1" 77 | local sandboxId="$2" 78 | local version=`date "+%Y-%m-%d %T"` 79 | veracode-api-invoke-v5 createbuild app_id="$appId"&version="$version" 80 | } 81 | 82 | function veracode-app-build-in-sandbox { 83 | local appId="$1" 84 | local sandboxId="$2" 85 | local version=`date "+%Y-%m-%d %T"` 86 | veracode-api-invoke-v5 createbuild app_id="$appId"&version="$version"&sandbox_id="$sandboxId" 87 | } 88 | 89 | function veracode-app-build-begin-prescan { 90 | local appId="$1" 91 | raw_xml=$(veracode-api-invoke-v5 beginprescan "app_id=$appId&auto_scan=true&scan_all_nonfatal_top_level_modules=true") 92 | 93 | format-veracode-app-build-info "$raw_xml" 94 | } 95 | 96 | function veracode-app-build-begin-scan { 97 | local appId="$1" 98 | if [[ "$2" != "" ]]; then 99 | local target="modules=$2" 100 | else 101 | local target="scan_all_top_level_modules=true" 102 | fi 103 | 104 | #local all_modules="scan_all_top_level_modules=true" 105 | veracode-api-invoke-v5 beginscan "app_id=$appId&$target" 106 | } 107 | 108 | function veracode-app-build-delete { 109 | local appId="$1" 110 | veracode-api-invoke-v5 deletebuild "app_id=$appId" 111 | } 112 | 113 | function veracode-download { 114 | local app_name="$1" 115 | #delete_after_download="$2" 116 | 117 | local app_id=$(veracode-app-id "$app_name") 118 | 119 | if [[ "$app_id" == "" ]]; then 120 | echo "Error: could not resolve app with name $app_name" 121 | echo 122 | else 123 | 124 | #local build_id=$(veracode-scan-last-build-id "$1") 125 | 126 | local build_info=$(veracode-api-invoke-v5 getbuildinfo "app_id=$app_id") 127 | local build_id=$(format-veracode-app-build-id "$build_info") 128 | 129 | local target_folder="./reports/${app_name}/$build_id" 130 | if [ -d "$target_folder" ]; then 131 | echo "[Skipping] report has already been downloaded: app_name = $app_name ; app_id = $app_id ; build_id = $build_id" 132 | else 133 | echo " * last build_id $build_id" 134 | 135 | veracode-download-all-files "$app_name" "$app_id" "$build_id" 136 | veracode-scan-save-all_call-stacks "$app_name" "$app_id" "$build_id" 137 | 138 | # if [[ "$delete_after_download" == "delete" ]]; then 139 | # echo "Deleting application $app_name with $app_id" 140 | # veracode-delete-app $app_id 141 | # fi 142 | fi 143 | fi 144 | } 145 | 146 | function veracode-download-latest-reports { 147 | echo 148 | echo " Downloading all latest reports " 149 | echo "---------------------------------------------" 150 | local all_apps=$(veracode-apps) 151 | for app_name in $all_apps; 152 | do 153 | echo "---------------------------------------------" 154 | echo " * processing app: $app_name" 155 | 156 | exit -1 157 | done 158 | } 159 | 160 | function veracode-download-all-completed { 161 | delete_after_download="$1" 162 | local all_apps=$(veracode-apps) 163 | for app_name in $all_apps; 164 | do 165 | echo "---------------------------------------------" 166 | echo " * processing app: $app_name" 167 | local app_id=$(veracode-app-id "$app_name") 168 | echo " * app_id: $app_id" 169 | if [[ "$app_id" != "" ]]; then 170 | local app_status=$(veracode-app-build-status $app_id) 171 | echo " * current status: $app_status" 172 | if [[ "$app_status" == "Results Ready" ]]; then 173 | echo 174 | veracode-download $app_name #$delete_after_download 175 | echo 176 | else 177 | echo " * skipping due to status being $app_status" 178 | fi 179 | fi 180 | done 181 | 182 | } 183 | 184 | function veracode-download-all-files { 185 | local app_name="$1" 186 | local app_id="$2" 187 | local build_id="$3" 188 | #local app_id=$(veracode-app-id "$app_name") 189 | 190 | #local build_info=$(veracode-api-invoke-v5 getbuildinfo "app_id=$app_id") 191 | #local build_id=$(format-veracode-app-build-id "$build_info") 192 | 193 | echo "Downloading report files for: app_name = $app_name ; app_id = $app_id ; build_id = $build_id" 194 | echo 195 | veracode-download-pdf-detailed "$app_name" "$app_id" "$build_id" 196 | veracode-download-pdf-summary "$app_name" "$app_id" "$build_id" 197 | veracode-download-xml-detailed "$app_name" "$app_id" "$build_id" 198 | veracode-download-xml-summary "$app_name" "$app_id" "$build_id" 199 | #veracode-download-pdf-3rd-party "$1" 200 | echo 201 | 202 | } 203 | 204 | function veracode-download-file { 205 | 206 | local command=$1 207 | local app_name="$2" 208 | local file_suffix="$3" 209 | local app_id="$4" 210 | local build_id="$5" 211 | 212 | local target_folder="./reports/${app_name}/$build_id" 213 | local target_file="$target_folder/$file_suffix" 214 | local latest_file="./reports/${app_name}/last_build_id" 215 | echo " - $command to location $target_file" 216 | 217 | mkdir -p "$target_folder" 218 | veracode-api-download "2.0" "$command" "build_id=$build_id" "$target_file" 219 | 220 | if [[ $file_suffix =~ ".xml" ]]; then # fix xml formatting 221 | echo "$(format-xml "$(cat $target_file)")" > $target_file 222 | fi 223 | echo $build_id > $latest_file 224 | 225 | } 226 | 227 | function veracode-download-pdf-detailed { veracode-download-file detailedreportpdf "$1" "detailed.pdf" $2 $3 ; } 228 | function veracode-download-pdf-summary { veracode-download-file summaryreportpdf "$1" "summary.pdf" $2 $3 ; } 229 | function veracode-download-pdf-3rd-party { veracode-download-file thirdpartyreportpdf "$1" "3rd-party.pdf" $2 $3 ; } 230 | function veracode-download-xml-detailed { veracode-download-file detailedreport "$1" "detailed.xml" $2 $3 ; } 231 | function veracode-download-xml-summary { veracode-download-file summaryreport "$1" "summary.xml" $2 $3 ; } 232 | 233 | 234 | 235 | function veracode-app-build-info { 236 | local appId="$1" 237 | raw_xml=$(veracode-api-invoke-v5 getbuildinfo "app_id=$appId") 238 | 239 | format-veracode-app-build-info "$raw_xml" 240 | } 241 | 242 | 243 | function veracode-app-build-files { 244 | local appId="$1" 245 | raw_xml=$(veracode-api-invoke-v5 getfilelist "app_id=$appId") 246 | veracode-format-file-list "$raw_xml" 247 | } 248 | 249 | function veracode-app-build-prescan-results { 250 | local appId="$1" 251 | veracode-api-invoke-v5 getprescanresults "app_id=$appId" 252 | } 253 | 254 | function veracode-app-build-status { 255 | local appId="$1" 256 | raw_xml=$(veracode-api-invoke-v5 getbuildinfo "app_id=$appId") 257 | 258 | local formatted_xml=$(format-xml "$raw_xml") 259 | status=$(attribute-value "$formatted_xml" "analysis_unit" "status") 260 | echo "$status" 261 | } 262 | 263 | function veracode-app-build-status-all { 264 | local all_apps=$(veracode-apps) 265 | # this should be in the veracode-format.sh but the results take some time to load so it is better to have it showing one line at the time 266 | echo "App id App Name Scan status" 267 | echo ------------------------------------------------------------------- 268 | for app_name in $all_apps; 269 | do 270 | local app_id=$(veracode-app-id "$app_name") 271 | if [[ "$app_id" != "" ]]; then 272 | local app_status=$(veracode-app-build-status $app_id) 273 | printf "%-10s %-30s %-30s \n" "$app_id" "$app_name" "$app_status" 274 | fi 275 | done 276 | echo 277 | } 278 | 279 | function veracode-app-upload-file { 280 | local appId="$1" 281 | local file="$2" 282 | raw_xml=$(veracode-api-invoke-v5-F uploadfile "app_id=$appId -F file=@$file") 283 | veracode-format-file-list "$raw_xml" 284 | } 285 | 286 | 287 | function veracode-scan-call-stack { 288 | local build_id="$1" 289 | local flaw_id="$2" 290 | raw_xml=$(veracode-api-invoke-v4 getcallstacks "build_id=$build_id&flaw_id=$flaw_id") 291 | echo "$(format-xml "$raw_xml")" 292 | } 293 | 294 | function veracode-scan-history-download { 295 | echo 296 | local target_folder="./reports/_scan_history" 297 | local download_token="${target_folder}/_download_token" 298 | local latest_report="${target_folder}/_latest_report" 299 | local latest_report_csv="${target_folder}/_latest_report.csv" 300 | 301 | # return codes 302 | # 0 - report downloaded ok 303 | # 1 - download token not found 304 | # 2 - invalid credentials 305 | # 3 - invalid token 306 | # 4 - report not yet available 307 | # 5 - failed to download after x attempts 308 | 309 | #cp ${latest_report} ${download_token} 310 | 311 | if ! [[ -f "$download_token" ]]; then 312 | echo "Download_token file doesn't exist, skipping check (please created it using veracode-scan-history-generate)" 313 | echo 314 | return 1 315 | else 316 | token=$(cat ${download_token}) 317 | local target_file="${target_folder}/${token}.csv" 318 | #echo "... found download_token: ${token}" 319 | 320 | report=$(veracode-api-invoke-v4 downloadcustomreport token=$token) 321 | 322 | if [[ $report =~ .*\Request.requires.HTTP.authentication.\.* ]] ; then 323 | echo 'Error - Invalid credentials (Http authentication failed)' 324 | return 2 325 | else 326 | if [[ $report =~ .*\Please.provide.a.valid.report.token.\<\/error\>.* ]] ; then 327 | echo "Error - Invalid token: $token" 328 | return 3 329 | else 330 | 331 | if [[ "$report" != "" ]]; then 332 | echo $report > ${target_file} 333 | echo "... saved original report to ${target_file}" 334 | mv ${download_token} ${latest_report} 335 | cp ${target_file} ${latest_report_csv} 336 | echo "... saved updated report to ${latest_report_csv}" 337 | return 0 338 | else 339 | echo "report NOT available for token $token . Please try later" 340 | return 4 341 | fi 342 | fi 343 | fi 344 | fi 345 | } 346 | 347 | function veracode-scan-history-download-loop 348 | { 349 | local number_attempts=100 350 | local sleep_value=10 351 | for i in `seq 1 $number_attempts`; 352 | do 353 | veracode-scan-history-download 354 | local status="$?" 355 | if [[ "$status" == "0" ]]; then 356 | #echo "Report downloaded ok" 357 | return 0 358 | else 359 | if [[ "$status" == "1" ]]; then 360 | #echo "No report to download" 361 | return 0 362 | else 363 | if [[ "$status" == "4" ]]; then 364 | echo "[#${i}] Waiting ${sleep_value}s for report" 365 | sleep $sleep_value 366 | else 367 | #echo "Download failed" 368 | return $status 369 | fi 370 | fi 371 | fi 372 | done 373 | echo "Error Failed to download after #{number_attempts}" 374 | exit 1 375 | } 376 | 377 | function veracode-scan-history-generate { 378 | 379 | echo 380 | local target_folder="./reports/_scan_history" 381 | local download_token="${target_folder}/_download_token" 382 | mkdir -p "$target_folder" 383 | 384 | 385 | if [[ -f "$download_token" ]]; then 386 | echo "download_token file already exist, download that file first: ${download_token}" 387 | echo 388 | else 389 | raw_xml=$(veracode-api-invoke-v4 generatecustomreport report_identifier=scan_history) 390 | token=$(veracode-format-scan-history-token "$raw_xml") 391 | if [[ "$token" != "" ]]; then 392 | echo ${token} > $download_token 393 | echo "Token value saved to ${download_token}" 394 | echo "To download use: veracode-scan-history-download" 395 | else 396 | echo "Token generation failed" 397 | fi 398 | fi 399 | #raw_xml=$(veracode-api-invoke-v4 generatecustomreport #report_identifier=scan_history) 400 | #veracode-format-scan-history-token "$raw_xml" 401 | } 402 | 403 | function veracode-scan-save-call-stack { 404 | local app_name="$1" 405 | local build_id="$2" 406 | # local build_id=$(veracode-scan-last-build-id "$1") 407 | local flaw_id="$3" 408 | local raw_xml=$(veracode-scan-call-stack $build_id $flaw_id) 409 | 410 | if [[ $raw_xml =~ .*\ ]]; then 411 | echo "Error downloading flaw with id $flaw_id: $raw_xml" 412 | else 413 | local target_folder=local target_folder="./reports/${app_name}/$build_id/call-stacks" 414 | local target_file="$target_folder/$flaw_id.xml" 415 | mkdir -p $target_folder 416 | echo "$(format-xml "$raw_xml")" > $target_file 417 | echo " * saved call-stack with flaw_id $flaw_id to $target_file" 418 | fi 419 | } 420 | 421 | function veracode-scan-save-all_call-stacks { 422 | local app_name="$1" 423 | local app_id="$2" 424 | local build_id="$3" 425 | local total_flaws=$(veracode-scan-total-flaws $app_name) 426 | echo "Downloading call-stacks" 427 | echo 428 | if [[ "$total_flaws" == "0" ]]; then 429 | echo " - no flaws to download" 430 | else 431 | echo " - downloading $total_flaws call stacks from $app_name" 432 | for i in `seq 1 $total_flaws`; 433 | do 434 | veracode-scan-save-call-stack "$app_name" "$build_id" "$i" 435 | done 436 | fi 437 | echo 438 | } 439 | 440 | function veracode-scan-last-build-id { 441 | local app_name="$1" 442 | local target_folder="./reports/${app_name}/$build_id" 443 | local latest_file="./reports/${app_name}/last_build_id" 444 | echo $(cat $latest_file) 445 | } 446 | 447 | function veracode-scan-total-flaws { 448 | local app_name="$1" 449 | local target_folder="./reports/${app_name}/$build_id" 450 | local latest_file="./reports/${app_name}/last_build_id" 451 | local last_build_id=$(cat $latest_file) 452 | local summary_xml="./reports/${app_name}/$last_build_id/summary.xml" 453 | 454 | local raw_xml="$(cat $summary_xml)" 455 | 456 | echo $(attribute-value "$raw_xml" "summaryreport" "total_flaws") 457 | 458 | } 459 | # similar methods with different signatures (the idea is to make the method name as intuitive as possible) 460 | 461 | function veracode-apps { veracode-app-names ; } 462 | function veracode-builds { veracode-app-builds ; } 463 | function veracode-create-app { veracode-app-create $1; } 464 | function veracode-delete-app { veracode-app-delete $1; } 465 | function veracode-delete-build { veracode-app-build-delete $1; } 466 | function veracode-list { veracode-app-list ; } 467 | function veracode-status { veracode-app-build-status-all $1; } 468 | 469 | -------------------------------------------------------------------------------- /bash/src/legacy-version.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | #### ORIGINAL METHODS#### 4 | 5 | # based on code from https://github.com/aparsons/Veracode/blob/master/shell/veracode.sh 6 | # Veracode Upload, version 1.2 7 | # Adam Parsons, adam@aparsons.net 8 | 9 | # CHANGE THESE SETTINGS TO MATCH YOUR CONFIGURATION 10 | 11 | #APP_ID= 12 | #API_USERNAME="" 13 | #API_PASSWORD="" 14 | PRESCAN_SLEEP_TIME=300 15 | SCAN_SLEEP_TIME=300 16 | 17 | function setup_tmp { 18 | # Directory argument 19 | if [[ "$1" != "" ]]; then 20 | UPLOAD_DIR="$1" 21 | else 22 | echo "[-] Directory not specified." 23 | exit 1 24 | fi 25 | 26 | # Check if directory exists 27 | if ! [[ -d "$UPLOAD_DIR" ]]; then 28 | echo "[-] Directory does not exist" 29 | exit 1 30 | fi 31 | 32 | # Version argument 33 | if [[ "$2" != "" ]]; then 34 | VERSION="$2" 35 | else 36 | VERSION=`date "+%Y-%m-%d %T"` # Use date as default 37 | fi 38 | 39 | 40 | RESULTS_DIR="$(pwd)"/results/"$VERSION" 41 | 42 | DETAILED_REPORT_PDF_FILE="$RESULTS_DIR"/"veracode.detailed.pdf" 43 | DETAILED_REPORT_XML_FILE="$RESULTS_DIR"/"veracode.detailed.xml" 44 | SUMMARY_REPORT_PDF_FILE="$RESULTS_DIR"/"veracode.summary.pdf" 45 | } 46 | 47 | # Email Settings (Disabled, uncomment at the bottom to enable) 48 | SUBJECT="Veracode Results ($VERSION)" 49 | TO_ADDR="" 50 | FROM_ADDR="" 51 | 52 | # Validate HTTP response 53 | function validate_response { 54 | local response="$1" 55 | 56 | # Check if response is XML 57 | if ! [[ "$response" =~ (\<\?xml version=\"1\.0\" encoding=\"UTF-8\"\?\>) ]]; then 58 | echo "[-] Response body is not XML format at `date`" 59 | echo "$response" 60 | #exit 1 61 | fi 62 | 63 | # Check for an error element 64 | if [[ "$response" =~ ([a-zA-Z0-9 \.]+) ]]; then 65 | local error=$(echo $response | sed -n 's/.*\(.*\)<\/error>.*/\1/p') 66 | echo "[-] Error: $error" 67 | exit 1 68 | fi 69 | } 70 | 71 | # Checks the state of the application prior to attempting to create a new build 72 | function check_state { 73 | echo "[+] Checking application build state" 74 | local build_info_response=`curl --silent --compressed -u "$API_USERNAME:$API_PASSWORD" https://analysiscenter.veracode.com/api/4.0/getbuildinfo.do --data "app_id=$APP_ID"` 75 | validate_response "$build_info_response" 76 | 77 | if ! [[ "$build_info_response" =~ (\) ]]; then 78 | echo "[+] Removing latest build" 79 | local delete_build_response=`curl --silent --compressed -u "$API_USERNAME:$API_PASSWORD" https://analysiscenter.veracode.com/api/4.0/deletebuild.do --data "app_id=$APP_ID"` 80 | validate_response "$delete_build_response" 81 | fi 82 | } 83 | 84 | # Create new build 85 | function createbuild { 86 | echo "[+] Creating a new Veracode build named \"$VERSION\" for application #$APP_ID" 87 | 88 | local create_build_response=`curl --silent --compressed -u "$API_USERNAME:$API_PASSWORD" https://analysiscenter.veracode.com/api/4.0/createbuild.do --data "app_id=$APP_ID&version=$VERSION"` 89 | validate_response "$create_build_response" 90 | 91 | # Extract build id 92 | BUILD_ID=$(echo $create_build_response | sed -n 's/.* build_id=\"\([0-9]*\)\" .*/\1/p') 93 | } 94 | 95 | # Upload files 96 | function uploadfile { 97 | file $1 98 | echo "> uploading $file to scan $APP_ID" 99 | return 100 | # do 101 | # if [[ -f "$file" ]]; then 102 | # echo "[+] Uploading $file" 103 | # local upload_file_response=`curl --compressed -u "$API_USERNAME:$API_PASSWORD" https://analysiscenter.veracode.com/api/4.0/uploadfile.do -F "app_id=$APP_ID" -F "file=@$file"` 104 | # validate_response "$upload_file_response" 105 | # fi 106 | # done 107 | # 108 | # # Validate all files were successfully uploaded 109 | # for file in $UPLOAD_DIR/* 110 | # do 111 | # if [[ -f "$file" ]]; then 112 | # if ! [[ "$upload_file_response" =~ (\) ]]; then 113 | # echo "[-] Error uploading $file" 114 | # exit 1 115 | # fi 116 | # fi 117 | # done 118 | } 119 | 120 | # Upload files 121 | function uploadfiles { 122 | for file in $UPLOAD_DIR/* 123 | do 124 | if [[ -f "$file" ]]; then 125 | echo "[+] Uploading $file" 126 | local upload_file_response=`curl --compressed -u "$API_USERNAME:$API_PASSWORD" https://analysiscenter.veracode.com/api/4.0/uploadfile.do -F "app_id=$APP_ID" -F "file=@$file"` 127 | validate_response "$upload_file_response" 128 | fi 129 | done 130 | 131 | # Validate all files were successfully uploaded 132 | for file in $UPLOAD_DIR/* 133 | do 134 | if [[ -f "$file" ]]; then 135 | if ! [[ "$upload_file_response" =~ (\) ]]; then 136 | echo "[-] Error uploading $file" 137 | exit 1 138 | fi 139 | fi 140 | done 141 | } 142 | 143 | # Begin pre-scan 144 | function beginprescan { 145 | echo "[+] Starting pre-scan of uploaded files" 146 | local pre_scan_response=`curl --silent --compressed -u "$API_USERNAME:$API_PASSWORD" https://analysiscenter.veracode.com/api/4.0/beginprescan.do --data "app_id=$APP_ID"` 147 | validate_response "$pre_scan_response" 148 | } 149 | 150 | # Poll pre-scan status 151 | function pollprescan { 152 | echo "[+] Polling pre-scan status every $PRESCAN_SLEEP_TIME seconds" 153 | local is_pre_scanning=true 154 | while $is_pre_scanning; do 155 | sleep $PRESCAN_SLEEP_TIME 156 | 157 | local build_info_response=` curl --silent --compressed -u "$API_USERNAME:$API_PASSWORD" https://analysiscenter.veracode.com/api/4.0/getbuildinfo.do --data "app_id=$APP_ID"` 158 | validate_response "$build_info_response" 159 | 160 | # Check if pre-scan is successful 161 | if [[ "$build_info_response" =~ (\) ]]; then 162 | is_pre_scanning=false 163 | echo -e "\n[+] Pre-scan complete" 164 | else 165 | echo -n -e "." 166 | fi 167 | done 168 | } 169 | 170 | # Begin application scan 171 | function beginscan { 172 | echo "[+] Starting scan of uploaded files" 173 | local begin_scan_response=`curl --silent --compressed -u "$API_USERNAME:$API_PASSWORD" https://analysiscenter.veracode.com/api/4.0/beginscan.do --data "app_id=$APP_ID&scan_all_top_level_modules=true"` 174 | validate_response "$begin_scan_response" 175 | } 176 | 177 | # Poll scan status 178 | function pollscan { 179 | echo "[+] Polling scan status every $SCAN_SLEEP_TIME seconds" 180 | local is_scanning=true 181 | while $is_scanning; do 182 | sleep $SCAN_SLEEP_TIME 183 | 184 | local build_info_response=`curl --silent --compressed -u "$API_USERNAME:$API_PASSWORD" https://analysiscenter.veracode.com/api/4.0/getbuildinfo.do --data "app_id=$APP_ID"` 185 | validate_response "$build_info_response" 186 | if [[ "$build_info_response" =~ (\) ]]; then 187 | is_scanning=false 188 | echo -e "\n[+] Scan complete" 189 | else 190 | echo -n -e "." 191 | fi 192 | done 193 | } 194 | 195 | # Download reports 196 | function download { 197 | if ! [[ -d "$RESULTS_DIR" ]]; then 198 | mkdir -p "$RESULTS_DIR" 199 | fi 200 | 201 | echo "[+] Downloading detailed report PDF" 202 | curl --compressed -o "$DETAILED_REPORT_PDF_FILE" -u "$API_USERNAME:$API_PASSWORD" https://analysiscenter.veracode.com/api/2.0/detailedreportpdf.do?build_id=$BUILD_ID 203 | 204 | echo "[+] Downloading detailed report XML" 205 | curl --compressed -o "$DETAILED_REPORT_XML_FILE" -u "$API_USERNAME:$API_PASSWORD" https://analysiscenter.veracode.com/api/2.0/detailedreport.do?build_id=$BUILD_ID 206 | 207 | echo "[+] Downloading summary report PDF" 208 | curl --compressed -o "$SUMMARY_REPORT_PDF_FILE" -u "$API_USERNAME:$API_PASSWORD" https://analysiscenter.veracode.com/api/2.0/summaryreportpdf.do?build_id=$BUILD_ID 209 | 210 | # Validate files were downloaded 211 | if ! [[ -f $DETAILED_REPORT_PDF_FILE ]]; then 212 | echo "[-] Detailed PDF report failed to download" 213 | exit 1 214 | fi 215 | 216 | if ! [[ -f $DETAILED_REPORT_XML_FILE ]]; then 217 | echo "[-] Detailed XML report failed to download" 218 | exit 1 219 | fi 220 | 221 | if ! [[ -f $SUMMARY_REPORT_PDF_FILE ]]; then 222 | echo "[-] Summary PDF report failed to download" 223 | exit 1 224 | fi 225 | } 226 | 227 | # Emails the reports 228 | function email { 229 | echo "[+] Emailing all reports" 230 | mailx -s "$SUBJECT" -a "$DETAILED_REPORT_PDF_FILE" -a "$SUMMARY_REPORT_PDF_FILE" -a "$DETAILED_REPORT_XML_FILE" -r $FROM_ADDR $TO_ADDR 231 | } 232 | 233 | 234 | 235 | #echo "Init - `date`" 236 | #check_state 237 | #createbuild 238 | #uploadfiles 239 | #beginprescan 240 | #pollprescan 241 | #beginscan 242 | #pollscan 243 | #download 244 | ##email 245 | #echo "Complete - `date`" 246 | 247 | #exit 0 248 | -------------------------------------------------------------------------------- /bash/src/veracode-format.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ### Format helpers 4 | 5 | function attribute-value { 6 | local data=$1 7 | local element_name=$2 8 | local attribute_name=$3 9 | echo "$data" | grep "<$element_name " | sed -n "s/.*$attribute_name=\"\([^\"]*\).*/\1/p" 10 | } 11 | 12 | function format-dash-line { 13 | local size=$1 14 | local dash_line=$(echo $(printf "%0.s-" $(eval echo "{1..$size}"))) 15 | echo "|$dash_line|" 16 | 17 | } 18 | 19 | function format-xml { 20 | local data="$1" 21 | local formated_Data=$(echo "$data" | xmllint --format --noent --nonet -) # use xmllint to format xml content so that grep filter is easier to write 22 | echo "$formated_Data" 23 | } 24 | 25 | ### Formatting output utils 26 | 27 | 28 | 29 | function format-application-build { 30 | data=$1 31 | 32 | app_name=$(attribute-value "$data" "application" "app_name") 33 | app_id=$(attribute-value "$data" "application" "app_id") 34 | modified_date=$(attribute-value "$data" "application" "modified_date" | sed 's/T.*//') 35 | rules_status=$(attribute-value "$data" "build" "rules_status") 36 | build_id=$(attribute-value "$data" "build" "build_id") 37 | analysis_type=$(attribute-value "$data" "analysis_unit" "analysis_type") 38 | published_date=$(attribute-value "$data" "analysis_unit" "published_date" | sed 's/T.*//') 39 | status=$(attribute-value "$data" "analysis_unit" "status") 40 | 41 | echo "$(printf "| %-30s | %-15s | %-15s | %-15s | %-15s | %-15s | %-15s | %-15s |\n" \ 42 | "$app_name" "$app_id" "$build_id" "$modified_date" "$rules_status" "$analysis_type" "$published_date" "$status")" 43 | #echo $data 44 | } 45 | 46 | function format-veracode-app-build-id { 47 | raw_xml=$1 48 | local formatted_xml=$(format-xml "$raw_xml") 49 | build_id=$(attribute-value "$formatted_xml" "buildinfo" "build_id") 50 | echo "$build_id" 51 | } 52 | 53 | function format-veracode-app-build-info { 54 | raw_xml=$1 55 | local formatted_xml=$(format-xml "$raw_xml") 56 | 57 | app_id=$(attribute-value "$formatted_xml" "buildinfo" "app_id") 58 | build_id=$(attribute-value "$formatted_xml" "buildinfo" "build_id") 59 | rules_status=$(attribute-value "$formatted_xml" "build" "rules_status") 60 | analysis_type=$(attribute-value "$formatted_xml" "analysis_unit" "analysis_type") 61 | status=$(attribute-value "$formatted_xml" "analysis_unit" "status") 62 | 63 | echo 64 | echo "Veracode build info for app $app_id" 65 | echo "|-----------------------------------------------------------------------|" 66 | echo "$(printf "| %-10s | %-15s | %-15s | %-20s |\n" "Build Id" "Rules status" "Analysis Type" "Status")" 67 | echo "|-----------------------------------------------------------------------|" 68 | echo "$(printf "| %-10s | %-15s | %-15s | %-20s |\n" "$build_id" "$rules_status" "$analysis_type" "$status")" 69 | echo "|-----------------------------------------------------------------------|" 70 | echo 71 | } 72 | 73 | function format-veracode-app-builds { 74 | local raw_xml=$1 75 | formated_xml=$(format-xml "$raw_xml") 76 | 77 | number_of_apps=$(echo "$formated_xml" | grep "/dev/null)") 89 | format-application-build "$application_xml" 90 | done 91 | format-dash-line 158 92 | } 93 | 94 | function format-veracode-app-create { 95 | raw_xml=$1 96 | app_id=$( echo $raw_xml | sed -n 's/.*app_id="\(.*\)".app_name.*/\1/p' ) 97 | echo $app_id 98 | } 99 | 100 | function format-veracode-app-delete { 101 | local data="$1" 102 | if [[ $data =~ .*\.*\.* ]] ; then 103 | echo "0 (failed to delete)" 104 | else 105 | echo "1 (delete ok)" 106 | fi 107 | } 108 | 109 | function format-veracode-app-list { 110 | raw_xml=$1 111 | echo 112 | echo "App id App Name Last Scan" 113 | echo ------------------------------------------------------------------- 114 | echo "$(format-xml "$raw_xml")" | grep "*/\1/p' ) 135 | app_id=$(echo "$formatted_xml" | grep " 8 | @.save_Latest_Usage_Report_As_Json => 9 | @.create_Report_Stats() 10 | @.create_Report_Targets() 11 | #console.log "Files in #{@.parsed_History} :" 12 | #console.log @.parsed_History.files().file_Names() 13 | 14 | -------------------------------------------------------------------------------- /node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "veracode-node-api", 3 | "version": "0.0.1", 4 | "description": "Node API to parse veracode data", 5 | "main": "index.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "test": "node node_modules/mocha/bin/_mocha --compilers coffee:coffee-script/register --recursive test", 11 | "test-watch": "npm test --- --watch" 12 | }, 13 | "author": "", 14 | "license": "ISC", 15 | "dependencies": { 16 | "async": "^2.1.5", 17 | "csv": "^1.1.1", 18 | "xml2json": "^0.11.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /node/src/Chart-Engine.coffee: -------------------------------------------------------------------------------- 1 | Buffer::save_As = (file_Path)-> 2 | fs = require('fs') 3 | out = fs.createWriteStream(file_Path); 4 | out.write(@); 5 | file_Path 6 | 7 | jsdom = require('jsdom') 8 | 9 | class Chart_Engine 10 | 11 | constructor: (chart_Data)-> 12 | @.document = null 13 | @.window = null 14 | @.chart_Data = @.chart_Data || null 15 | 16 | create_Chart: (chart_Data, target_File, callback)=> 17 | @.chart_Data = chart_Data 18 | @.setup_Jsdom => 19 | @.new_Chart() 20 | @.save_Chart target_File,-> 21 | callback target_File 22 | 23 | new_Chart: ()=> 24 | new @.chart @.ctx, @.chart_Data # will store chart in @.canvas 25 | 26 | save_Chart: (target, callback)=> 27 | save = (blob) => 28 | jsdom.blobToBuffer blob 29 | .save_As target 30 | callback() 31 | 32 | @.canvas.toBlob save #, "image/png" 33 | 34 | 35 | setup_Jsdom: (callback)=> 36 | html = '>' 37 | scripts = [ 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.2.2/Chart.js' ] # don't like this, online dependency 38 | 39 | jsdom.env html, scripts, (err, window) => 40 | @.window = window 41 | @.document = window.document 42 | #@.chart = require 'chart.js' # using local copy of chart.js is not working so for now load it from the CDN 43 | global.window = @.window # need to set these values since jsdom makes calls to window.* internally 44 | global.document = @.document 45 | @.chart = @.window .Chart 46 | @.canvas = @.document.getElementById('myChart') 47 | @.ctx = @.canvas .getContext('2d') 48 | 49 | callback() 50 | 51 | 52 | bar_Chart: ()-> 53 | data_Template = 54 | type: 'bar' 55 | data: 56 | labels: [] 57 | datasets: [ { 58 | label :'"Test Chart', 59 | backgroundColor : '#004488' 60 | borderColor : '#C0C0C0', 61 | data: [] 62 | }, ] 63 | options: 64 | responsive: false 65 | animation: false 66 | scales: yAxes: [ { ticks: beginAtZero: true } ] 67 | return { 68 | data : data_Template 69 | add_Bar: (name, value)-> 70 | data_Template.data.labels.push(name) 71 | data_Template.data.datasets[0].data.push value 72 | color: (value)-> 73 | data_Template.data.datasets[0].backgroundColor = value 74 | border: (value)-> 75 | data_Template.data.datasets[0].borderColor = value 76 | title: (value)-> 77 | data_Template.data.datasets[0].label = value 78 | 79 | } 80 | 81 | 82 | test_Data: ()=> 83 | type: 'line' 84 | data: 85 | labels: [ 86 | 'Red' 87 | 'Blue' 88 | 'Yellow' 89 | 'Green' 90 | 'Purple' 91 | 'Orange', 'aaa','bbb' 92 | ] 93 | datasets: [ { 94 | label : "My First dataset", 95 | backgroundColor : "rgba(179,181,198,0.2)", 96 | borderColor : "rgba(179,181,198,1)", 97 | pointBackgroundColor: "rgba(179,181,198,1)", 98 | pointBorderColor: "#fff", 99 | pointHoverBackgroundColor: "#fff", 100 | pointHoverBorderColor: "rgba(179,181,198,1)", 101 | data: [15, 29, 10, 11, 26, 15, 40,11] 102 | }, { 103 | label : 'Red and Green' 104 | data : [10,22,13,4,25,22,33,11] 105 | backgroundColor : "rgba(255,0,0,0.5)" 106 | borderColor : 'green' 107 | fill : true 108 | steppedLine : true 109 | borderWidth : 2 110 | 111 | }, { 112 | label: '# of Votes' 113 | data: [ 12, 13, 3, 5, 1, 12 ,22, 33] 114 | backgroundColor: [ 115 | 'rgba(255, 99, 132, 0.2)' 116 | 'rgba(54, 162, 235, 0.2)' 117 | 'rgba(255, 206, 86, 0.2)' 118 | 'rgba(75, 192, 192, 0.2)' 119 | 'rgba(153, 102, 255, 0.2)' 120 | 'rgba(255, 159, 64, 0.2)' 121 | ] 122 | borderColor: [ 123 | 'rgba(255,99,132,1)' 124 | 'rgba(54, 162, 235, 1)' 125 | 'rgba(255, 206, 86, 1)' 126 | 'rgba(75, 192, 192, 1)' 127 | 'rgba(153, 102, 255, 1)' 128 | 'rgba(255, 159, 64, 1)' 129 | ] 130 | borderWidth: 1 131 | } ] 132 | options: 133 | responsive: false 134 | animation: false 135 | width: 400 136 | height: 400 137 | scales: yAxes: [ { display: true , ticks: beginAtZero: true, _max: 10, min: 0, stepSize: 6} ] 138 | #class Chart_Engine 139 | # constructor: -> 140 | # 141 | # test_Data: ()-> 142 | # type: 'bar', 143 | # data: { 144 | # labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], 145 | # datasets: [{ 146 | # label: '# of Votes', 147 | # data: [12, 19, 3, 5, 2, 3], 148 | # backgroundColor: [ 149 | # 'rgba(255, 99, 132, 0.2)', 150 | # 'rgba(54, 162, 235, 0.2)', 151 | # 'rgba(255, 206, 86, 0.2)', 152 | # 'rgba(75, 192, 192, 0.2)', 153 | # 'rgba(153, 102, 255, 0.2)', 154 | # 'rgba(255, 159, 64, 0.2)' 155 | # ], 156 | # borderColor: [ 157 | # 'rgba(255,99,132,1)', 158 | # 'rgba(54, 162, 235, 1)', 159 | # 'rgba(255, 206, 86, 1)', 160 | # 'rgba(75, 192, 192, 1)', 161 | # 'rgba(153, 102, 255, 1)', 162 | # 'rgba(255, 159, 64, 1)' 163 | # ], 164 | # borderWidth: 1 165 | # }] 166 | # }, 167 | # options: { 168 | # responsive: false, 169 | # width: 400, 170 | # height: 400, 171 | # animation: false, 172 | # scales: { 173 | # yAxes: [{ 174 | # ticks: { 175 | # beginAtZero:true 176 | # } 177 | # }] 178 | # }, 179 | # tooltips: { 180 | # mode: 'label' 181 | # } 182 | # } 183 | # new_Chart: (width=600, height=600)=> 184 | # @.test_Data() 185 | # chartNode = new ChartjsNode(width, height) 186 | # return chartNode.drawChart(@.test_Data()).then () => 187 | # console.log 'here' 188 | # return chartNode 189 | 190 | module.exports = Chart_Engine -------------------------------------------------------------------------------- /node/src/Veracode-Scan-Charts.coffee: -------------------------------------------------------------------------------- 1 | Veracode_Scan_Report = require './Veracode-Scan-Report' 2 | Chart_Engine = require './Chart-Engine' 3 | 4 | class Veracode_Scan_Charts 5 | constructor: -> 6 | @.scan_Report = new Veracode_Scan_Report() 7 | @.chart_Engine = new Chart_Engine() 8 | 9 | 10 | create_Chart_Flaw_Categories: (callback)=> 11 | data = @.scan_Report.path_Flaws_Stats.load_Json() 12 | target_Folder = @.scan_Report.reports_Folder.path_Combine '_graphs' 13 | 14 | using @.chart_Engine, -> 15 | bar_Chart = using @.bar_Chart(), -> 16 | 17 | for name,value of data.flaw_Categories 18 | @.add_Bar name, value 19 | @.title("Veracode Scan Flaw Categories") 20 | return @ 21 | target_File = target_Folder.path_Combine 'flaw_Categories.png' 22 | chart_Data = bar_Chart.data 23 | @.create_Chart chart_Data, target_File, callback 24 | 25 | module.exports = Veracode_Scan_Charts -------------------------------------------------------------------------------- /node/src/Veracode-Scan-Report.coffee: -------------------------------------------------------------------------------- 1 | parser = require 'xml2json' 2 | 3 | require 'fluentnode' 4 | 5 | sort_By_Key = (target)-> 6 | result = {} 7 | for key,value in target._keys().sort() 8 | result[key] = target[key] 9 | return result 10 | 11 | class Veracode_Scan_Report 12 | constructor: -> 13 | @.base_Folder = wallaby?.localProjectDir || '.'.real_Path() 14 | @.reports_Folder = @.base_Folder .path_Combine '../../reports' 15 | @.scan_Reports = @.reports_Folder .path_Combine '_scan_Reports' 16 | @.parsed_Reports = @.scan_Reports .path_Combine 'parsed_Xml' 17 | 18 | @.path_Flaws = @.scan_Reports.path_Combine 'flaws.json' 19 | @.path_Flaws_Stats = @.scan_Reports.path_Combine 'flaws-stats.json' 20 | 21 | 22 | if @.reports_Folder.folder_Exists() # if there is a reports folder, then create the other folders (in case they don't exist) 23 | @.scan_Reports .folder_Create() 24 | @.parsed_Reports.folder_Create() 25 | 26 | scan_Report_Xml: (name)=> 27 | last_build_id = @.reports_Folder.path_Combine("#{name}/last_build_id") 28 | if last_build_id.file_Exists() 29 | report_Xml_File = @.reports_Folder.path_Combine("#{name}/#{last_build_id.file_Contents().trim()}/detailed.xml") 30 | if report_Xml_File.file_Exists() 31 | return report_Xml_File.file_Contents() 32 | return null 33 | 34 | scan_Report_Json: (name)=> 35 | xml = @.scan_Report_Xml name 36 | if xml 37 | return parser.toJson(xml, object: true) 38 | else 39 | console.log "failed toload #{name}" 40 | return null 41 | 42 | scans: => 43 | @.reports_Folder.folders() 44 | .folder_Names() 45 | .filter (item)-> 46 | ['_scan_history', '_scan_Reports'].not_Contains item 47 | 48 | transform_Reports_To_Json: ()=> 49 | reports = [] 50 | for scan_Name in @.scans() 51 | target_File = @.parsed_Reports.path_Combine("#{scan_Name}.json") 52 | 53 | xml_Checksum = @.scan_Report_Xml(scan_Name).checksum() 54 | 55 | if target_File.file_Contents() is null or target_File.file_Contents().not_Contains xml_Checksum # skip if report has already been calculated 56 | report_Json = @.scan_Report_Json scan_Name 57 | if report_Json != null 58 | report_Json.xml_Checksum = xml_Checksum # add xml_Checksum to saved json file 59 | report_Json.json_Pretty().save_As(target_File) 60 | if target_File.file_Exists() 61 | reports.add target_File 62 | 63 | return reports 64 | 65 | create_Report_Stats: ()=> 66 | target_File = @.scan_Reports.path_Combine 'stats.json' 67 | 68 | stats = 69 | number_of_Scans : 0 # 70 | analysis_bytes : 0 # Analysis Size KB 71 | analysis_Mb : 0 # Analysis Size KB 72 | flaws_total : 0 # detailedreport.total_flaws 73 | flaws_not_mitigated : 0 # flaws_not_mitigated 74 | flaws_very_high : 0 # detailedreport['static-analysis'].modules.module.numflawssev5 75 | flaws_high : 0 # detailedreport['static-analysis'].modules.module.numflawssev4 76 | flaws_medium : 0 # detailedreport['static-analysis'].modules.module.numflawssev3 77 | flaws_low : 0 # detailedreport['static-analysis'].modules.module.numflawssev2 78 | flaws_very_low : 0 # detailedreport['static-analysis'].modules.module.numflawssev1 79 | 80 | for scan_Name in @.scans() #.splice(1) #.take(10) 81 | scan_File = @.parsed_Reports.path_Combine("#{scan_Name}.json") 82 | scan_Data = scan_File.load_Json() 83 | if not scan_Data.detailedreport 84 | console.log scan_Name 85 | if scan_Data.detailedreport 86 | using stats, -> 87 | @.number_of_Scans++ 88 | @.flaws_total += Number scan_Data.detailedreport.total_flaws 89 | @.flaws_not_mitigated += Number scan_Data.detailedreport.flaws_not_mitigated 90 | @.analysis_bytes += Number scan_Data.detailedreport['static-analysis'].analysis_size_bytes 91 | for module in scan_Data.detailedreport['static-analysis'].modules.module 92 | @.flaws_very_high += Number module.numflawssev5 93 | @.flaws_high += Number module.numflawssev4 94 | @.flaws_medium += Number module.numflawssev3 95 | @.flaws_low += Number module.numflawssev2 96 | @.flaws_very_low += Number module.numflawssev1 97 | 98 | #console.log module 99 | #console.log severity.level 100 | 101 | #console.log scan_Data 102 | stats.analysis_Mb = Math.floor(stats.analysis_bytes / (1024 * 1024)) 103 | delete stats.analysis_bytes 104 | stats.json_Pretty().save_As target_File 105 | return target_File 106 | 107 | create_Report_Flaws: ()=> 108 | target_File = @.scan_Reports.path_Combine 'flaws.json' 109 | 110 | flaws = {} 111 | 112 | severity_Name = ['info', 'very low', 'low', 'medium','high', 'very high'] 113 | map_Flaw = (target, data, scan_Name)=> 114 | target.count++ 115 | target.flaws[data.categoryname] ?= { severity: {} } 116 | target.flaws[data.categoryname].severity[severity_Name[data.severity]] ?= [] 117 | 118 | 119 | target.flaws[data.categoryname].severity[severity_Name[data.severity]].add 120 | scan_Name: scan_Name 121 | issueid : data.issueid 122 | location: "#{data.sourcefilepath}#{data.sourcefile}:#{data.line}" 123 | 124 | 125 | 126 | map_Category = (target, data, scan_Name)-> 127 | using target,-> 128 | if data.cwe.cweid 129 | data.cwe = [ data.cwe ] 130 | for cwe in data.cwe 131 | if cwe.staticflaws.flaw.severity 132 | cwe.staticflaws.flaw = [ cwe.staticflaws.flaw ] 133 | for flaw in cwe.staticflaws.flaw 134 | map_Flaw target, flaw, scan_Name 135 | 136 | for scan_Name in @.scans().take(100) 137 | scan_File = @.parsed_Reports.path_Combine("#{scan_Name}.json") 138 | scan_Data = scan_File.load_Json() 139 | if scan_Data.detailedreport 140 | for severity in scan_Data.detailedreport.severity 141 | if severity.category 142 | if severity.category.categoryname 143 | severity.category = [ severity.category ] # ensure severity.category is an array 144 | for category in severity.category 145 | flaws[category.categoryname] ?= { id: category.categoryid, count: 0, flaws: {} } # create category object 146 | map_Category flaws[category.categoryname], category, scan_Name 147 | 148 | 149 | #console.log flaws 150 | 151 | flaws.json_Pretty().save_As target_File 152 | return target_File 153 | 154 | 155 | create_Report_Flaws_Stats: ()=> 156 | flaws_File = @.path_Flaws #@.scan_Reports.path_Combine 'flaws.json' 157 | target_File = @.path_Flaws_Stats #@.scan_Reports.path_Combine 'flaws-stats.json' 158 | flaws_Stats = 159 | flaw_Categories : {} 160 | flaw_Names : [] 161 | flaws_total : 0 162 | flaws_very_high : 0 163 | flaws_high : 0 164 | flaws_medium : 0 165 | flaws_low : 0 166 | flaws_very_low : 0 167 | 168 | flaws = flaws_File.load_Json() 169 | 170 | for category_Name,category_Value of flaws 171 | flaws_Stats.flaw_Categories[category_Name]= category_Value.count 172 | for flaw_Name, flaw_Value of category_Value.flaws 173 | #flaws_Stats.flaws_Names.add flaw_Name 174 | using flaws_Stats, -> 175 | @.flaw_Names.add flaw_Name 176 | @.flaws_very_high += flaw_Value.severity['very high']?._keys().size() | 0 177 | @.flaws_high += flaw_Value.severity['high' ]?._keys().size() | 0 178 | @.flaws_medium += flaw_Value.severity['medium' ]?._keys().size() | 0 179 | @.flaws_low += flaw_Value.severity['low' ]?._keys().size() | 0 180 | @.flaws_very_low += flaw_Value.severity['very low' ]?._keys().size() | 0 181 | 182 | 183 | 184 | using flaws_Stats, -> 185 | @.flaw_Categories = sort_By_Key @.flaw_Categories 186 | @.flaw_Names.sort() 187 | @.flaws_total = @.flaws_very_high + @.flaws_high + @.flaws_medium + @.flaws_low + @.flaws_very_low 188 | #console.log f@laws._keys() 189 | #console.log flaws_Stats 190 | 191 | flaws_Stats.json_Pretty().save_As target_File 192 | return target_File 193 | 194 | module.exports = Veracode_Scan_Report 195 | 196 | #detailed.xml -------------------------------------------------------------------------------- /node/src/Veracode-Usage-Reports.coffee: -------------------------------------------------------------------------------- 1 | Usage_Report = require './models/Usage-Report.model' 2 | 3 | require 'fluentnode' 4 | 5 | Number::to_Decimal = -> Number.parseFloat(@.toFixed(4)) 6 | 7 | fix_Numbers = (target)-> # to address this issue https://github.com/DinisCruz/Book_Software_Quality/issues/90 8 | for key,value of target when is_Number(value) 9 | target[key] = value.to_Decimal() 10 | 11 | class Veracode_Usage_Reports 12 | constructor: -> 13 | @.base_Folder = wallaby?.localProjectDir || '.'.real_Path() 14 | @.reports_Folder = @.base_Folder .path_Combine '../../reports' 15 | @.scan_History = @.reports_Folder .path_Combine '_scan_history' 16 | @.parsed_History = @.scan_History .path_Combine '_parsed' 17 | 18 | if @.reports_Folder.folder_Exists() # if there is a reports folder, then create the other folders (in case they don't exist) 19 | @.scan_History .folder_Create() 20 | @.parsed_History .folder_Create() 21 | 22 | latest_Usage_Report_Csv: => 23 | @.scan_History.path_Combine("#{@.latest_Usage_Report_Id()}.csv").file_Contents() 24 | 25 | latest_Usage_Report_Json: => 26 | data = @.parsed_History.path_Combine('usage-reports-raw.json').load_Json() 27 | return data.filter (item)-> # remove this App (since it was testing and was adding lots of non relevant findings) 28 | return item.App.not_Contains 'Infosec Trial' 29 | 30 | latest_Usage_Report_Id: => 31 | @.scan_History.path_Combine('_latest_report').file_Contents().trim() 32 | 33 | save_Latest_Usage_Report_As_Json: (callback)=> 34 | Usage_Report.Parse_Entries @.latest_Usage_Report_Csv(), (data)=> 35 | target_File = @.parsed_History.path_Combine 'usage-reports-raw.json' 36 | data.json_Pretty().save_As target_File 37 | callback target_File 38 | 39 | transform_Usage_Report: => 40 | raw_Data = @.latest_Usage_Report_Json() 41 | report = {} 42 | fields = ['App', 'App ID', 'Version', 'Version ID', 'Is Latest Pub Build'] 43 | for entry in raw_Data 44 | 45 | if entry['App'] is 'myrecs-audit' 46 | #if entry['Is Latest Pub Build'] is '0' 47 | 48 | item = {} 49 | for name in fields 50 | item[name] = entry[name] 51 | 52 | report[item.App] = item 53 | 54 | #console.log item 55 | return report 56 | 57 | 58 | create_Report_Stats: => 59 | target_File = @.parsed_History.path_Combine 'stats.json' 60 | 61 | stats = 62 | number_of_Scans : 0 # 63 | uploaded_Kb : 0 # KB Uploaded 64 | analysis_Kb : 0 # Analysis Size KB 65 | lines_of_code : 0 # Lines Of Code 66 | flaws_total : 0 # Flaws 67 | flaws_very_high : 0 # Very High Flaws 68 | flaws_high : 0 # High Flaws 69 | flaws_medium : 0 # Medium Flaws 70 | flaws_low : 0 # Low Flaws 71 | flaws_very_low : 0 # Very Low Flaws 72 | 73 | for entry in @.latest_Usage_Report_Json() 74 | using stats, -> 75 | @.number_of_Scans++ 76 | @.uploaded_Kb += Number(entry['KB Uploaded' ]) 77 | @.analysis_Kb += Number(entry['Analysis Size KB']) 78 | @.lines_of_code += Number(entry['Lines Of Code' ]) 79 | @.flaws_total += Number(entry['Flaws' ]) 80 | @.flaws_very_high += Number(entry['Very High Flaws' ]) 81 | @.flaws_high += Number(entry['High Flaws' ]) 82 | @.flaws_medium += Number(entry['Medium Flaws' ]) 83 | @.flaws_low += Number(entry['Low Flaws' ]) 84 | @.flaws_very_low += Number(entry['Very Low Flaws' ]) 85 | 86 | fix_Numbers(stats) 87 | 88 | stats.json_Pretty().save_As target_File 89 | return target_File 90 | 91 | create_Report_Targets: => 92 | target_File = @.parsed_History.path_Combine 'targets.json' 93 | targets = {} 94 | for entry in @.latest_Usage_Report_Json() 95 | targets[entry.App] ?= { number_of_scans: 0, scans: []} 96 | using targets[entry.App], -> 97 | @.number_of_scans++ 98 | data = {} 99 | using data, -> 100 | @.uploaded_Kb = entry['KB Uploaded' ] 101 | @.analysis_Kb = entry['Analysis Size KB'] 102 | @.lines_of_code = entry['Lines Of Code' ] 103 | @.flaws_total = entry['Flaws' ] 104 | @.flaws_very_high = entry['Very High Flaws' ] 105 | @.flaws_high = entry['High Flaws' ] 106 | @.flaws_medium = entry['Medium Flaws' ] 107 | @.flaws_low = entry['Low Flaws' ] 108 | @.flaws_very_low = entry['Very Low Flaws' ] 109 | @.score = entry['Score' ] 110 | @.language = entry['Language' ] 111 | @.scans.add data 112 | 113 | #console.log targets[entry.App] 114 | targets.json_Pretty().save_As target_File 115 | return target_File 116 | 117 | module.exports = Veracode_Usage_Reports -------------------------------------------------------------------------------- /node/src/bar_chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DinisCruz/veracode-api/fcdc8c45502dd7c3ba22c3c9267ff3d19d8afc4b/node/src/bar_chart.png -------------------------------------------------------------------------------- /node/src/chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DinisCruz/veracode-api/fcdc8c45502dd7c3ba22c3c9267ff3d19d8afc4b/node/src/chart.png -------------------------------------------------------------------------------- /node/src/models/Usage-Report.model.coffee: -------------------------------------------------------------------------------- 1 | csv = require('csv'); 2 | async = require 'async' 3 | 4 | class Usage_Report 5 | 6 | constructor: -> 7 | @['Account'] = '' 8 | @['Enterprise'] = '' 9 | @['App'] = '' 10 | @['App ID'] = '' 11 | @['Version'] = '' 12 | @['Version ID'] = '' 13 | @['Is Latest Pub Build'] = '' 14 | @['Analysis Type'] = '' 15 | @['Vsa'] = '' 16 | @['Business Unit'] = '' 17 | @['Business Owner'] = '' 18 | @['Business Owner Email'] = '' 19 | @['Archer Name'] = '' 20 | @['Language'] = '' 21 | @['Version Created'] = '' 22 | @['Submitted'] = '' 23 | @['Published'] = '' 24 | @['Published To Enterprise'] = '' 25 | @['Next Build Published'] = '' 26 | @['Business Days To Publish'] = '' 27 | @['Met SLO'] = '' 28 | @['Policy'] = '' 29 | @['Policy Compliance'] = '' 30 | @['Min Required Level'] = '' 31 | @['Published Level'] = '' 32 | @['Mitigated Level'] = '' 33 | @['Score'] = '' 34 | @['Mitigated Score'] = '' 35 | @['Rating'] = '' 36 | @['Published Rating'] = '' 37 | @['Mitigated Rating'] = '' 38 | @['Assess Type'] = '' 39 | @['Assurance Level'] = '' 40 | @['Lifecycle Stage'] = '' 41 | @['Tags'] = '' 42 | @['Vendor'] = '' 43 | @['Bytes Uploaded'] = '' 44 | @['KB Uploaded'] = '' 45 | @['Analysis Size KB'] = '' 46 | @['Lines Of Code'] = '' 47 | @['Dyn Scan Window Requested']= '' 48 | @['Dyn Scan Window Start'] = '' 49 | @['Dyn Scan Window Stop'] = '' 50 | @['Dyn Scan Start'] = '' 51 | @['Dyn Scan Stop'] = '' 52 | @['Elapsed Dyn Days'] = '' 53 | @['Dyn Links Visited'] = '' 54 | @['Flaws'] = '' 55 | @['Very High Flaws'] = '' 56 | @['High Flaws'] = '' 57 | @['Medium Flaws'] = '' 58 | @['Low Flaws'] = '' 59 | @['Very Low Flaws'] = '' 60 | @['Api Abuse'] = '' 61 | @['Authentication Issues'] = '' 62 | @['Command Or Argument Injection'] = '' 63 | @['Credentials Management'] = '' 64 | @['Crlf Injection'] = '' 65 | @['cross-site scripting (xss)'] = '' 66 | @['Cryptographic Issues'] = '' 67 | @['Deployment Configuration'] = '' 68 | @['Directory Traversal'] = '' 69 | @['Encapsulation'] = '' 70 | @['Error Handling'] = '' 71 | @['Information Leakage'] = '' 72 | @['Insecure Dependencies'] = '' 73 | @['Insufficient Input Validation'] = '' 74 | @['Race Conditions'] = '' 75 | @['Server Configuration'] = '' 76 | @['Session Fixation'] = '' 77 | @['Sql Injection'] = '' 78 | @['Time And State'] = '' 79 | @['Untrusted Initialization'] = '' 80 | @['Untrusted Search Path'] = '' 81 | @['New Flaws'] = '' 82 | @['Flaws From Prev Build'] = '' 83 | @['Flaws Remediated'] = '' 84 | @['Flaws Regressed'] = '' 85 | @['Flaws Mitigated'] = '' 86 | @['Owasptext Flaws'] = '' 87 | @['Count Of Fix For Policy Flaws'] = '' 88 | @['Teams'] = '' 89 | @['Custom 1'] = '' 90 | @['Custom 2'] = '' 91 | @['Custom 3'] = '' 92 | @['Custom 4'] = '' 93 | @['Custom 5'] = '' 94 | @['Deployment Method'] = '' 95 | @['Submitter Name'] = '' 96 | @['Submitter Email'] = '' 97 | @['Submitted By Api Account'] = '' 98 | @['Custom 6'] = '' 99 | @['Custom 7'] = '' 100 | @['Custom 8'] = '' 101 | @['Custom 9'] = '' 102 | @['Custom 10'] = '' 103 | @['Custom 11'] = '' 104 | @['Custom 12'] = '' 105 | @['Custom 13'] = '' 106 | @['Custom 14'] = '' 107 | @['Custom 15'] = '' 108 | @['Custom 16'] = '' 109 | @['Custom 17'] = '' 110 | @['Custom 18'] = '' 111 | @['Custom 19'] = '' 112 | @['Custom 20'] = '' 113 | @['Custom 21'] = '' 114 | @['Custom 22'] = '' 115 | @['Custom 23'] = '' 116 | @['Custom 24'] = '' 117 | @['Custom 25'] = '' 118 | 119 | 120 | Usage_Report.Parse_Entry = (csv_Data, callback)-> 121 | 122 | return callback null if not csv_Data # send null if there no data passed 123 | csv.parse csv_Data, (err, data)-> 124 | if err or data.length < 1 125 | callback null # or there was an error with parsing 126 | else 127 | usage_Report = new Usage_Report() # create Usage_Report 128 | fields = usage_Report._keys() # get is fields 129 | 130 | for item, index in data.first() # for each csv value 131 | usage_Report[fields[index]] = item # assign it to Usage_Report (note that this is depending on the correct order 132 | 133 | callback usage_Report # send object create as callback 134 | 135 | Usage_Report.Parse_Entries = (data, callback)-> 136 | 137 | csv_Entries = data?.split_Lines() 138 | if (not csv_Entries) or csv_Entries.empty() 139 | callback null 140 | else 141 | csv.parse data, columns: true, (err, data)-> 142 | if data.empty() or data.first()._keys().str() isnt new Usage_Report()._keys().str() # confirm fields match 143 | callback null 144 | else 145 | callback data 146 | 147 | 148 | module.exports = Usage_Report -------------------------------------------------------------------------------- /node/src/test.md: -------------------------------------------------------------------------------- 1 | ## testing if GitHub will show the graph 2 | 3 | Graph goes below 4 | 5 | ### pure markdown 6 | 7 | ![](./chart.png) 8 | 9 | ### using html 10 | 11 | -------------------------------------------------------------------------------- /node/test/Chart-Engine.test.coffee: -------------------------------------------------------------------------------- 1 | require 'fluentnode' 2 | 3 | Chart_Engine = require '../src/Chart-Engine' 4 | 5 | describe 'Chart-Engine', -> 6 | chart_Engine = null 7 | 8 | beforeEach -> 9 | chart_Engine = new Chart_Engine() 10 | 11 | 12 | it 'constructor', -> 13 | using chart_Engine, -> 14 | assert_Is_Null @.document 15 | assert_Is_Null @.window 16 | 17 | it 'new_Chart', (done)-> 18 | using chart_Engine, -> 19 | @.setup_Jsdom => 20 | @.new_Chart() 21 | done() 22 | 23 | it 'save_Chart', (done)-> 24 | target_File = __dirname.path_Combine 'chart.png' 25 | target_File.file_Delete() 26 | using chart_Engine, -> 27 | @.chart_Data = @.test_Data() 28 | @.setup_Jsdom => 29 | @.new_Chart() 30 | @.save_Chart target_File,-> 31 | target_File.assert_File_Exists() 32 | done() 33 | 34 | it 'setup_Jsdom', (done)-> 35 | using chart_Engine, -> 36 | @.setup_Jsdom => 37 | @.window ._keys().assert_Contains [ '_core', '_globalProxy', '__timers', '_top', '_parent', '_frameElement', '_document'] 38 | @.document ._keys().assert_Is ['location'] 39 | @.canvas .assert_Is {} 40 | @.ctx._keys().assert_Is [ 'canvas', 'createPattern', 'drawImage' ] 41 | done() 42 | 43 | it 'create_Bar_Chart', (done)-> 44 | 45 | using chart_Engine, -> 46 | bar_Chart = using @.bar_Chart(), -> 47 | @.add_Bar 'aaa', 12 48 | @.add_Bar 'bbb', 22 49 | @.add_Bar 'ccc', 11 50 | @.color '#226622' 51 | @.border 'black' 52 | @.title 'A test chart' 53 | return @ 54 | 55 | 56 | target_File = __dirname.path_Combine '../src/bar_chart.png' 57 | chart_Data = bar_Chart.data 58 | @.create_Chart chart_Data, target_File, -> 59 | target_File.assert_File_Exists()#.file_Delete().assert_Is_True() 60 | done() 61 | 62 | 63 | it 'test_Data', -> 64 | using chart_Engine, -> 65 | #console.log @.test_Data() 66 | 67 | xdescribe 'Chart-Engine', -> 68 | chart_Engine = null 69 | 70 | beforeEach -> 71 | chart_Engine = new Chart_Engine() 72 | 73 | it 'constructor', -> 74 | using chart_Engine, -> 75 | #@.base_Folder .assert_Folder_Exists() 76 | 77 | it 'new_Chart', (done)-> 78 | using chart_Engine, -> 79 | console.log @.new_Chart().then ()-> 80 | console.log 'here' 81 | @.new_Chart() 82 | .then (chartNode)=> 83 | #console.log chartNode 84 | done() 85 | 86 | it 'test2', (done)-> 87 | 88 | fs = require('fs') 89 | jsdom = require('jsdom') 90 | jsdom.defaultDocumentFeatures = 91 | FetchExternalResources: [ 'script' ] 92 | ProcessExternalResources: true 93 | 94 | jsdom.env '
>
', [ 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.2.2/Chart.js' ], (err, window) -> 95 | global.window = window 96 | global.document = window.document 97 | # Comes from the Chart.js link above just like