Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support JS Restify #273

Merged
merged 4 commits into from
Apr 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 32 additions & 0 deletions spec/functional_test/fixtures/js_restify/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const restify = require('restify');

function setupServer(server) {
server.get('/', function(req, res, next) {
var userAgent = req.header('X-API-Key');
var paramName = req.query.name;

res.send('index'); // Assuming 'index' is a simple response for demonstration
return next();
});

server.post('/upload', function(req, res, next) {
// Restify does not parse cookies by default, so you need to use a plugin or middleware if you want to access cookies
// const auth = req.cookies.auth; // This line needs adjustment if using cookies
const name = req.body.name;

res.send('index'); // Similarly, adjust according to your actual response handling
return next();
});
}

// Setup Restify server
const server = restify.createServer();

server.use(restify.plugins.bodyParser()); // Parse JSON body data
// server.use(restify.plugins.cookieParser()); // Uncomment if you need cookie parsing

setupServer(server);

server.listen(3000, function() {
console.log('%s listening at %s', server.name, server.url);
});
2 changes: 1 addition & 1 deletion spec/functional_test/func_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class FunctionalTester
key = endpoint.method.to_s + "::" + endpoint.url.to_s
found_endpoint = find_endpoint key
if found_endpoint.nil?
it "endpoint [#{key}] not founded" do
it "endpoint [#{key}] not found" do
false.should eq true
end
else
Expand Down
17 changes: 17 additions & 0 deletions spec/functional_test/testers/js_restify_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
require "../func_spec.cr"

extected_endpoints = [
Endpoint.new("/", "GET", [
Param.new("name", "", "query"),
Param.new("X-API-Key", "", "header"),
]),
Endpoint.new("/upload", "POST", [
Param.new("name", "", "json"),
Param.new("auth", "", "cookie"),
]),
]

FunctionalTester.new("fixtures/js_restify/", {
:techs => 1,
:endpoints => 2,
}, extected_endpoints).test_all
13 changes: 13 additions & 0 deletions spec/unit_test/detector/detect_js_restify_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require "../../../src/detector/detectors/*"

describe "Detect JS Restify" do
options = default_options()
instance = DetectorJsRestify.new options

it "require_single_quot" do
instance.detect("index.js", "require('restify')").should eq(true)
end
it "require_double_quot" do
instance.detect("index.js", "require(\"restify\")").should eq(true)
end
end
1 change: 1 addition & 0 deletions src/analyzer/analyzer.cr
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def initialize_analyzers(logger : NoirLogger)
analyzers["java_jsp"] = ->analyzer_jsp(Hash(Symbol, String))
analyzers["java_spring"] = ->analyzer_java_spring(Hash(Symbol, String))
analyzers["js_express"] = ->analyzer_express(Hash(Symbol, String))
analyzers["js_restify"] = ->analyzer_restify(Hash(Symbol, String))
analyzers["kotlin_spring"] = ->analyzer_kotlin_spring(Hash(Symbol, String))
analyzers["oas2"] = ->analyzer_oas2(Hash(Symbol, String))
analyzers["oas3"] = ->analyzer_oas3(Hash(Symbol, String))
Expand Down
111 changes: 111 additions & 0 deletions src/analyzer/analyzers/analyzer_restify.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
require "../../models/analyzer"

class AnalyzerRestify < Analyzer
def analyze
# Source Analysis
begin
Dir.glob("#{base_path}/**/*") do |path|
next if File.directory?(path)
if File.exists?(path)
File.open(path, "r", encoding: "utf-8", invalid: :skip) do |file|
last_endpoint = Endpoint.new("", "")
file.each_line.with_index do |line, index|
endpoint = line_to_endpoint(line)
if endpoint.method != ""
details = Details.new(PathInfo.new(path, index + 1))
endpoint.set_details(details)
result << endpoint
last_endpoint = endpoint
end

param = line_to_param(line)
if param.name != ""
if last_endpoint.method != ""
last_endpoint.push_param(param)
end
end
end
end
end
end
rescue e
# TODO
end

result
end

def express_get_endpoint(line : String)
api_path = ""
splited = line.split("(")
if splited.size > 0
api_path = splited[1].split(",")[0].gsub(/['"]/, "")
end

api_path
end

def line_to_param(line : String) : Param
if line.includes? "req.body."
param = line.split("req.body.")[1].split(")")[0].split("}")[0].split(";")[0]
return Param.new(param, "", "json")
end

if line.includes? "req.query."
param = line.split("req.query.")[1].split(")")[0].split("}")[0].split(";")[0]
return Param.new(param, "", "query")
end

if line.includes? "req.cookies."
param = line.split("req.cookies.")[1].split(")")[0].split("}")[0].split(";")[0]
return Param.new(param, "", "cookie")
end

if line.includes? "req.header("
param = line.split("req.header(")[1].split(")")[0].gsub(/['"]/, "")
return Param.new(param, "", "header")
end

Param.new("", "", "")
end

def line_to_endpoint(line : String) : Endpoint
if line.includes? ".get('/"
api_path = express_get_endpoint(line)
if api_path != ""
return Endpoint.new(api_path, "GET")
end
end
if line.includes? ".post('/"
api_path = express_get_endpoint(line)
if api_path != ""
return Endpoint.new(api_path, "POST")
end
end
if line.includes? ".put('/"
api_path = express_get_endpoint(line)
if api_path != ""
return Endpoint.new(api_path, "PUT")
end
end
if line.includes? ".delete('/"
api_path = express_get_endpoint(line)
if api_path != ""
return Endpoint.new(api_path, "DELETE")
end
end
if line.includes? ".patch('/"
api_path = express_get_endpoint(line)
if api_path != ""
return Endpoint.new(api_path, "PATCH")
end
end

Endpoint.new("", "")
end
end

def analyzer_restify(options : Hash(Symbol, String))
instance = AnalyzerRestify.new(options)
instance.analyze
end
1 change: 1 addition & 0 deletions src/detector/detector.cr
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def detect_techs(base_path : String, options : Hash(Symbol, String), logger : No
DetectorJavaJsp,
DetectorJavaSpring,
DetectorJsExpress,
DetectorJsRestify,
DetectorKotlinSpring,
DetectorOas2,
DetectorOas3,
Expand Down
21 changes: 21 additions & 0 deletions src/detector/detectors/js_restify.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require "../../models/detector"

class DetectorJsRestify < Detector
def detect(filename : String, file_contents : String) : Bool
if (filename.includes? ".js") && (file_contents.includes? "require('restify')")
true
elsif (filename.includes? ".js") && (file_contents.includes? "require(\"restify\")")
true
elsif (filename.includes? ".ts") && (file_contents.includes? "server")
true
elsif (filename.includes? ".ts") && (file_contents.includes? "require(\"restify\")")
true
else
false
end
end

def set_name
@name = "js_restify"
end
end
5 changes: 5 additions & 0 deletions src/techs/techs.cr
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ module NoirTechs
:language => "JavaScript",
:similar => ["express", "js-express", "js_express"],
},
:js_restify => {
:framework => "Restify",
:language => "JavaScript",
:similar => ["restify", "js-restify"],
},
:kotlin_spring => {
:framework => "Spring",
:language => "Kotlin",
Expand Down