Compare commits
4 commits
b79c954d3b
...
212524429f
Author | SHA1 | Date | |
---|---|---|---|
|
212524429f | ||
|
455a00ecc0 | ||
|
38bbeceab4 | ||
|
42cec427a8 |
9 changed files with 87 additions and 55 deletions
10
Gemfile
10
Gemfile
|
@ -28,8 +28,7 @@ gem 'bootsnap', '>= 1.4.4', require: false
|
|||
gem 'ssh_data'
|
||||
|
||||
group :development, :test do
|
||||
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
|
||||
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
|
||||
gem 'pry'
|
||||
end
|
||||
|
||||
group :development do
|
||||
|
@ -46,11 +45,8 @@ group :development do
|
|||
end
|
||||
|
||||
group :test do
|
||||
# Adds support for Capybara system testing and selenium driver
|
||||
gem 'capybara', '>= 3.26'
|
||||
gem 'selenium-webdriver'
|
||||
# Easy installation and use of web drivers to run system tests with browsers
|
||||
gem 'webdrivers'
|
||||
gem 'database_cleaner'
|
||||
gem 'factory_bot'
|
||||
end
|
||||
|
||||
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
||||
|
|
45
Gemfile.lock
45
Gemfile.lock
|
@ -60,8 +60,6 @@ GEM
|
|||
minitest (>= 5.1)
|
||||
tzinfo (~> 2.0)
|
||||
zeitwerk (~> 2.3)
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
ast (2.4.2)
|
||||
bcrypt (3.1.17-x86_64-linux-musl)
|
||||
bindex (0.8.1-x86_64-linux-musl)
|
||||
|
@ -74,20 +72,16 @@ GEM
|
|||
msgpack (~> 1.2)
|
||||
brakeman (5.2.1)
|
||||
builder (3.2.4)
|
||||
byebug (11.1.3-x86_64-linux-musl)
|
||||
capybara (3.36.0)
|
||||
addressable
|
||||
matrix
|
||||
mini_mime (>= 0.1.3)
|
||||
nokogiri (~> 1.8)
|
||||
rack (>= 1.6.0)
|
||||
rack-test (>= 0.6.3)
|
||||
regexp_parser (>= 1.5, < 3.0)
|
||||
xpath (~> 3.2)
|
||||
chartkick (4.1.3)
|
||||
childprocess (4.1.0)
|
||||
coderay (1.1.3)
|
||||
concurrent-ruby (1.1.9)
|
||||
crass (1.0.6)
|
||||
database_cleaner (2.0.1)
|
||||
database_cleaner-active_record (~> 2.0.0)
|
||||
database_cleaner-active_record (2.0.1)
|
||||
activerecord (>= 5.a)
|
||||
database_cleaner-core (~> 2.0.0)
|
||||
database_cleaner-core (2.0.1)
|
||||
devise (4.8.1)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
|
@ -101,6 +95,8 @@ GEM
|
|||
exception_notification (4.5.0)
|
||||
actionmailer (>= 5.2, < 8)
|
||||
activesupport (>= 5.2, < 8)
|
||||
factory_bot (6.2.1)
|
||||
activesupport (>= 5.0.0)
|
||||
ffi (1.15.5-x86_64-linux-musl)
|
||||
globalid (1.0.0)
|
||||
activesupport (>= 5.0)
|
||||
|
@ -123,7 +119,6 @@ GEM
|
|||
mail (2.7.1)
|
||||
mini_mime (>= 0.1.1)
|
||||
marcel (1.0.2)
|
||||
matrix (0.4.2)
|
||||
method_source (1.0.0)
|
||||
mini_mime (1.1.2)
|
||||
mini_portile2 (2.8.0)
|
||||
|
@ -138,7 +133,9 @@ GEM
|
|||
parser (3.1.1.0)
|
||||
ast (~> 2.4.1)
|
||||
pg (1.3.4-x86_64-linux-musl)
|
||||
public_suffix (4.0.6)
|
||||
pry (0.14.1)
|
||||
coderay (~> 1.1)
|
||||
method_source (~> 1.0)
|
||||
puma (5.6.2-x86_64-linux-musl)
|
||||
nio4r (~> 2.0)
|
||||
racc (1.6.0-x86_64-linux-musl)
|
||||
|
@ -199,7 +196,6 @@ GEM
|
|||
rubocop-ast (1.16.0)
|
||||
parser (>= 3.1.1.0)
|
||||
ruby-progressbar (1.11.0)
|
||||
rubyzip (2.3.2)
|
||||
safely_block (0.3.0)
|
||||
errbase (>= 0.1.1)
|
||||
sass-rails (6.0.0)
|
||||
|
@ -212,10 +208,6 @@ GEM
|
|||
sprockets (> 3.0)
|
||||
sprockets-rails
|
||||
tilt
|
||||
selenium-webdriver (4.1.0)
|
||||
childprocess (>= 0.5, < 5.0)
|
||||
rexml (~> 3.2, >= 3.2.5)
|
||||
rubyzip (>= 1.2.2)
|
||||
semantic_range (3.0.0)
|
||||
spring (4.0.0)
|
||||
sprockets (4.0.3)
|
||||
|
@ -241,10 +233,6 @@ GEM
|
|||
activemodel (>= 6.0.0)
|
||||
bindex (>= 0.4.0)
|
||||
railties (>= 6.0.0)
|
||||
webdrivers (5.0.0)
|
||||
nokogiri (~> 1.6)
|
||||
rubyzip (>= 1.3.0)
|
||||
selenium-webdriver (~> 4.0)
|
||||
webpacker (5.4.3)
|
||||
activesupport (>= 5.2)
|
||||
rack-proxy (>= 0.6.1)
|
||||
|
@ -253,8 +241,6 @@ GEM
|
|||
websocket-driver (0.7.5-x86_64-linux-musl)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.5)
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
zeitwerk (2.5.4)
|
||||
|
||||
PLATFORMS
|
||||
|
@ -265,27 +251,26 @@ DEPENDENCIES
|
|||
blazer
|
||||
bootsnap (>= 1.4.4)
|
||||
brakeman
|
||||
byebug
|
||||
capybara (>= 3.26)
|
||||
database_cleaner
|
||||
devise
|
||||
devise-i18n
|
||||
exception_notification
|
||||
factory_bot
|
||||
jbuilder (~> 2.7)
|
||||
listen (~> 3.3)
|
||||
lograge
|
||||
pg (~> 1.1)
|
||||
pry
|
||||
puma (~> 5.0)
|
||||
rack-mini-profiler (~> 2.0)
|
||||
rails (~> 6.1.4)
|
||||
rubocop
|
||||
sass-rails (>= 6)
|
||||
selenium-webdriver
|
||||
spring
|
||||
ssh_data
|
||||
turbolinks (~> 5)
|
||||
tzinfo-data
|
||||
web-console (>= 4.1.0)
|
||||
webdrivers
|
||||
webpacker (~> 5.0)
|
||||
|
||||
RUBY VERSION
|
||||
|
|
|
@ -15,13 +15,16 @@ class ReadingsController < ActionController::API
|
|||
reading = raspberry.readings.build reading_params
|
||||
reading.id = params[:transaction_uuid]
|
||||
reading.signature = request.headers[:'X-Signature']
|
||||
reading.raw_transaction = request.raw_post
|
||||
reading.verified = reading.verify_ssh_signature
|
||||
reading.raw_transaction = request.raw_post
|
||||
reading.raw_transaction << "\n"
|
||||
reading.verified = reading.verify(public_key)
|
||||
|
||||
params[:arduinos]&.each do |a|
|
||||
params[:arduinos]&.reject do |a|
|
||||
a[:id].blank? || a[:sensores].empty?
|
||||
end&.each do |a|
|
||||
arduino = reading.arduinos.build local_id: a[:id], raspberry: raspberry
|
||||
|
||||
a[:sensores]&.each do |s|
|
||||
a[:sensores].each do |s|
|
||||
arduino.sensors.build(sensor_params s)
|
||||
end
|
||||
end
|
||||
|
@ -55,11 +58,14 @@ class ReadingsController < ActionController::API
|
|||
r.name = params[:controller_id]
|
||||
r.serial_number = params[:serial_number]
|
||||
r.save
|
||||
r.public_keys.find_or_create_by(content: params[:public_key])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def public_key
|
||||
@public_key ||= SSHData::PublicKey.parse_openssh(raspberry.public_keys.find_or_create_by(content: params[:public_key]).content)
|
||||
end
|
||||
|
||||
# Procesa la transacción
|
||||
def reading_params
|
||||
@reading_params ||= params.permit(:timestamp,
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
class Reading < ApplicationRecord
|
||||
belongs_to :raspberry
|
||||
has_many :arduinos
|
||||
has_many :sensors, through: :arduinos
|
||||
|
||||
def verify_ssh_signature
|
||||
ssh_signature.verify raw_transaction
|
||||
# @param :public_key [SSHData::PublicKey]
|
||||
def verify(public_key)
|
||||
public_key == ssh_signature.public_key && ssh_signature.verify(raw_transaction)
|
||||
rescue SSHData::Error
|
||||
false
|
||||
end
|
||||
|
|
42
test/controllers/readings_controller_test.rb
Normal file
42
test/controllers/readings_controller_test.rb
Normal file
|
@ -0,0 +1,42 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'test_helper'
|
||||
|
||||
class ReadingsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
@reading = JSON.parse(File.read(Rails.root.join(*%w[test fixtures files 20220318165621-565ca662-a6dc-11ec-95a5-574e273d29ba])))
|
||||
@signature = File.read(Rails.root.join(*%w[test fixtures files 20220318165621-565ca662-a6dc-11ec-95a5-574e273d29ba.sig])).split("\n").tap do |s|
|
||||
s.pop
|
||||
s.reverse!
|
||||
s.pop
|
||||
s.reverse!
|
||||
end.join('')
|
||||
end
|
||||
|
||||
test 'se puede probar la conexión' do
|
||||
post readings_url, as: :json
|
||||
|
||||
assert_response :ok
|
||||
end
|
||||
|
||||
test 'se pueden enviar lecturas' do
|
||||
post readings_url, as: :json, headers: {
|
||||
'X-Signature': @signature
|
||||
}, params: @reading
|
||||
|
||||
assert_response :ok
|
||||
assert_equal @reading['transaction_uuid'], response.body
|
||||
assert (reading = Reading.find(response.body))
|
||||
|
||||
assert reading.raspberry
|
||||
assert_equal @reading['controller_id'], reading.raspberry.name
|
||||
assert_equal @reading['serial_number'], reading.raspberry.serial_number
|
||||
|
||||
assert_equal 1, reading.arduinos.count
|
||||
assert_equal 2, reading.sensors.count
|
||||
|
||||
# XXX: Este JSON no se puede verificar porque hay espacios en el
|
||||
# original que no llegaron con el envío a través de params
|
||||
assert_not reading.verified
|
||||
end
|
||||
end
|
1
test/fixtures/files/20220318165621-565ca662-a6dc-11ec-95a5-574e273d29ba
vendored
Normal file
1
test/fixtures/files/20220318165621-565ca662-a6dc-11ec-95a5-574e273d29ba
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{"transaction_uuid":"565ca662-a6dc-11ec-95a5-574e273d29ba","serial_number":"0000000083a999fd","public_key":"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBC30/zzdbYNJGOaIhnXllJ15OjXmBh/hVhQFJ1DKHMGuDqFJ1iW+QJhwJFWdYLvN64FNplM0wOP7Ibg+T/0sUcQ= Taller_RND 0000000083a999fd","controller_id":"Taller_RND","timestamp":"1647622581","error_code":"10","coordinates":{"lat":1,"lng":1},"battery_status":"98","sample":"0","storage":"uso del almacenamiento","arduinos":[ { "id":"0x01", "sensores": [ { "type": "hum", "value": 78, "unit": "P", "error": 99 }, { "type": "pre", "value": 100, "unit": "Hpa", "error": 98 }]}, { "id":"", "sensores": []}]}
|
7
test/fixtures/files/20220318165621-565ca662-a6dc-11ec-95a5-574e273d29ba.sig
vendored
Normal file
7
test/fixtures/files/20220318165621-565ca662-a6dc-11ec-95a5-574e273d29ba.sig
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
-----BEGIN SSH SIGNATURE-----
|
||||
U1NIU0lHAAAAAQAAAGgAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAAhuaXN0cDI1NgAAAE
|
||||
EELfT/PN1tg0kY5oiGdeWUnXk6NeYGH+FWFAUnUMocwa4OoUnWJb5AmHAkVZ1gu83rgU2m
|
||||
UzTA4/shuD5P/SxRxAAAAARmaWxlAAAAAAAAAAZzaGE1MTIAAABkAAAAE2VjZHNhLXNoYT
|
||||
ItbmlzdHAyNTYAAABJAAAAIASFthCP5MwCvt6lPLtv14U0IPPoTIsdceySf1SUfE8WAAAA
|
||||
IQDN2bI/hkbvS2W+5Qta+gwFMKtB6ZPMaXSF4o/XWf5sCA==
|
||||
-----END SSH SIGNATURE-----
|
11
test/fixtures/users.yml
vendored
11
test/fixtures/users.yml
vendored
|
@ -1,11 +0,0 @@
|
|||
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
# This model initially had no columns defined. If you add columns to the
|
||||
# model remove the '{}' from the fixture names and add the columns immediately
|
||||
# below each fixture, per the syntax in the comments below
|
||||
#
|
||||
one: {}
|
||||
# column: value
|
||||
#
|
||||
two: {}
|
||||
# column: value
|
|
@ -10,4 +10,8 @@ class ActiveSupport::TestCase
|
|||
fixtures :all
|
||||
|
||||
# Add more helper methods to be used by all tests here...
|
||||
DatabaseCleaner.strategy = :transaction
|
||||
|
||||
setup { DatabaseCleaner.start }
|
||||
teardown { DatabaseCleaner.clean }
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue