missing-jwt-token
Ast Rule: function definition
missing-jwt-token
function visit(node, filename, code) {
const decorators_available = node.context
.imports.filter(i => i.astType === "fromstatement" && i.pkg && i.pkg.value === "flask_jwt_extended")
.flatMap(i => i.elements.filter(e => e.name && e.name.value).map(e => e.name.value));
if(!decorators_available || decorators_available.length == 0) {
return;
}
const checkElement = (element) => {
if (!element) {
return;
}
if (element.astType === "functioncall") {
if (element.functionName.value === "dumps" && element.moduleOrObject.value === "json") {
const error = buildError(element.start.line, element.start.col, element.end.line, element.end.col,
"do not use json.dumps, use flask.jsonify() instead", "CRITICAL", "SECURITY");
addError(error);
}
}
if (element.astType === "assignment") {
checkElement(element.right);
}
};
const isRoute = node.decorators && node.decorators.filter(d => d.name && d.name.value === "app.route").length > 0;
const useJwtDecorator = node.decorators && node.decorators.filter(d => d.name && decorators_available.includes(d.name.value)).length > 0;
if (isRoute && !useJwtDecorator) {
var error = buildError(node.name.start.line, node.name.start.col,
node.name.end.line, node.name.end.col,
"flask_jwt_extended imported - you may want to add a decorator",
"CRITICAL", "SECURITY");
decorators_available.forEach(d => {
const edit = buildEditAdd(node.start.line, node.start.col - 1, `@${d}()\n`);
const fix = buildFix(`add decorator ${d}`, [edit]);
error = error.addFix(fix);
});
addError(error);
}
}
with-decorator.py
Expected test result: no error
without-decorator.py
Expected test result: no error