fixed topic delete not post method security problem.

This commit is contained in:
fengmk2 2013-01-06 14:08:57 +08:00
parent cb62ca84cc
commit bcb7f3e75d
7 changed files with 62 additions and 53 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
config.js
.cov
node_modules
.naeindex
public/user_data

View File

@ -1,25 +1,25 @@
TESTS = $(shell find test -type f -name "*.js")
TESTTIMEOUT = 5000
REPORTER = spec
JSCOVERAGE = ./node_modules/visionmedia-jscoverage/jscoverage
PROJECT_DIR = $(shell pwd)
JSCOVERAGE = ./node_modules/jscover/bin/jscover
test:
install:
@npm install
test: install
@if ! test -f config.js; then \
cp config.default.js config.js; \
fi
@NODE_ENV=test ./node_modules/mocha/bin/mocha \
--reporter $(REPORTER) --timeout $(TESTTIMEOUT) $(TESTS)
cov:
@rm -rf ../nodeclub-cov
@$(JSCOVERAGE) --encoding=utf-8 --exclude=node_modules --exclude=public --exclude=test ./ ../nodeclub-cov
@cp -rf ./node_modules ./test ./public ../nodeclub-cov
cov: install
@rm -rf .cov
@$(JSCOVERAGE) --exclude=public --exclude=test . .cov
@cp -rf node_modules test public .cov
test-cov: cov
@$(MAKE) -C $(PROJECT_DIR)/../nodeclub-cov test REPORTER=progress
@$(MAKE) -C $(PROJECT_DIR)/../nodeclub-cov test REPORTER=html-cov > coverage.html
@$(MAKE) test REPORTER=markdown > test_results.md
@$(MAKE) -C .cov test REPORTER=progress
@$(MAKE) -C .cov test REPORTER=html-cov > coverage.html
.PHONY: test test-cov cov

View File

