Skip to content

Commit e0f4786

Browse files
committed
WIP
1 parent 93839ac commit e0f4786

File tree

6 files changed

+303
-12
lines changed

6 files changed

+303
-12
lines changed

.editorconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# EditorConfig is awesome: http://EditorConfig.org
2+
3+
# top-most EditorConfig file
4+
root = true
5+
6+
# Unix-style newlines with a newline ending every file
7+
[*]
8+
charset = utf-8
9+
end_of_line = lf
10+
insert_final_newline = true
11+
indent_style = space
12+
indent_size = 2
13+
14+
# Don't trim Markdown files
15+
[*.md]
16+
trim_trailing_whitespace = false

.gitignore

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,2 @@
1-
*.class
2-
3-
# Mobile Tools for Java (J2ME)
4-
.mtj.tmp/
5-
6-
# Package Files #
7-
*.jar
8-
*.war
9-
*.ear
10-
11-
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
12-
hs_err_pid*
1+
*.idea
2+
node_modules

lib/callback.js

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
var VERSION = 0.1;
2+
3+
var util = require('util');
4+
var aws = require('aws-sdk');
5+
var s3 = new aws.S3({apiVersion: '2006-03-01'});
6+
var http = require('https');
7+
var qs = require('querystring');
8+
const API_ENDPOINT = '/v2.1/files/';
9+
10+
console.log('Loading function v', VERSION);
11+
12+
// replace below with your credentials in the form key:secret
13+
// to create your key go to https://scanii.com/account/settings/keys
14+
var SCANII_CREDS = 'KEY:SECRET';
15+
16+
// callbacks
17+
18+
onFindings = function (bucket, key, result) {
19+
console.log('findings:', result.findings);
20+
};
21+
22+
onNoFindings = function (bucket, key, result) {
23+
console.log('file has no findings');
24+
};
25+
26+
// do not edit below this line
27+
fetch = function (id, context, bucket, key) {
28+
console.log('looking up ', id);
29+
var req = http.request({
30+
auth: SCANII_CREDS,
31+
port: 443,
32+
host: 'api.scanii.com',
33+
path: API_ENDPOINT + id,
34+
method: 'GET'
35+
}, function (res) {
36+
console.log("statusCode: ", res.statusCode);
37+
console.log("headers: ", res.headers);
38+
39+
if (res.statusCode == 200) {
40+
console.log('response found, processing');
41+
} else {
42+
console.log('response pending, waiting');
43+
setTimeout(fetch(id, context), 1000);
44+
return;
45+
}
46+
res.on('data', function (data) {
47+
var r = JSON.parse(data);
48+
console.log('response:', JSON.stringify(r, null, 2));
49+
50+
if (r.findings !== undefined) {
51+
if (r.findings.size > 0) {
52+
onFindings(bucket, key, r);
53+
} else {
54+
onNoFindings(bucket, key, r);
55+
}
56+
57+
}
58+
context.done();
59+
});
60+
});
61+
req.end();
62+
req.on('error', function (error) {
63+
console.log(error);
64+
});
65+
};
66+
67+
exports.handler = function (event, context) {
68+
console.log('Received event:', JSON.stringify(event, null, 2));
69+
70+
// Get the object from the event and show its content type
71+
var bucket = event.Records[0].s3.bucket.name;
72+
var key = event.Records[0].s3.object.key;
73+
74+
console.log(util.format('processing s3://%s/%s', bucket, key));
75+
76+
// creating signed url for processing
77+
var url = s3.getSignedUrl('getObject', {
78+
Bucket: bucket,
79+
Key: key,
80+
Expires: 3600 // 1 hour
81+
});
82+
console.log('created signed url', url);
83+
console.log('submitting content for malware processing');
84+
85+
var payload = qs.stringify({
86+
location: url
87+
});
88+
var options = {
89+
auth: SCANII_CREDS,
90+
port: 443,
91+
host: 'api.scanii.com',
92+
path: API_ENDPOINT + 'fetch',
93+
method: 'POST',
94+
headers: {
95+
'Content-Type': 'application/x-www-form-urlencoded',
96+
'Content-Length': payload.length,
97+
'User-Agent': 'scanii-mu/v' + VERSION
98+
}
99+
};
100+
101+
// calling scanii API v2.1 (http://docs.scanii.com/v2.1/resources.html):
102+
var req = http.request(options, function (res) {
103+
console.log("statusCode: ", res.statusCode);
104+
console.log("headers: ", res.headers);
105+
106+
res.on('data', function (data) {
107+
var serviceResponse = JSON.parse(data);
108+
console.log('file id:', serviceResponse.id);
109+
// polling for response:
110+
setTimeout(fetch(serviceResponse.id, context, bucket, key), 1000);
111+
});
112+
});
113+
114+
req.write(payload);
115+
req.end();
116+
117+
req.on('error', function (error) {
118+
console.log(error);
119+
});
120+
};

