- Add security

- Add configuration option on categories to enable
This commit is contained in:
Sam Saffron 2015-06-10 06:09:20 +10:00
parent a4e9ee4552
commit 09292d6ff9
6 changed files with 67 additions and 9 deletions

View File

@ -0,0 +1,8 @@
<section class='field'>
<div class="enable-accepted-answer">
<label class="checkbox-label">
{{input type="checkbox" checked=model.enable_accepted_answers}}
{{i18n 'accepted_answer.allow_accepted_answers'}}
</label>
</div>
</section>

View File

@ -8,6 +8,16 @@ export default {
name: 'extend-for-solved-button',
initialize: function() {
Discourse.Category.reopen({
enable_accepted_answers: function(key, value){
if (arguments.length > 1) {
this.set('custom_fields.enable_accepted_answers', value ? "true" : "false");
}
var fields = this.get('custom_fields');
return fields && (fields.enable_accepted_answers === "true");
}.property('custom_fields')
}),
Topic.reopen({
// keeping this here cause there is complex localization

View File

@ -1,6 +1,7 @@
en:
js:
accepted_answer:
allow_accepted_answers: "Allow users to accept answers"
accept_answer: "Accept answer"
unaccept_answer: "Unaccept answer"
accepted_html: "<i class='fa-check-square fa accepted'></i> Solved by <a href data-user-card='{{username_lower}}'>{{username}}</a> in <a href='{{post_path}}'>post #{{post_number}}</a>"

View File

@ -1,3 +0,0 @@
en:
site_settings:
categories_with_solved_button: "List of categories where solved button is allowed"

View File

@ -1,4 +0,0 @@
uncategorized:
categories_with_solved_button:
default: ''
client: true

View File

@ -19,9 +19,10 @@ after_initialize do
require_dependency "application_controller"
class DiscourseSolvedButton::AnswerController < ::ApplicationController
def accept
post = Post.find(params[:id].to_i)
guardian.ensure_can_accept_answer!(post.topic)
accepted_id = post.topic.custom_fields["accepted_answer_post_id"].to_i
if accepted_id > 0
if p2 = Post.find_by(id: accepted_id)
@ -40,6 +41,9 @@ after_initialize do
def unaccept
post = Post.find(params[:id].to_i)
guardian.ensure_can_accept_answer!(post.topic)
post.custom_fields["is_accepted_answer"] = nil
post.topic.custom_fields["accepted_answer_post_id"] = nil
post.topic.save!
@ -95,6 +99,44 @@ after_initialize do
end
class ::Category
after_save :reset_accepted_cache
protected
def reset_accepted_cache
::Guardian.reset_accepted_answer_cache
end
end
class ::Guardian
@@allowed_accepted_cache = DistributedCache.new("allowed_accepted")
def self.reset_accepted_answer_cache
@@allowed_accepted_cache["allowed"] =
begin
Set.new(
CategoryCustomField
.where(name: "enable_accepted_answers", value: "true")
.pluck(:category_id)
)
end
end
def allow_accepted_answers_on_category?(category_id)
self.class.reset_accepted_answer_cache unless @@allowed_accepted_cache["allowed"]
@@allowed_accepted_cache["allowed"].include?(category_id)
end
def can_accept_answer?(topic)
allow_accepted_answers_on_category?(topic.category_id) && (
is_staff? || (
authenticated? && !topic.closed? && topic.user_id == current_user.id
)
)
end
end
require_dependency 'post_serializer'
class ::PostSerializer
attributes :can_accept_answer, :can_unaccept_answer, :accepted_answer
@ -102,12 +144,16 @@ after_initialize do
def can_accept_answer
topic = (topic_view && topic_view.topic) || object.topic
if topic
scope.can_accept_answer?(topic) &&
object.post_number > 1 && !accepted_answer
end
end
def can_unaccept_answer
post_custom_fields["is_accepted_answer"]
topic = (topic_view && topic_view.topic) || object.topic
if topic
scope.can_accept_answer?(topic) && post_custom_fields["is_accepted_answer"]
end
end
def accepted_answer