2 * Copyright 2014 IBM Corp.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 var should = require("should");
18 var sinon = require('sinon');
19 var request = require('supertest');
20 var http = require('http');
21 var express = require('express');
23 var fs = require('fs-extra');
24 var path = require('path');
25 var when = require('when');
28 var RED = require("../../red/red.js");
29 var server = require("../../red/server.js");
30 var nodes = require("../../red/nodes");
32 describe("library", function() {
33 var userDir = path.join(__dirname,".testUserHome");
34 before(function(done) {
35 fs.remove(userDir,function(err) {
36 fs.mkdir(userDir,function() {
37 sinon.stub(nodes, 'load', function() {
38 return when.promise(function(resolve,reject){
42 RED.init(http.createServer(function(req,res){app(req,res)}),
44 server.start().then(function () { done(); });
49 after(function(done) {
50 fs.remove(userDir,done);
55 afterEach(function(done) {
56 fs.remove(userDir,function(err) {
57 fs.mkdir(userDir,done);
61 describe("flows", function() {
62 it('returns empty result', function(done) {
63 request(RED.httpAdmin)
64 .get('/library/flows')
66 .end(function(err,res) {
70 res.body.should.not.have.property('f');
75 it('returns 404 for non-existent entry', function(done) {
76 request(RED.httpAdmin)
77 .get('/library/flows/foo')
82 it('can store and retrieve item', function(done) {
84 request(RED.httpAdmin)
85 .post('/library/flows/foo')
86 .set('Content-Type', 'text/plain')
88 .expect(204).end(function (err, res) {
92 request(RED.httpAdmin)
93 .get('/library/flows/foo')
95 .end(function(err,res) {
99 res.text.should.equal(flow);
105 it('lists a stored item', function(done) {
106 request(RED.httpAdmin)
107 .post('/library/flows/bar')
110 request(RED.httpAdmin)
111 .get('/library/flows')
113 .end(function(err,res) {
117 res.body.should.have.property('f');
118 should.deepEqual(res.body.f,['bar']);
124 it('returns 403 for malicious access attempt', function(done) {
125 // without the userDir override the malicious url would be
126 // http://127.0.0.1:1880/library/flows/../../package to
127 // obtain package.json from the node-red root.
128 request(RED.httpAdmin)
129 .get('/library/flows/../../../../../package')
134 it('returns 403 for malicious access attempt', function(done) {
135 // without the userDir override the malicious url would be
136 // http://127.0.0.1:1880/library/flows/../../package to
137 // obtain package.json from the node-red root.
138 request(RED.httpAdmin)
139 .post('/library/flows/../../../../../package')
146 describe("type", function() {
148 RED.library.register('test');
151 it('returns empty result', function(done) {
152 request(RED.httpAdmin)
153 .get('/library/test')
155 .end(function(err,res) {
159 res.body.should.not.have.property('f');
164 it('returns 404 for non-existent entry', function(done) {
165 request(RED.httpAdmin)
166 .get('/library/test/foo')
171 it('can store and retrieve item', function(done) {
173 request(RED.httpAdmin)
174 .post('/library/test/foo')
175 .set('Content-Type', 'text/plain')
177 .expect(204).end(function (err, res) {
181 request(RED.httpAdmin)
182 .get('/library/test/foo')
184 .end(function(err,res) {
188 res.text.should.equal(flow);
194 it('lists a stored item', function(done) {
195 request(RED.httpAdmin)
196 .post('/library/test/bar')
199 request(RED.httpAdmin)
200 .get('/library/test')
202 .end(function(err,res) {
206 should.deepEqual(res.body,[{ fn: 'bar'}]);
213 it('returns 403 for malicious access attempt', function(done) {
214 request(RED.httpAdmin)
215 .get('/library/test/../../../../../../../../../../etc/passwd')
220 it('returns 403 for malicious access attempt', function(done) {
221 request(RED.httpAdmin)
222 .get('/library/test/..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\etc\\passwd')
227 it('returns 403 for malicious access attempt', function(done) {
228 request(RED.httpAdmin)
229 .post('/library/test/../../../../../../../../../../etc/passwd')
230 .set('Content-Type', 'text/plain')
231 .send('root:x:0:0:root:/root:/usr/bin/tclsh')