Skip CSRF verification for changeset comment actions
[rails.git] / app / controllers / changeset_comments_controller.rb
1 class ChangesetCommentsController < ApplicationController
2   skip_before_action :verify_authenticity_token, :except => [:index]
3   before_action :authorize_web, :only => [:index]
4   before_action :set_locale, :only => [:index]
5   before_action :authorize, :only => [:create, :destroy, :restore]
6   before_action :require_moderator, :only => [:destroy, :restore]
7   before_action :require_allow_write_api, :only => [:create, :destroy, :restore]
8   before_action :require_public_data, :only => [:create]
9   before_action :check_api_writable, :only => [:create, :destroy, :restore]
10   before_action :check_api_readable, :except => [:create, :index]
11   before_action(:only => [:index]) { |c| c.check_database_readable(true) }
12   around_action :api_call_handle_error, :except => [:index]
13   around_action :api_call_timeout, :except => [:index]
14   around_action :web_timeout, :only => [:index]
15
16   ##
17   # Add a comment to a changeset
18   def create
19     # Check the arguments are sane
20     raise OSM::APIBadUserInput, "No id was given" unless params[:id]
21     raise OSM::APIBadUserInput, "No text was given" if params[:text].blank?
22
23     # Extract the arguments
24     id = params[:id].to_i
25     body = params[:text]
26
27     # Find the changeset and check it is valid
28     changeset = Changeset.find(id)
29     raise OSM::APIChangesetNotYetClosedError, changeset if changeset.is_open?
30
31     # Add a comment to the changeset
32     comment = changeset.comments.create(:changeset => changeset,
33                                         :body => body,
34                                         :author => current_user)
35
36     # Notify current subscribers of the new comment
37     changeset.subscribers.visible.each do |user|
38       Notifier.changeset_comment_notification(comment, user).deliver_later if current_user != user
39     end
40
41     # Add the commenter to the subscribers if necessary
42     changeset.subscribers << current_user unless changeset.subscribers.exists?(current_user.id)
43
44     # Return a copy of the updated changeset
45     render :xml => changeset.to_xml.to_s
46   end
47
48   ##
49   # Sets visible flag on comment to false
50   def destroy
51     # Check the arguments are sane
52     raise OSM::APIBadUserInput, "No id was given" unless params[:id]
53
54     # Extract the arguments
55     id = params[:id].to_i
56
57     # Find the changeset
58     comment = ChangesetComment.find(id)
59
60     # Hide the comment
61     comment.update(:visible => false)
62
63     # Return a copy of the updated changeset
64     render :xml => comment.changeset.to_xml.to_s
65   end
66
67   ##
68   # Sets visible flag on comment to true
69   def restore
70     # Check the arguments are sane
71     raise OSM::APIBadUserInput, "No id was given" unless params[:id]
72
73     # Extract the arguments
74     id = params[:id].to_i
75
76     # Find the changeset
77     comment = ChangesetComment.find(id)
78
79     # Unhide the comment
80     comment.update(:visible => true)
81
82     # Return a copy of the updated changeset
83     render :xml => comment.changeset.to_xml.to_s
84   end
85
86   ##
87   # Get a feed of recent changeset comments
88   def index
89     if params[:id]
90       # Extract the arguments
91       id = params[:id].to_i
92
93       # Find the changeset
94       changeset = Changeset.find(id)
95
96       # Return comments for this changeset only
97       @comments = changeset.comments.includes(:author, :changeset).limit(comments_limit)
98     else
99       # Return comments
100       @comments = ChangesetComment.includes(:author, :changeset).where(:visible => true).order("created_at DESC").limit(comments_limit).preload(:changeset)
101     end
102
103     # Render the result
104     respond_to do |format|
105       format.rss
106     end
107   rescue OSM::APIBadUserInput
108     head :bad_request
109   end
110
111   private
112
113   ##
114   # Get the maximum number of comments to return
115   def comments_limit
116     if params[:limit]
117       if params[:limit].to_i.positive? && params[:limit].to_i <= 10000
118         params[:limit].to_i
119       else
120         raise OSM::APIBadUserInput, "Comments limit must be between 1 and 10000"
121       end
122     else
123       100
124     end
125   end
126 end