lib/index.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
var VERSION = 0.2;
2+
3+
var util = require('util');
4+
var aws = require('aws-sdk');
5+
var s3 = new aws.S3({apiVersion: '2006-03-01'});
6+
var http = require('https');
7+
var qs = require('querystring');
8+
var crypto = require('crypto');
9+
10+
// replace below with your credentials in the form key:secret
11+
// to create your key go to https://scanii.com/account/settings/keys
12+
var SCANII_CREDS = 'KEY:SECRET';
13+
14+
// Do not edit below this line
15+
16+
const API_ENDPOINT = '/v2.1/files/';
17+
18+
console.log('Loading function v', VERSION);
19+
20+
var KEY = SCANII_CREDS.split(':')[0];
21+
var SECRET = SCANII_CREDS.split(':')[1];
22+
23+
var internalId = function(bucket, key) {
24+
return util.format('processing s3://%s/%s', bucket, key);
25+
};
26+
27+
exports.handler = function (event, context) {
28+
console.log('Received event:', JSON.stringify(event, null, 2));
29+
30+
// Get the object from the event and show its content type
31+
var bucket = event.Records[0].s3.bucket.name;
32+
var key = event.Records[0].s3.object.key;
33+
34+
console.log('processing ' + internalId(bucket, key));
35+
36+
// creating signed url for processing
37+
var url = s3.getSignedUrl('getObject', {
38+
Bucket: bucket,
39+
Key: key,
40+
Expires: 3600 // 1 hour
41+
});
42+
console.log('created signed url', url);
43+
console.log('submitting content for processing');
44+
45+
// signing request
46+
var signature = crypto.createHmac('sha1', SECRET).update(internalId(bucket, key)).digest('hex');
47+
console.log('using signature ' + signature);
48+
49+
var payload = qs.stringify({
50+
location: url,
51+
'metadata[hmac]': signature,
52+
'metadata[id]': internalId(bucket, key)
53+
});
54+
55+
console.log(payload);
56+
57+
var options = {
58+
auth: SCANII_CREDS,
59+
port: 443,
60+
host: 'api.scanii.com',
61+
path: API_ENDPOINT + 'fetch',
62+
method: 'POST',
63+
headers: {
64+
'Content-Type': 'application/x-www-form-urlencoded',
65+
'Content-Length': payload.length,
66+
'User-Agent': 'scanii-mu/v' + VERSION
67+
}
68+
};
69+
70+
// calling scanii API v2.1 (http://docs.scanii.com/v2.1/resources.html):
71+
var req = http.request(options, function (res) {
72+
console.log("statusCode: ", res.statusCode);
73+
console.log("headers: ", res.headers);
74+
75+
res.on('data', function (data) {
76+
var serviceResponse = JSON.parse(data);
77+
console.log('file id:', serviceResponse.id);
78+
context.succeed('OK - id ' + serviceResponse.id);
79+
});
80+
});
81+
82+
req.write(payload);
83+
req.end();
84+
85+
req.on('error', function (error) {
86+
console.log(error);
87+
context.fail(error);
88+
});
89+
};

package.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "scanii-mu",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "node_modules/mocha/bin/mocha tests.js"
8+
},
9+
"author": "",
10+
"license": "Apache-2.0",
11+
"dependencies": {
12+
"aws-lambda-mock-context": "^0.2.0",
13+
"aws-sdk": "^2.2.5",
14+
"consoleplusplus": "^1.3.0",
15+
"mocha": "^2.3.3"
16+
}
17+
}

tests.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
var handler = require('./lib/index.js').handler;
2+
var assert = require('assert');
3+
var context = require('aws-lambda-mock-context');
4+
5+
6+
// Start the test
7+
describe('Scanii-Mu Tests', function () {
8+
it('should process a create object event', function (done) {
9+
handler({
10+
"Records": [
11+
{
12+
"eventVersion": "2.0",
13+
"eventSource": "aws:s3",
14+
"awsRegion": "us-west-2",
15+
"eventTime": "2015-10-01T23:28:54.280Z",
16+
"eventName": "ObjectCreated:Put",
17+
"userIdentity": {
18+
"principalId": "AWS:principal"
19+
},
20+
"requestParameters": {
21+
"sourceIPAddress": "98.167.155.191"
22+
},
23+
"responseElements": {
24+
"x-amz-request-id": "EEC943B096DE3DF9",
25+
"x-amz-id-2": "W/myEjyXFBsOA6N0byxW0tOxMA4m1fmv9KAVcovvG0nD9W1s5aX5+Wx61tlCop8LbZAw1Nz0mnc="
26+
},
27+
"s3": {
28+
"s3SchemaVersion": "1.0",
29+
"configurationId": "948c2c1a-a028-4564-93fc-76cea7622633",
30+
"bucket": {
31+
"name": "scanii-mu",
32+
"ownerIdentity": {
33+
"principalId": "principal"
34+
},
35+
"arn": "arn:aws:s3:::scanii-mu"
36+
},
37+
"object": {
38+
"key": "016.xml",
39+
"size": 519,
40+
"eTag": "aa1e5c8a6a07217c25f55aa8e96ea37a",
41+
"sequencer": "00560DC1B62F962FCD"
42+
}
43+
}
44+
}
45+
]
46+
}, context());
47+
context.Promise
48+
.then(function () {
49+
// succeed() called
50+
done();
51+
})
52+
.catch(function (err) {
53+
// fail() called
54+
done(err);
55+
});
56+
});
57+
58+
});
59+

0 commit comments

Comments
 (0)