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