[UNSTABLE] Add `permissions` table.
parent
3aa6772187
commit
f3f1782c2e
|
@ -1,6 +1,8 @@
|
|||
module Api
|
||||
class SequencesController < Api::AbstractController
|
||||
PUBLIC_SEQUENCES = Sequence.with_usage_reports.where public: true
|
||||
PUBLIC_SEQUENCES = Sequence
|
||||
.with_usage_reports
|
||||
.where(is_public: true)
|
||||
SERIALIZED_PUBLIC_SEQUENCES = PUBLIC_SEQUENCES.to_a.map do |s|
|
||||
CeleryScript::FetchCelery.run!(sequence: s)
|
||||
end
|
||||
|
|
|
@ -93,7 +93,7 @@ module CeleryScript
|
|||
args: Sequence::DEFAULT_ARGS,
|
||||
color: sequence.color,
|
||||
name: sequence.name,
|
||||
public: (sequence.public || false),
|
||||
public: (sequence.is_public || false),
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -10,15 +10,16 @@ module CeleryScriptSettingsBag
|
|||
PLANT_STAGES = %w(planned planted harvested)
|
||||
ALLOWED_PIN_MODES = [DIGITAL = 0, ANALOG = 1]
|
||||
ALLOWED_PIN_TYPES = [Peripheral, Sensor].map(&:name)
|
||||
ALLOWED_RPC_NODES = %w(home emergency_lock emergency_unlock read_status
|
||||
sync check_updates power_off reboot toggle_pin
|
||||
config_update calibrate execute move_absolute
|
||||
move_relative write_pin read_pin send_message
|
||||
factory_reset execute_script set_user_env wait
|
||||
install_farmware update_farmware take_photo zero
|
||||
install_first_party_farmware remove_farmware
|
||||
find_home register_gpio unregister_gpio
|
||||
set_servo_angle change_ownership dump_info)
|
||||
RPCS = %w(_if calibrate change_ownership check_updates
|
||||
config_update dump_info emergency_lock
|
||||
emergency_unlock execute execute_script
|
||||
factory_reset find_home home install_farmware
|
||||
install_first_party_farmware move_absolute
|
||||
move_relative power_off read_pin read_status
|
||||
reboot register_gpio remove_farmware send_message
|
||||
set_servo_angle set_user_env sync take_photo
|
||||
toggle_pin unregister_gpio update_farmware wait
|
||||
write_pin zero)
|
||||
ALLOWED_PACKAGES = %w(farmbot_os arduino_firmware)
|
||||
ALLOWED_CHAGES = %w(add remove update)
|
||||
RESOURCE_NAME = %w(images plants regimens peripherals
|
||||
|
@ -32,9 +33,6 @@ module CeleryScriptSettingsBag
|
|||
ALLOWED_AXIS = %w(x y z all)
|
||||
ALLOWED_LHS_TYPES = [String, :named_pin]
|
||||
ALLOWED_LHS_STRINGS = [*(0..69)].map{|x| "pin#{x}"}.concat(%w(x y z))
|
||||
STEPS = %w(_if execute execute_script find_home move_absolute
|
||||
move_relative read_pin send_message take_photo wait
|
||||
write_pin )
|
||||
BAD_ALLOWED_PIN_MODES = '"%s" is not a valid pin_mode. Allowed values: %s'
|
||||
BAD_LHS = 'Can not put "%s" into a left hand side (LHS) '\
|
||||
'argument. Allowed values: %s'
|
||||
|
@ -192,7 +190,7 @@ module CeleryScriptSettingsBag
|
|||
.node(:send_message, [:message, :message_type], [:channel])
|
||||
.node(:execute, [:sequence_id])
|
||||
.node(:_if, [:lhs, :op, :rhs, :_then, :_else], [:pair])
|
||||
.node(:sequence, [:version, :locals], STEPS)
|
||||
.node(:sequence, [:version, :locals], RPCS)
|
||||
.node(:home, [:speed, :axis], [])
|
||||
.node(:find_home, [:speed, :axis], [])
|
||||
.node(:zero, [:axis], [])
|
||||
|
@ -205,7 +203,7 @@ module CeleryScriptSettingsBag
|
|||
.node(:reboot, [], [])
|
||||
.node(:toggle_pin, [:pin_number], [])
|
||||
.node(:explanation, [:message], [])
|
||||
.node(:rpc_request, [:label], ALLOWED_RPC_NODES)
|
||||
.node(:rpc_request, [:label], RPCS)
|
||||
.node(:rpc_ok, [:label], [])
|
||||
.node(:rpc_error, [:label], [:explanation])
|
||||
.node(:calibrate, [:axis], [])
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
class Permission < ApplicationRecord
|
||||
end
|
|
@ -55,7 +55,7 @@ class Sequence < ApplicationRecord
|
|||
end
|
||||
|
||||
def manually_sync!
|
||||
device.auto_sync_transaction { broadcast! } if device
|
||||
device.auto_sync_transaction { broadcast! } if device # && !self.is_public
|
||||
end
|
||||
|
||||
# THIS IS AN OVERRIDE - See Sequence#body_as_json
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
# expiration date).
|
||||
class TokenIssuance < ApplicationRecord
|
||||
belongs_to :device
|
||||
after_destroy :maybe_evict_clients
|
||||
puts "Fix client eviction logic."
|
||||
# after_destroy :maybe_evict_clients
|
||||
|
||||
def broadcast?
|
||||
false
|
||||
|
@ -20,10 +21,11 @@ class TokenIssuance < ApplicationRecord
|
|||
# Kick _everyone_ off the broker. The clients with the revoked token will
|
||||
# not be able to reconnect.
|
||||
def maybe_evict_clients
|
||||
Timeout::timeout(2.5) do
|
||||
id = "device_#{device_id}"
|
||||
Transport::Mgmt.try(:close_connections_for_username, id)
|
||||
end
|
||||
puts "TODO: Fix this (slow) method."
|
||||
# Timeout::timeout(Rails.env.test? ? 0.1 : 2.5) do
|
||||
# id = "device_#{device_id}"
|
||||
# Transport::Mgmt.try(:close_connections_for_username, id)
|
||||
# end
|
||||
rescue Faraday::ConnectionFailed
|
||||
rescue Timeout::Error
|
||||
Rollbar.error("Failed to evict clients on token revocation")
|
||||
|
|
|
@ -31,6 +31,8 @@ module Sequences
|
|||
seq.manually_sync! # We must manually sync this resource.
|
||||
result
|
||||
end
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
binding.pry
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
module Sequences
|
||||
class MaybeBootstrap
|
||||
PATH = File.join File.dirname(__FILE__), "public_sequences.json"
|
||||
PUBLIC_SEQUENCES = JSON.parse(File.read(PATH))
|
||||
|
||||
def self.run!
|
||||
Sequence.transaction do
|
||||
public_device.save!
|
||||
PUBLIC_SEQUENCES
|
||||
.reject { |p| Sequence.where(is_public: true, name: p["name"]).any? }
|
||||
.map { |p| p[:device] = public_device; p }
|
||||
.map { |p| Sequences::Create.run!(p) }
|
||||
.pluck(:id)
|
||||
.map { |id| Sequence.find(id).update_attributes!(is_public: true) }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.public_device
|
||||
@public_device ||= Device.find_or_create_by!(name: "Public FarmBot")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,38 @@
|
|||
[
|
||||
{
|
||||
"name": "Sync",
|
||||
"body": [
|
||||
{
|
||||
"kind": "sync",
|
||||
"args": {}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "E-stop",
|
||||
"body": [
|
||||
{
|
||||
"kind": "emergency_lock",
|
||||
"args": {}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Shutdown",
|
||||
"body": [
|
||||
{
|
||||
"kind": "power_off",
|
||||
"args": {}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Reboot",
|
||||
"body": [
|
||||
{
|
||||
"kind": "reboot",
|
||||
"args": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -0,0 +1 @@
|
|||
# Sequences::MaybeBootstrap.run!
|
|
@ -1,5 +1,5 @@
|
|||
class AddPublicToSequences < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :sequences, :public, :boolean, default: false
|
||||
add_column :sequences, :is_public, :boolean, default: false
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
class CreatePermissions < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :permissions do |t|
|
||||
t.timestamps
|
||||
t.string :name, limit: 16
|
||||
end
|
||||
create_join_table :devices, :permissions do |t|
|
||||
t.index [:device_id, :permission_id]
|
||||
t.index [:permission_id, :device_id]
|
||||
end
|
||||
end
|
||||
end
|
17
db/schema.rb
17
db/schema.rb
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2018_07_10_184108) do
|
||||
ActiveRecord::Schema.define(version: 2018_07_11_143520) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "hstore"
|
||||
|
@ -53,6 +53,13 @@ ActiveRecord::Schema.define(version: 2018_07_10_184108) do
|
|||
t.index ["timezone"], name: "index_devices_on_timezone"
|
||||
end
|
||||
|
||||
create_table "devices_permissions", id: false, force: :cascade do |t|
|
||||
t.bigint "device_id", null: false
|
||||
t.bigint "permission_id", null: false
|
||||
t.index ["device_id", "permission_id"], name: "index_devices_permissions_on_device_id_and_permission_id"
|
||||
t.index ["permission_id", "device_id"], name: "index_devices_permissions_on_permission_id_and_device_id"
|
||||
end
|
||||
|
||||
create_table "diagnostic_dumps", force: :cascade do |t|
|
||||
t.bigint "device_id", null: false
|
||||
t.string "ticket_identifier", null: false
|
||||
|
@ -273,6 +280,12 @@ ActiveRecord::Schema.define(version: 2018_07_10_184108) do
|
|||
t.index ["mode"], name: "index_peripherals_on_mode"
|
||||
end
|
||||
|
||||
create_table "permissions", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "name", limit: 16
|
||||
end
|
||||
|
||||
create_table "pin_bindings", force: :cascade do |t|
|
||||
t.bigint "device_id"
|
||||
t.integer "pin_num"
|
||||
|
@ -393,7 +406,7 @@ ActiveRecord::Schema.define(version: 2018_07_10_184108) do
|
|||
t.datetime "updated_at"
|
||||
t.datetime "created_at"
|
||||
t.boolean "migrated_nodes", default: false
|
||||
t.boolean "public", default: false
|
||||
t.boolean "is_public", default: false
|
||||
t.index ["created_at"], name: "index_sequences_on_created_at"
|
||||
t.index ["device_id"], name: "index_sequences_on_device_id"
|
||||
end
|
||||
|
|
|
@ -127,7 +127,7 @@ class CorpusEmitter
|
|||
result.push(enum_type :Color, Sequence::COLORS)
|
||||
result.push(enum_type :LegalArgString, HASH[:args].map{ |x| x[:name] }.sort.uniq)
|
||||
result.push(enum_type :LegalKindString, HASH[:nodes].map{ |x| x[:name] }.sort.uniq)
|
||||
result.push(enum_type :LegalSequenceKind, CeleryScriptSettingsBag::STEPS.sort)
|
||||
result.push(enum_type :LegalSequenceKind, CeleryScriptSettingsBag::RPCS.sort)
|
||||
result.push(enum_type :DataChangeType, CeleryScriptSettingsBag::ALLOWED_CHAGES)
|
||||
result.push(enum_type :PointType, CeleryScriptSettingsBag::ALLOWED_POINTER_TYPE)
|
||||
result.push(enum_type :AllowedPinTypes, CeleryScriptSettingsBag::ALLOWED_PIN_TYPES)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
FactoryBot.define do
|
||||
factory :permission do
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Permission, type: :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
|
@ -9,8 +9,8 @@ describe TokenIssuance do
|
|||
end
|
||||
|
||||
it "clears out old stuff via #clean_old_tokens" do
|
||||
TokenIssuance.delete_all
|
||||
TokenIssuance.create(device_id: 8,
|
||||
TokenIssuance.destroy_all
|
||||
TokenIssuance.create(device_id: FactoryBot.create(:device).id,
|
||||
exp: 1.year.ago.to_i,
|
||||
jti: "WOW")
|
||||
expect(TokenIssuance.count).to eq(1)
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
require "spec_helper"
|
||||
|
||||
describe Sequences::MaybeBootstrap do
|
||||
it "bootstraps a list of public sequences (only once)" do
|
||||
Point.destroy_all
|
||||
TokenIssuance.destroy_all
|
||||
Device.destroy_all
|
||||
Sequence.destroy_all
|
||||
ps = Sequences::MaybeBootstrap::PUBLIC_SEQUENCES
|
||||
|
||||
Sequences::MaybeBootstrap.run!
|
||||
expect(Device.count).to eq(1)
|
||||
expect(Sequence.count).to eq(ps.count)
|
||||
|
||||
Sequences::MaybeBootstrap.run!
|
||||
expect(Device.count).to eq(1)
|
||||
expect(Sequence.count).to eq(ps.count)
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue