Compare commits
No commits in common. "212524429f82c53a8900247fcb096f3bdc1c709e" and "b79c954d3bffc456c039333aef62e3534ab6156c" have entirely different histories.
212524429f
...
b79c954d3b
9 changed files with 55 additions and 87 deletions
10
Gemfile
10
Gemfile
|
@ -28,7 +28,8 @@ gem 'bootsnap', '>= 1.4.4', require: false
|
||||||
gem 'ssh_data'
|
gem 'ssh_data'
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
gem 'pry'
|
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
|
||||||
|
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
|
@ -45,8 +46,11 @@ group :development do
|
||||||
end
|
end
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem 'database_cleaner'
|
# Adds support for Capybara system testing and selenium driver
|
||||||
gem 'factory_bot'
|
gem 'capybara', '>= 3.26'
|
||||||
|
gem 'selenium-webdriver'
|
||||||
|
# Easy installation and use of web drivers to run system tests with browsers
|
||||||
|
gem 'webdrivers'
|
||||||
end
|
end
|
||||||
|
|
||||||
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
||||||
|
|
45
Gemfile.lock
45
Gemfile.lock
|
@ -60,6 +60,8 @@ GEM
|
||||||
minitest (>= 5.1)
|
minitest (>= 5.1)
|
||||||
tzinfo (~> 2.0)
|
tzinfo (~> 2.0)
|
||||||
zeitwerk (~> 2.3)
|
zeitwerk (~> 2.3)
|
||||||
|
addressable (2.8.0)
|
||||||
|
public_suffix (>= 2.0.2, < 5.0)
|
||||||
ast (2.4.2)
|
ast (2.4.2)
|
||||||
bcrypt (3.1.17-x86_64-linux-musl)
|
bcrypt (3.1.17-x86_64-linux-musl)
|
||||||
bindex (0.8.1-x86_64-linux-musl)
|
bindex (0.8.1-x86_64-linux-musl)
|
||||||
|
@ -72,16 +74,20 @@ GEM
|
||||||
msgpack (~> 1.2)
|
msgpack (~> 1.2)
|
||||||
brakeman (5.2.1)
|
brakeman (5.2.1)
|
||||||
builder (3.2.4)
|
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)
|
chartkick (4.1.3)
|
||||||
coderay (1.1.3)
|
childprocess (4.1.0)
|
||||||
concurrent-ruby (1.1.9)
|
concurrent-ruby (1.1.9)
|
||||||
crass (1.0.6)
|
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)
|
devise (4.8.1)
|
||||||
bcrypt (~> 3.0)
|
bcrypt (~> 3.0)
|
||||||
orm_adapter (~> 0.1)
|
orm_adapter (~> 0.1)
|
||||||
|
@ -95,8 +101,6 @@ GEM
|
||||||
exception_notification (4.5.0)
|
exception_notification (4.5.0)
|
||||||
actionmailer (>= 5.2, < 8)
|
actionmailer (>= 5.2, < 8)
|
||||||
activesupport (>= 5.2, < 8)
|
activesupport (>= 5.2, < 8)
|
||||||
factory_bot (6.2.1)
|
|
||||||
activesupport (>= 5.0.0)
|
|
||||||
ffi (1.15.5-x86_64-linux-musl)
|
ffi (1.15.5-x86_64-linux-musl)
|
||||||
globalid (1.0.0)
|
globalid (1.0.0)
|
||||||
activesupport (>= 5.0)
|
activesupport (>= 5.0)
|
||||||
|
@ -119,6 +123,7 @@ GEM
|
||||||
mail (2.7.1)
|
mail (2.7.1)
|
||||||
mini_mime (>= 0.1.1)
|
mini_mime (>= 0.1.1)
|
||||||
marcel (1.0.2)
|
marcel (1.0.2)
|
||||||
|
matrix (0.4.2)
|
||||||
method_source (1.0.0)
|
method_source (1.0.0)
|
||||||
mini_mime (1.1.2)
|
mini_mime (1.1.2)
|
||||||
mini_portile2 (2.8.0)
|
mini_portile2 (2.8.0)
|
||||||
|
@ -133,9 +138,7 @@ GEM
|
||||||
parser (3.1.1.0)
|
parser (3.1.1.0)
|
||||||
ast (~> 2.4.1)
|
ast (~> 2.4.1)
|
||||||
pg (1.3.4-x86_64-linux-musl)
|
pg (1.3.4-x86_64-linux-musl)
|
||||||
pry (0.14.1)
|
public_suffix (4.0.6)
|
||||||
coderay (~> 1.1)
|
|
||||||
method_source (~> 1.0)
|
|
||||||
puma (5.6.2-x86_64-linux-musl)
|
puma (5.6.2-x86_64-linux-musl)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
racc (1.6.0-x86_64-linux-musl)
|
racc (1.6.0-x86_64-linux-musl)
|
||||||
|
@ -196,6 +199,7 @@ GEM
|
||||||
rubocop-ast (1.16.0)
|
rubocop-ast (1.16.0)
|
||||||
parser (>= 3.1.1.0)
|
parser (>= 3.1.1.0)
|
||||||
ruby-progressbar (1.11.0)
|
ruby-progressbar (1.11.0)
|
||||||
|
rubyzip (2.3.2)
|
||||||
safely_block (0.3.0)
|
safely_block (0.3.0)
|
||||||
errbase (>= 0.1.1)
|
errbase (>= 0.1.1)
|
||||||
sass-rails (6.0.0)
|
sass-rails (6.0.0)
|
||||||
|
@ -208,6 +212,10 @@ GEM
|
||||||
sprockets (> 3.0)
|
sprockets (> 3.0)
|
||||||
sprockets-rails
|
sprockets-rails
|
||||||
tilt
|
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)
|
semantic_range (3.0.0)
|
||||||
spring (4.0.0)
|
spring (4.0.0)
|
||||||
sprockets (4.0.3)
|
sprockets (4.0.3)
|
||||||
|
@ -233,6 +241,10 @@ GEM
|
||||||
activemodel (>= 6.0.0)
|
activemodel (>= 6.0.0)
|
||||||
bindex (>= 0.4.0)
|
bindex (>= 0.4.0)
|
||||||
railties (>= 6.0.0)
|
railties (>= 6.0.0)
|
||||||
|
webdrivers (5.0.0)
|
||||||
|
nokogiri (~> 1.6)
|
||||||
|
rubyzip (>= 1.3.0)
|
||||||
|
selenium-webdriver (~> 4.0)
|
||||||
webpacker (5.4.3)
|
webpacker (5.4.3)
|
||||||
activesupport (>= 5.2)
|
activesupport (>= 5.2)
|
||||||
rack-proxy (>= 0.6.1)
|
rack-proxy (>= 0.6.1)
|
||||||
|
@ -241,6 +253,8 @@ GEM
|
||||||
websocket-driver (0.7.5-x86_64-linux-musl)
|
websocket-driver (0.7.5-x86_64-linux-musl)
|
||||||
websocket-extensions (>= 0.1.0)
|
websocket-extensions (>= 0.1.0)
|
||||||
websocket-extensions (0.1.5)
|
websocket-extensions (0.1.5)
|
||||||
|
xpath (3.2.0)
|
||||||
|
nokogiri (~> 1.8)
|
||||||
zeitwerk (2.5.4)
|
zeitwerk (2.5.4)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
|
@ -251,26 +265,27 @@ DEPENDENCIES
|
||||||
blazer
|
blazer
|
||||||
bootsnap (>= 1.4.4)
|
bootsnap (>= 1.4.4)
|
||||||
brakeman
|
brakeman
|
||||||
database_cleaner
|
byebug
|
||||||
|
capybara (>= 3.26)
|
||||||
devise
|
devise
|
||||||
devise-i18n
|
devise-i18n
|
||||||
exception_notification
|
exception_notification
|
||||||
factory_bot
|
|
||||||
jbuilder (~> 2.7)
|
jbuilder (~> 2.7)
|
||||||
listen (~> 3.3)
|
listen (~> 3.3)
|
||||||
lograge
|
lograge
|
||||||
pg (~> 1.1)
|
pg (~> 1.1)
|
||||||
pry
|
|
||||||
puma (~> 5.0)
|
puma (~> 5.0)
|
||||||
rack-mini-profiler (~> 2.0)
|
rack-mini-profiler (~> 2.0)
|
||||||
rails (~> 6.1.4)
|
rails (~> 6.1.4)
|
||||||
rubocop
|
rubocop
|
||||||
sass-rails (>= 6)
|
sass-rails (>= 6)
|
||||||
|
selenium-webdriver
|
||||||
spring
|
spring
|
||||||
ssh_data
|
ssh_data
|
||||||
turbolinks (~> 5)
|
turbolinks (~> 5)
|
||||||
tzinfo-data
|
tzinfo-data
|
||||||
web-console (>= 4.1.0)
|
web-console (>= 4.1.0)
|
||||||
|
webdrivers
|
||||||
webpacker (~> 5.0)
|
webpacker (~> 5.0)
|
||||||
|
|
||||||
RUBY VERSION
|
RUBY VERSION
|
||||||
|
|
|
@ -15,16 +15,13 @@ class ReadingsController < ActionController::API
|
||||||
reading = raspberry.readings.build reading_params
|
reading = raspberry.readings.build reading_params
|
||||||
reading.id = params[:transaction_uuid]
|
reading.id = params[:transaction_uuid]
|
||||||
reading.signature = request.headers[:'X-Signature']
|
reading.signature = request.headers[:'X-Signature']
|
||||||
reading.raw_transaction = request.raw_post
|
reading.raw_transaction = request.raw_post
|
||||||
reading.raw_transaction << "\n"
|
reading.verified = reading.verify_ssh_signature
|
||||||
reading.verified = reading.verify(public_key)
|
|
||||||
|
|
||||||
params[:arduinos]&.reject do |a|
|
params[:arduinos]&.each do |a|
|
||||||
a[:id].blank? || a[:sensores].empty?
|
|
||||||
end&.each do |a|
|
|
||||||
arduino = reading.arduinos.build local_id: a[:id], raspberry: raspberry
|
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)
|
arduino.sensors.build(sensor_params s)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -58,14 +55,11 @@ class ReadingsController < ActionController::API
|
||||||
r.name = params[:controller_id]
|
r.name = params[:controller_id]
|
||||||
r.serial_number = params[:serial_number]
|
r.serial_number = params[:serial_number]
|
||||||
r.save
|
r.save
|
||||||
|
r.public_keys.find_or_create_by(content: params[:public_key])
|
||||||
end
|
end
|
||||||
end
|
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
|
# Procesa la transacción
|
||||||
def reading_params
|
def reading_params
|
||||||
@reading_params ||= params.permit(:timestamp,
|
@reading_params ||= params.permit(:timestamp,
|
||||||
|
|
|
@ -3,11 +3,9 @@
|
||||||
class Reading < ApplicationRecord
|
class Reading < ApplicationRecord
|
||||||
belongs_to :raspberry
|
belongs_to :raspberry
|
||||||
has_many :arduinos
|
has_many :arduinos
|
||||||
has_many :sensors, through: :arduinos
|
|
||||||
|
|
||||||
# @param :public_key [SSHData::PublicKey]
|
def verify_ssh_signature
|
||||||
def verify(public_key)
|
ssh_signature.verify raw_transaction
|
||||||
public_key == ssh_signature.public_key && ssh_signature.verify(raw_transaction)
|
|
||||||
rescue SSHData::Error
|
rescue SSHData::Error
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
# 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 +0,0 @@
|
||||||
{"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": []}]}
|
|
|
@ -1,7 +0,0 @@
|
||||||
-----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
Normal file
11
test/fixtures/users.yml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# 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,8 +10,4 @@ class ActiveSupport::TestCase
|
||||||
fixtures :all
|
fixtures :all
|
||||||
|
|
||||||
# Add more helper methods to be used by all tests here...
|
# Add more helper methods to be used by all tests here...
|
||||||
DatabaseCleaner.strategy = :transaction
|
|
||||||
|
|
||||||
setup { DatabaseCleaner.start }
|
|
||||||
teardown { DatabaseCleaner.clean }
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue