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