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