Compare commits

..

No commits in common. "212524429f82c53a8900247fcb096f3bdc1c709e" and "b79c954d3bffc456c039333aef62e3534ab6156c" have entirely different histories.

9 changed files with 55 additions and 87 deletions

10
Gemfile
View file

@ -28,7 +28,8 @@ gem 'bootsnap', '>= 1.4.4', require: false
gem 'ssh_data'
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
group :development do
@ -45,8 +46,11 @@ group :development do
end
group :test do
gem 'database_cleaner'
gem 'factory_bot'
# 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'
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem

View file

@ -60,6 +60,8 @@ 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)
@ -72,16 +74,20 @@ 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)
coderay (1.1.3)
childprocess (4.1.0)
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)
@ -95,8 +101,6 @@ 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)
@ -119,6 +123,7 @@ 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)
@ -133,9 +138,7 @@ GEM
parser (3.1.1.0)
ast (~> 2.4.1)
pg (1.3.4-x86_64-linux-musl)
pry (0.14.1)
coderay (~> 1.1)
method_source (~> 1.0)
public_suffix (4.0.6)
puma (5.6.2-x86_64-linux-musl)
nio4r (~> 2.0)
racc (1.6.0-x86_64-linux-musl)
@ -196,6 +199,7 @@ 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)
@ -208,6 +212,10 @@ 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)
@ -233,6 +241,10 @@ 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)
@ -241,6 +253,8 @@ 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
@ -251,26 +265,27 @@ DEPENDENCIES
blazer
bootsnap (>= 1.4.4)
brakeman
database_cleaner
byebug
capybara (>= 3.26)
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

View file

@ -16,15 +16,12 @@ class ReadingsController < ActionController::API
reading.id = params[:transaction_uuid]
reading.signature = request.headers[:'X-Signature']
reading.raw_transaction = request.raw_post
reading.raw_transaction << "\n"
reading.verified = reading.verify(public_key)
reading.verified = reading.verify_ssh_signature
params[:arduinos]&.reject do |a|
a[:id].blank? || a[:sensores].empty?
end&.each do |a|
params[:arduinos]&.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
@ -58,14 +55,11 @@ 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,

View file

@ -3,11 +3,9 @@
class Reading < ApplicationRecord
belongs_to :raspberry
has_many :arduinos
has_many :sensors, through: :arduinos
# @param :public_key [SSHData::PublicKey]
def verify(public_key)
public_key == ssh_signature.public_key && ssh_signature.verify(raw_transaction)
def verify_ssh_signature
ssh_signature.verify raw_transaction
rescue SSHData::Error
false
end

View file

@ -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

View file

@ -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": []}]}

View file

@ -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
View 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

View file

@ -10,8 +10,4 @@ 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