@ -1,6 +1,4 @@
# nodeclub
[![Build Status](https://secure.travis-ci.org/cnodejs/nodeclub.png?branch=master)](http://travis-ci.org/cnodejs/nodeclub)
# nodeclub [![Build Status](https://secure.travis-ci.org/cnodejs/nodeclub.png?branch=master)](http://travis-ci.org/cnodejs/nodeclub)
基于nodejs的社区系统
@ -32,7 +30,6 @@ jscoverage
$ make test-cov
```
* test results: [test_results.md](https://github.com/cnodejs/nodeclub/blob/master/test_results.md)
* jscoverage: [**31%**](http://fengmk2.github.com/coverage/nodeclub.html)
## 其它
@ -101,7 +98,7 @@ Below is the output from `git-summary`.
( The MIT License )
Copyright (c) 2012 muyuan, fengmk2 and other nodeclub contributors
Copyright (c) 2012 - 2013 muyuan, fengmk2 and other nodeclub contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@ -51,7 +51,7 @@ exports.index = function (req, res, next) {
next(err);
});
ep.once('topic', function(topic) {
ep.once('topic', function (topic) {
if (topic.content_is_html) {
return ep.emit('@user');
}
@ -120,9 +120,11 @@ exports.index = function (req, res, next) {
});
// get no reply topics
var options2 = { limit:5, sort: [ ['create_at', 'desc'] ] };
get_topics_by_query({ reply_count: 0 }, options2, function(err, topics) {
if (err) return ep.emit('error', err);
var options2 = { limit: 5, sort: [ ['create_at', 'desc'] ] };
get_topics_by_query({ reply_count: 0 }, options2, function (err, topics) {
if (err) {
return ep.emit('error', err);
}
ep.emit('no_reply_topics', topics);
});
});
@ -135,8 +137,8 @@ exports.create = function (req, res, next) {
}
var method = req.method.toLowerCase();
if(method == 'get'){
tag_ctrl.get_all_tags(function(err,tags){
if (method === 'get') {
tag_ctrl.get_all_tags(function (err, tags) {
if(err) return next(err);
res.render('topic/edit',{tags:tags});
return;
@ -384,33 +386,30 @@ exports.edit = function(req,res,next){
}
};
exports.delete = function(req,res,next){
exports.delete = function (req,res,next) {
//删除话题, 话题作者topic_count减1
//删除回复回复作者reply_count减1
//删除topic_tag标签topic_count减1
//删除topic_collect用户collect_topic_count减1
if(!req.session.user || !req.session.user.is_admin){
res.redirect('home');
return;
if (!req.session.user || !req.session.user.is_admin) {
return res.send({ success: false, message: '无权限' })
}
var topic_id = req.params.tid;
if(topic_id.length != 24){
res.render('notify/notify',{error: '此话题不存在或已被删除。'});
return;
if (topic_id.length !== 24) {
return res.send({ success: false, error: '此话题不存在或已被删除。' });
}
get_topic_by_id(topic_id,function(err,topic,tags,author){
if(!topic){
res.render('notify/notify',{error: '此话题不存在或已被删除。'});
return;
get_topic_by_id(topic_id, function (err, topic, tags, author) {
if (err) {
return res.send({ success: false, message: err.message });
}
var proxy = new EventProxy();
var render = function(){
res.render('notify/notify',{success: '话题已被删除。'});
return;
if (!topic) {
return res.send({ success: false, message: '此话题不存在或已被删除。' });
}
proxy.assign('topic_removed',render);
topic.remove(function(err){
proxy.emit('topic_removed');
topic.remove(function (err) {
if (err) {
return res.send({ success: false, message: err.message });
}
res.send({ success: true, message: '话题已被删除。' });
});
});
};

View File

@ -1,25 +1,25 @@
{
"name": "nodeclub",
"version": "0.3.2",
"main": "./app.js",
"main": "app.js",
"private": true,
"dependencies": {
"express": "2.5.1",
"ejs": ">=0.8.0",
"eventproxy": ">=0.1.0",
"ejs": "0.8.0",
"eventproxy": "0.2.1",
"mongoose": "2.4.1",
"node-markdown": "0.1.0",
"validator": "0.3.7",
"ndir": ">=0.1.3",
"ndir": "0.1.3",
"nodemailer": "0.3.5",
"data2xml": "0.4.0",
"xss": ">=0.0.2"
"xss": "0.0.3"
},
"devDependencies": {
"should": "*",
"mocha": "*",
"rewire": "0.3.0",
"visionmedia-jscoverage": "*"
"rewire": "*",
"jscover": "*"
},
"scripts": {
"test": "make test"

View File

@ -76,7 +76,12 @@ module.exports = function (app) {
app.get('/topic/:tid', topic.index);
app.get('/topic/:tid/top/:is_top?', topic.top);
app.get('/topic/:tid/edit', topic.edit);
app.get('/topic/:tid/delete', topic.delete);
// Po-Ying Chen <poying.me@gmail.com>: 當 "非" 作者的使用者在留言的地方貼上一個網址為
// http://[domain name]/topic/[topic id]/delete 的圖片之後,只要作者一看到圖片,文章就會被刪除了,
// 可能需要將刪除的方法改成 post 來避免此問題
app.post('/topic/:tid/delete', topic.delete);
app.post('/topic/create', topic.create);
app.post('/topic/:tid/edit', topic.edit);
app.post('/topic/collect', topic.collect);

View File

@ -88,7 +88,7 @@
<a href='/topic/<%= topic._id %>/top/1'><img class='user_icon' src='<%- config.site_static_host %>/images/star_fav_icon&16.png' title='置顶' /></a>
<% } %>
<a href='/topic/<%= topic._id %>/edit'><img class='user_icon' src='<%- config.site_static_host %>/images/doc_edit_icon&16.png' title='编辑' /></a>
<a href='/topic/<%= topic._id %>/delete' class='delete_topic_btn'><img class='user_icon' src='<%- config.site_static_host %>/images/trash_icon&16.png' title='删除' /></a>
<a href='javascript:;' data-id="<%= topic._id %>" class='delete_topic_btn'><img class='user_icon' src='<%- config.site_static_host %>/images/trash_icon&16.png' title='删除' /></a>
<% } else { %>
<% if (current_user._id == topic.author_id) { %>
<span class='sp10'></span>
@ -129,7 +129,7 @@
<div id='wmd-preview' class='wmd-preview reply-wmd-preview'></div>
</div>
</div>
<input type='hidden' name='_csrf' value='<%= csrf %>' />
<input type='hidden' name='_csrf' id="_csrf" value='<%= csrf %>' />
</div>
<div class='sep10'></div>
<button id='submit_btn' class='btn'>回复</button>
@ -281,7 +281,7 @@
reply_id: reply_id,
_csrf: "<%- csrf %>"
};
$.post('/reply/' + reply_id + '/delete', data, function(data) {
$.post('/reply/' + reply_id + '/delete', data, function (data) {
if (data.status === 'success') {
if($me.hasClass('delete_reply_btn')){
$me.parents('.reply_item').remove();
@ -295,9 +295,16 @@
return false;
});
$('.delete_topic_btn').click(function() {
if(confirm('确定要删除此话题吗?')) {
window.location.href = $(this).attr('href');
$('.delete_topic_btn').click(function () {
var topicId = $(this).data('id');
if (topicId && confirm('确定要删除此话题吗?')) {
$.post('/topic/' + topicId + '/delete', { _csrf: $('#_csrf').val() }, function (result) {
if (!result.success) {
alert(result.message);
} else {
window.location.href = '/';
}
});
}
return false;
});