Skip to content

Commit

Permalink
docs: update rules count (#1399)
Browse files Browse the repository at this point in the history
* docs: update rules count

* chore: remove console.log
  • Loading branch information
cfabianski authored Nov 15, 2023
1 parent 7174c01 commit ddbac64
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 79 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<br /><br />
Bearer CLI is a static application security testing (SAST) tool that scans your source code and analyzes your data flows to discover, filter and prioritize security and privacy risks.
<br /><br />
Currently supporting: <strong>JavaScript/TypeScript</strong> (GA), <strong>Ruby</strong> (GA), <strong>Java</strong> (Beta), <strong>PHP</strong> (Beta), <strong>Go</strong> (Alpha), <strong>Python</strong> (Alpha) - <a href="https://docs.bearer.com/reference/supported-languages/">Learn more</a>
Currently supporting: <strong>JavaScript/TypeScript</strong> (GA), <strong>Ruby</strong> (GA), <strong>Java</strong> (Beta), <strong>PHP</strong> (Beta), <strong>Go</strong> (Beta), <strong>Python</strong> (Alpha) - <a href="https://docs.bearer.com/reference/supported-languages/">Learn more</a>

<br /><br />

Expand Down Expand Up @@ -259,17 +259,17 @@ Bearer CLI currently supports:
<table>
<tr>
<td>GA</td>
<td>JavaScript/TypeScript, Ruby</td>
<td>JavaScript/TypeScript, Ruby</td>
</tr>
<tr>
<td>Beta</td>
<td>Java, PHP</td>
<td>Java, PHP</td>
</tr>
<tr>
<td>Alpha</td>
<td>Go, Python</td>
<td>Go, Python</td>
</tr>
</table>
</table>
[Learn more](https://docs.bearer.com/reference/supported-languages/) about language support.
Expand Down
34 changes: 19 additions & 15 deletions docs/.eleventy.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ module.exports = function (eleventyConfig) {
return now
})
eleventyConfig.addShortcode("sectionLinks", function (sectionName) {
const section = nav.find(item => item.name == sectionName)
const section = nav.find((item) => item.name == sectionName)
let out = ""
if(section){
section.items.forEach(item => {
if (section) {
section.items.forEach((item) => {
out += `- [${item.name}](${item.url})\n`
})
}
Expand All @@ -63,19 +63,24 @@ module.exports = function (eleventyConfig) {
})

// {% yamlExample "ci/gitlab/basic" %}
eleventyConfig.addShortcode('yamlExample', function (exampleName) {
const example = fs.readFileSync(`./_data/examples/${exampleName}.yaml`, 'utf8')
return '```yaml\n' + example + '\n```';
});
eleventyConfig.addShortcode("yamlExample", function (exampleName) {
const example = fs.readFileSync(
`./_data/examples/${exampleName}.yaml`,
"utf8"
)
return "```yaml\n" + example + "\n```"
})

eleventyConfig.addShortcode('githubAction', function(data){
eleventyConfig.addShortcode("githubAction", function (data) {
out = "| Option | Description | Default |\n"
out += "| - | - | - |\n"
Object.keys(data).sort().forEach(key => {
const item = data[key]
const default_val = item.default ? "`"+item.default+"`" : ""
out += `| **${key}** | ${item.description} | ${default_val} |\n`
});
Object.keys(data)
.sort()
.forEach((key) => {
const item = data[key]
const default_val = item.default ? "`" + item.default + "`" : ""
out += `| **${key}** | ${item.description} | ${default_val} |\n`
})
return out
})

Expand Down Expand Up @@ -178,8 +183,7 @@ module.exports = function (eleventyConfig) {
const target = parent.split(path.sep).slice(1, -1)
const check = child.split(path.sep).slice(1, -1)
// handles individual rule pages highlighting "rule" in side nav
const isRule =
target.includes("rules") && check[check.length - 2] === "rules"
const isRule = target.includes("rules")
if (child === parent || isRule) {
return true
} else {
Expand Down
146 changes: 87 additions & 59 deletions docs/_data/rules.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
const { readFile, readdir } = require("node:fs/promises");
const { statSync } = require("fs");
const EleventyFetch = require("@11ty/eleventy-fetch");
const path = require("path");
const yaml = require("js-yaml");
const cweList = require("./cweList.json");
const gitly = require("gitly");
const source = "bearer/bearer-rules";
const rulesPath = "_tmp/rules-data";
const excludeDirectories = [".github", "scripts"];
const { readFile, readdir } = require("node:fs/promises")
const { statSync } = require("fs")
const EleventyFetch = require("@11ty/eleventy-fetch")
const path = require("path")
const yaml = require("js-yaml")
const cweList = require("./cweList.json")
const gitly = require("gitly")
const source = "bearer/bearer-rules"
const rulesPath = "_tmp/rules-data"
const excludeDirectories = [".github", "scripts"]

let counts = {
languages: {},
};
}

function updateCounts(lang, framework = null, id = null) {
if (framework !== null) {
if (counts.languages[lang].frameworks[framework]) {
counts.languages[lang].frameworks[framework].count++;
counts.languages[lang].frameworks[framework].rules.push(id);
counts.languages[lang].frameworks[framework].count++
counts.languages[lang].frameworks[framework].rules.push(id)
} else if (framework === "gosec") {
newFramework(lang, framework)
} else if (framework !== "lang") {
newFramework(lang, framework);
newFramework(lang, framework)
} else if (framework === "lang") {
counts.languages[lang].baseRules.push(id);
counts.languages[lang].baseRules.push(id)
}
counts.languages[lang].count++;
counts.languages[lang].count++
} else {
newLang(lang);
newLang(lang)
}
}

Expand All @@ -34,7 +36,7 @@ function newFramework(lang, name) {
name,
count: 1,
rules: [],
};
}
}

function newLang(name) {
Expand All @@ -43,105 +45,131 @@ function newLang(name) {
count: 0,
baseRules: [],
frameworks: {},
};
}
}

function isDirectory(dir) {
const result = statSync(dir);
return result.isDirectory();
const result = statSync(dir)
return result.isDirectory()
}

async function fetchRelease() {
let latest = {};
let latest = {}
try {
latest = await EleventyFetch(
`https://api.github.com/repos/${source}/releases/latest`,
{
duration: "60m",
type: "json",
}
);
)
} catch (e) {
console.error(e);
console.error(e)
}
try {
let src = await gitly.download(`${source}#${latest.tag_name}`);
await gitly.extract(src, rulesPath);
let src = await gitly.download(`${source}#${latest.tag_name}`)
await gitly.extract(src, rulesPath)
} catch (e) {
throw console.error(e);
throw console.error(e)
}
}

async function fetchData(location) {
let rules = [];
let rules = []
try {
const dirs = await readdir(location);
const dirs = await readdir(location)
// ex: looping through rules [ruby, gitleaks, sql]
dirs.forEach(async (dir) => {
const dirPath = path.join(location, dir);
const dirPath = path.join(location, dir)
if (isDirectory(dirPath) && !excludeDirectories.includes(dir)) {
const subDirs = await readdir(dirPath);
updateCounts(dir);
const subDirs = await readdir(dirPath)
updateCounts(dir)
// ex. looping through rules/ruby [lang, rails]
subDirs.forEach(async (subDir) => {
const subDirPath = path.join(dirPath, subDir);
if (isDirectory(subDirPath) && subDir !== "shared") {
const files = await readdir(subDirPath);
const subDirPath = path.join(dirPath, subDir)
if (
isDirectory(subDirPath) &&
subDir !== "shared" &&
subDir !== "gosec"
) {
const files = await readdir(subDirPath)
const children = await fetchAllFiles(
subDirPath,
path.join(dir, subDir),
files
);
rules.push(...children);
)
rules.push(...children)
} else if (isDirectory(subDirPath) && subDir === "gosec") {
const groupDirs = await readdir(subDirPath)

groupDirs.forEach(async (groupDir) => {
const groupDirPath = path.join(dirPath, subDir, groupDir)
if (isDirectory(groupDirPath)) {
const files = await readdir(groupDirPath)
const children = await fetchAllFiles(
groupDirPath,
path.join(dir, subDir, groupDir),
files
)
rules.push(...children)
}
})
}
});
})
}
});
return { counts, rules };
})
return { counts, rules }
} catch (err) {
throw err;
throw err
}
}

