Skip to content

Commit

Permalink
ensure only admins can create test devices, and fix world map permiss…
Browse files Browse the repository at this point in the history
…ions
  • Loading branch information
timcowlishaw committed Oct 3, 2024
1 parent 371642c commit d685440
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 10 deletions.
6 changes: 5 additions & 1 deletion app/controllers/v0/devices_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,11 @@ def device_params

# Researchers + Admins can update is_test and enable_forwarding
if current_user.is_admin_or_researcher?
params_to_permit.push(:is_test, :enable_forwarding)
params_to_permit.push(:enable_forwarding)
end

if current_user.is_admin?
params_to_permit.push(:is_test)
end

params.permit(
Expand Down
11 changes: 9 additions & 2 deletions app/models/device.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,15 @@ class Device < ActiveRecord::Base
end
end

scope :for_world_map, -> {
where.not(latitude: nil).where.not(last_reading_at: nil).where(is_test: false).includes(:owner, :tags)
scope :for_world_map, ->(authorized_user=nil) {
privacy_conditions = if authorized_user && authorized_user.is_admin?
[]
elsif authorized_user
["is_private IS NOT true OR owner_id = ?", authorized_user.id]
else
["is_private IS NOT true"]
end
where.not(latitude: nil).where.not(last_reading_at: nil).where(is_test: false).where(privacy_conditions).includes(:owner, :tags)
}

def self.ransackable_attributes(auth_object = nil)
Expand Down
2 changes: 1 addition & 1 deletion app/views/v0/devices/_world_map_list.jbuilder
Original file line number Diff line number Diff line change
@@ -1 +1 @@
json.array! Device.for_world_map, partial: 'device', as: :device, local_assigns: { with_data: false, with_postprocessing: false, slim_owner: true, never_authorized: never_authorized }
json.array! Device.for_world_map(!never_authorized && current_user), partial: 'device', as: :device, local_assigns: { with_data: false, with_postprocessing: false, slim_owner: true, never_authorized: never_authorized }
1 change: 0 additions & 1 deletion spec/factories/devices.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,4 @@
elevation { 100 }
hardware_info { { "id":47,"uuid":"7d45fead-defd-4482-bc6a-a1b711879e2d" } }
end

end
38 changes: 38 additions & 0 deletions spec/models/device_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,45 @@
expect(device.find_or_create_component_by_sensor_id(nil)).to be_blank
end
end
end

context ".for_world_map" do

let(:current_user) { create(:user) }
let(:other_user) { create(:user) }
let(:admin) { create(:admin) }

let(:public_device) { create(:device, last_reading_at: Time.now) }
let(:my_private_device) { create(:device, is_private: true, owner: current_user, last_reading_at: Time.now) }
let(:their_private_device) { create(:device, is_private: true, owner: other_user, last_reading_at: Time.now) }


context "when no authorized user is provided" do
it "only returns public devices" do
results = Device.for_world_map(false)
expect(results).to include(public_device)
expect(results).not_to include(my_private_device)
expect(results).not_to include(their_private_device)
end
end

context "when a non-admin user is provided" do
it "only returns public devices, and private devices owned by the current user" do
results = Device.for_world_map(current_user)
expect(results).to include(public_device)
expect(results).to include(my_private_device)
expect(results).not_to include(their_private_device)
end
end

context "when an admin user is provided" do
it "returns all devices" do
results = Device.for_world_map(admin)
expect(results).to include(public_device)
expect(results).to include(my_private_device)
expect(results).to include(their_private_device)
end
end
end

end
21 changes: 16 additions & 5 deletions spec/requests/v0/devices_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,26 @@

describe "world map" do
it "returns all devices" do
first = create(:device, data: { "": Time.now })
second = create(:device, data: { "": Time.now })
Rails.cache.clear
first = create(:device, last_reading_at: Time.now)
second = create(:device, last_reading_at: Time.now)
json = api_get "devices/world_map"
expect(response.status).to eq(200)
# World map is not always sorted. This test fails at random
#expect(json.map{|j| j['id']}).to eq([first, second].map(&:id))
ids = json.map { |d| d["id"] }
expect(ids).to include(first.id)
expect(ids).to include(second.id)
end

it "does not include private devices" do
Rails.cache.clear
public_device = create(:device, last_reading_at: Time.now)
private_device = create(:device, is_private: true, last_reading_at: Time.now)
json = api_get "devices/world_map"
ids = json.map { |d| d["id"] }
expect(ids).to include(public_device.id)
expect(ids).not_to include(private_device.id)
end

skip "needs more specs"
end

describe "with near" do
Expand Down

0 comments on commit d685440

Please sign in to comment.