]> git.openstreetmap.org Git - rails.git/blob - app/controllers/api/messages_controller.rb
Merge remote-tracking branch 'upstream/pull/5106'
[rails.git] / app / controllers / api / messages_controller.rb
1 # The MessagesController is the RESTful interface to Message objects
2
3 module Api
4   class MessagesController < ApiController
5     before_action :authorize
6
7     before_action :check_api_writable, :only => [:create, :update, :destroy]
8     before_action :check_api_readable, :except => [:create, :update, :destroy]
9
10     authorize_resource
11
12     around_action :api_call_handle_error, :api_call_timeout
13
14     before_action :set_request_formats
15
16     def inbox
17       @skip_body = true
18       @messages = Message.includes(:sender, :recipient).where(:to_user_id => current_user.id)
19
20       show_messages
21     end
22
23     def outbox
24       @skip_body = true
25       @messages = Message.includes(:sender, :recipient).where(:from_user_id => current_user.id)
26
27       show_messages
28     end
29
30     # Dump the details on a message given in params[:id]
31     def show
32       @message = Message.includes(:sender, :recipient).find(params[:id])
33
34       raise OSM::APIAccessDenied if current_user.id != @message.from_user_id && current_user.id != @message.to_user_id
35
36       # Render the result
37       respond_to do |format|
38         format.xml
39         format.json
40       end
41     end
42
43     # Create a new message from current user
44     def create
45       # Check the arguments are sane
46       raise OSM::APIBadUserInput, "No title was given" if params[:title].blank?
47       raise OSM::APIBadUserInput, "No body was given" if params[:body].blank?
48
49       # Extract the arguments
50       if params[:recipient_id]
51         recipient_id = params[:recipient_id].to_i
52         recipient = User.find(recipient_id)
53       elsif params[:recipient]
54         recipient_display_name = params[:recipient]
55         recipient = User.find_by(:display_name => recipient_display_name)
56       else
57         raise OSM::APIBadUserInput, "No recipient was given"
58       end
59
60       raise OSM::APIRateLimitExceeded if current_user.sent_messages.where(:sent_on => Time.now.utc - 1.hour..).count >= current_user.max_messages_per_hour
61
62       @message = Message.new(:sender => current_user,
63                              :recipient => recipient,
64                              :sent_on => Time.now.utc,
65                              :title => params[:title],
66                              :body => params[:body],
67                              :body_format => "markdown")
68       @message.save!
69
70       UserMailer.message_notification(@message).deliver_later if @message.notify_recipient?
71
72       # Return a copy of the new message
73       respond_to do |format|
74         format.xml { render :action => :show }
75         format.json { render :action => :show }
76       end
77     end
78
79     # Update read status of a message
80     def update
81       @message = Message.find(params[:id])
82       read_status_idx = %w[true false].index params[:read_status]
83
84       raise OSM::APIBadUserInput, "Invalid value of `read_status` was given" if read_status_idx.nil?
85       raise OSM::APIAccessDenied unless current_user.id == @message.to_user_id
86
87       @message.message_read = read_status_idx.zero?
88       @message.save!
89
90       # Return a copy of the message
91       respond_to do |format|
92         format.xml { render :action => :show }
93         format.json { render :action => :show }
94       end
95     end
96
97     # Delete message by marking it as not visible for the current user
98     def destroy
99       @message = Message.find(params[:id])
100       if current_user.id == @message.from_user_id
101         @message.from_user_visible = false
102       elsif current_user.id == @message.to_user_id
103         @message.to_user_visible = false
104       else
105         raise OSM::APIAccessDenied
106       end
107
108       @message.save!
109
110       # Return a copy of the message
111       respond_to do |format|
112         format.xml { render :action => :show }
113         format.json { render :action => :show }
114       end
115     end
116
117     private
118
119     def show_messages
120       @messages = @messages.where(:muted => false)
121       if params[:order].nil? || params[:order] == "newest"
122         @messages = @messages.where(:id => ..params[:from_id]) unless params[:from_id].nil?
123         @messages = @messages.order(:id => :desc)
124       elsif params[:order] == "oldest"
125         @messages = @messages.where(:id => params[:from_id]..) unless params[:from_id].nil?
126         @messages = @messages.order(:id => :asc)
127       else
128         raise OSM::APIBadUserInput, "Invalid order specified"
129       end
130
131       limit = params[:limit]
132       if !limit
133         limit = Settings.default_message_query_limit
134       elsif !limit.to_i.positive? || limit.to_i > Settings.max_message_query_limit
135         raise OSM::APIBadUserInput, "Messages limit must be between 1 and #{Settings.max_message_query_limit}"
136       else
137         limit = limit.to_i
138       end
139
140       @messages = @messages.limit(limit)
141
142       # Render the result
143       respond_to do |format|
144         format.xml
145         format.json
146       end
147     end
148   end
149 end