async function fetchAllFiles(directory, breadcrumb, files) {
let result = await Promise.all(
files.reduce((all, file) => {
const location = path.join(directory, file);
const location = path.join(directory, file)
if (path.extname(location) === ".yml") {
return [...all, fetchFile(path.join(directory, file), breadcrumb)];
return [...all, fetchFile(path.join(directory, file), breadcrumb)]
} else {
return all;
return all
}
}, [])
);
return result;
)
return result
}

async function fetchFile(location, breadcrumb) {
return readFile(location, { encoding: "utf8" }).then((file) => {
let out = yaml.load(file);
let owasps = new Set();
let subdir = breadcrumb.split("/");
let framework = subdir[subdir.length - 1];
updateCounts(subdir[subdir.length - 2], framework, out.metadata.id);
let out = yaml.load(file)
let owasps = new Set()
let subdir = breadcrumb.split("/")
let groupId = subdir[subdir.length - 2]
let framework = subdir[subdir.length - 1]
let lang = subdir[subdir.length - 2]
if (groupId === "gosec") {
framework = groupId
lang = subdir[subdir.length - 3]
}

updateCounts(lang, framework, out.metadata.id)
if (out.metadata.cwe_id) {
out.metadata.cwe_id.forEach((i) => {
if (cweList[i].owasp) {
owasps.add(cweList[i].owasp.id);
if (cweList[i] && cweList[i].owasp) {
owasps.add(cweList[i].owasp.id)
}
});
})
}
return {
name: path.basename(location, ".yml"),
location: path.join(breadcrumb, path.basename(location, ".yml")),
owasp_ids: [...owasps].sort(),
framework,
...out,
};
});
}
})
}

module.exports = async function () {
await fetchRelease();
return await fetchData(path.join(rulesPath, "rules"));
};
await fetchRelease()
return await fetchData(path.join(rulesPath, "rules"))
}

0 comments on commit ddbac64

Please sign in to comment.