source: Dev/trunk/src/server/api/open.js @ 527

Last change on this file since 527 was 527, checked in by hendrikvanantwerpen, 11 years ago
  • Dropped request module for a simple one we wrote ourselves using the native Node modules. Hopefully this one will not suffer from the problem that sometimes empty bodies are returned even when the statuscode and content-length of the request are ok & present.
  • Handle exceptions better in HTTPResult chain, they were hoisted in unknown responses before. Should we not include them in default processing, because they are special?
File size: 6.6 KB
Line 
1var express = require("express")
2  , cryptoken = require("../util/crypto-token")
3  , HTTPResult = require("../util/http-result")
4  , etags = require("../util/etags")
5  ;
6
7module.exports = function(couch,schema) {
8    var exports = {};
9
10    var util = require('./util')(couch,schema);
11    var app = exports.app = express();
12
13    var isSurveyRunRunning = exports.isSurveyRunRunning = function(surveyRun) {
14        var now = new Date();
15        var afterStart = !surveyRun.startDate || now >= new Date(surveyRun.startDate);
16        var beforeEnd = !surveyRun.endDate || now <= new Date(surveyRun.endDate);
17        return afterStart && beforeEnd;
18    };
19
20    app.get('/responses/:id',
21        util.ensureMIME(util.JSON_MIME),
22        function(req,res) {
23            var id = req.params.id;
24            var rev = etags.parse(req.header('If-Non-Match'))[0];
25            var secret = req.query.secret;
26            util.getDocument(id,rev,'Response')
27            .handle({
28                200: function(response) {
29                    if ( response.secret === secret ) {
30                        return util.getDocument(response.surveyRunId,[],'SurveyRun')
31                        .handle({
32                            200: function(surveyRun) {
33                                if ( !isSurveyRunRunning(surveyRun) ) {
34                                    return new HTTPResult(404,{error:"Survey is not running anymore."});
35                                } else {
36                                    response._surveyRun = surveyRun;
37                                    return response;
38                                }
39                            }
40                        });
41                    } else {
42                        return new HTTPResult(403,{error: "Wrong secret for response"});
43                    }
44                }
45            })
46            .handle({'-1': util.handleException})
47            .handle(res.send.bind(res));
48        });
49    app.post('/responses',
50        util.ensureMIME(util.JSON_MIME),
51        function(req,res) {
52            var secret = req.query.secret;
53            var response = req.body;
54            delete response._surveyRun;
55            util.getDocument(response.surveyRunId,[],'SurveyRun')
56            .handle({
57                200: function(surveyRun) {
58                    if ( surveyRun.secret !== secret ) {
59                        return new HTTPResult(403,{error:"Wrong secret for surveyRun."});
60                    } else if ( !isSurveyRunRunning(surveyRun) ) {
61                        return new HTTPResult(404,{error:"Survey is not running anymore."});
62                    } else if ( surveyRun.mode === 'closed' ) {
63                        return new HTTPResult(403,{error:"Survey is closed and doesn't allow new responses."});
64                    } else {
65                        return cryptoken()
66                        .then(function(token) {
67                            response.secret = token;
68                            return util.postDocument('Response',response)
69                            .then(function(doc){
70                                doc._surveyRun = surveyRun;
71                                return doc;
72                            });
73                        });
74                    }
75                }
76            })
77            .handle({'-1': util.handleException})
78            .handle(res.send.bind(res));
79        });
80    app.put('/responses/:id',
81        util.ensureMIME(util.JSON_MIME),
82        function(req,res){
83            var id = req.params.id;
84            var doc = req.body;
85            var rev = etags.parse(req.header('If-Match'))[0] || (doc && doc._rev);
86            var secret = req.query.secret || doc.secret;
87            delete doc._surveyRun;
88            util.getDocument(id,[],'Response')
89            .handle({
90                200: function(prev) {
91                    if ( prev.secret !== secret ) {
92                        return new HTTPResult(403,{error: "Secrets are not the same."});
93                    } else if ( prev.surveyRunId !== doc.surveyRunId ) {
94                        return new HTTPResult(400,{error:"Response cannot change it's surveyRunId."});
95                    } else {
96                        doc.secret = secret; // restore in case it got lost or was changed
97                        return util.getDocument(doc.surveyRunId,[],'SurveyRun')
98                        .handle({
99                            200: function(surveyRun) {
100                                if ( !isSurveyRunRunning(surveyRun) ) {
101                                    return new HTTPResult(404,{error:"Survey is not running anymore."});
102                                } else {
103                                    return util.putDocument(id,rev,'Response',doc)
104                                    .handle({
105                                        200: function(doc) {
106                                            doc._surveyRun = surveyRun;
107                                            return new HTTPResult(201,doc);
108                                        }
109                                    });
110                                }
111                            }
112                        });
113                    }
114                }
115            })
116            .handle({'-1': util.handleException})
117            .handle(res.send.bind(res));
118        });
119    app.delete('/responses/:id',
120        util.ensureMIME(util.JSON_MIME),
121        function(req,res){
122            var id = req.params.id;
123            var doc = req.body;
124            var rev = etags.parse(req.header('If-Match'))[0] || (doc && doc._rev);
125            var secret = req.query.secret || doc.secret;
126            delete doc._surveyRun;
127            util.getDocument(id,[],'Response')
128            .handle({
129                200: function(prev) {
130                    if ( prev.secret !== secret ) {
131                        return new HTTPResult(403,{error: "Secrets are not the same."});
132                    } else {
133                        return util.getDocument(doc.surveyRunId,[],'SurveyRun')
134                        .handle({
135                            200: function(surveyRun) {
136                                if ( surveyRun.respondentCanDeleteOwnResponse === true ) {
137                                    return util.deleteDocument(id,rev,doc);
138                                } else {
139                                    return new HTTPResult(403,{error:"Not allowed to delete response."});
140                                }
141                            }
142                        });
143                    }
144                }
145            })
146            .handle({'-1': util.handleException})
147            .handle(res.send.bind(res));
148        });
149
150    return exports;
151};
Note: See TracBrowser for help on using the repository browser.