]> git.openstreetmap.org Git - rails.git/blob - app/controllers/api/traces_controller.rb
Merge remote-tracking branch 'upstream/pull/5957'
[rails.git] / app / controllers / api / traces_controller.rb
1 module Api
2   class TracesController < ApiController
3     before_action :check_api_writable, :only => [:create, :update, :destroy]
4     before_action :set_request_formats, :only => [:show]
5     before_action :set_locale
6     before_action :authorize
7
8     authorize_resource
9
10     before_action :offline_error, :only => [:create, :destroy]
11     skip_around_action :api_call_timeout, :only => :create
12
13     def show
14       @trace = Trace.visible.find(params[:id])
15
16       return head :forbidden unless @trace.public? || @trace.user == current_user
17
18       respond_to do |format|
19         format.xml
20         format.json
21       end
22     end
23
24     def create
25       tags = params[:tags] || ""
26       description = params[:description] || ""
27       visibility = params[:visibility]
28
29       if visibility.nil?
30         visibility = if params[:public]&.to_i&.nonzero?
31                        "public"
32                      else
33                        "private"
34                      end
35       end
36
37       if params[:file].respond_to?(:read)
38         trace = do_create(params[:file], tags, description, visibility)
39
40         if trace.id
41           trace.schedule_import
42           render :plain => trace.id.to_s
43         elsif trace.valid?
44           head :internal_server_error
45         else
46           head :bad_request
47         end
48       else
49         head :bad_request
50       end
51     end
52
53     def update
54       trace = Trace.visible.find(params[:id])
55
56       if trace.user == current_user
57         trace.update_from_xml(request.raw_post)
58         trace.save!
59
60         head :ok
61       else
62         head :forbidden
63       end
64     end
65
66     def destroy
67       trace = Trace.visible.find(params[:id])
68
69       if trace.user == current_user
70         trace.visible = false
71         trace.save!
72         trace.schedule_destruction
73
74         head :ok
75       else
76         head :forbidden
77       end
78     end
79
80     private
81
82     def do_create(file, tags, description, visibility)
83       # Sanitise the user's filename
84       name = file.original_filename.gsub(/[^a-zA-Z0-9.]/, "_")
85
86       # Create the trace object, falsely marked as already
87       # inserted to stop the import daemon trying to load it
88       trace = Trace.new(
89         :name => name,
90         :tagstring => tags,
91         :description => description,
92         :visibility => visibility,
93         :inserted => false,
94         :user => current_user,
95         :timestamp => Time.now.utc,
96         :file => file
97       )
98
99       # Save the trace object
100       trace.save!
101
102       # Finally save the user's preferred privacy level
103       if pref = current_user.preferences.find_by(:k => "gps.trace.visibility")
104         pref.v = visibility
105         pref.save
106       else
107         current_user.preferences.create(:k => "gps.trace.visibility", :v => visibility)
108       end
109
110       trace
111     end
112
113     def offline_error
114       report_error "GPX files offline for maintenance", :service_unavailable if Settings.status == "gpx_offline"
115     end
116   end
117 end