apiotics 0.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +260 -0
- data/Rakefile +33 -0
- data/lib/apiotics.rb +57 -0
- data/lib/apiotics/client.rb +20 -0
- data/lib/apiotics/configuration.rb +22 -0
- data/lib/apiotics/extract.rb +87 -0
- data/lib/apiotics/insert.rb +105 -0
- data/lib/apiotics/parse.rb +20 -0
- data/lib/apiotics/portal.rb +156 -0
- data/lib/apiotics/railtie.rb +14 -0
- data/lib/apiotics/server.rb +236 -0
- data/lib/apiotics/version.rb +3 -0
- data/lib/generators/apiotics/channel/USAGE +10 -0
- data/lib/generators/apiotics/channel/channel_generator.rb +35 -0
- data/lib/generators/apiotics/channel/templates/apiotics_channel.rb.erb +9 -0
- data/lib/generators/apiotics/channel/templates/apiotics_channel_client.coffee.erb +16 -0
- data/lib/generators/apiotics/channel/templates/apiotics_channel_initializer.rb.erb +3 -0
- data/lib/generators/apiotics/controller/USAGE +8 -0
- data/lib/generators/apiotics/controller/controller_generator.rb +24 -0
- data/lib/generators/apiotics/controller/templates/apiotics_scaffold.rb.erb +60 -0
- data/lib/generators/apiotics/create_model/USAGE +10 -0
- data/lib/generators/apiotics/create_model/create_model_generator.rb +76 -0
- data/lib/generators/apiotics/create_model/templates/apiotics_logs_model.rb.erb +7 -0
- data/lib/generators/apiotics/create_model/templates/apiotics_model.rb.erb +49 -0
- data/lib/generators/apiotics/create_model/templates/apiotics_module.rb.erb +10 -0
- data/lib/generators/apiotics/create_model/templates/apiotics_module_model.rb.erb +8 -0
- data/lib/generators/apiotics/create_model/templates/create_module_model_table.rb.erb +8 -0
- data/lib/generators/apiotics/create_table/USAGE +9 -0
- data/lib/generators/apiotics/create_table/create_table_generator.rb +52 -0
- data/lib/generators/apiotics/create_table/templates/create_logs_table.rb.erb +14 -0
- data/lib/generators/apiotics/create_table/templates/create_table.rb.erb +16 -0
- data/lib/generators/apiotics/initializer/USAGE +8 -0
- data/lib/generators/apiotics/initializer/initializer_generator.rb +27 -0
- data/lib/generators/apiotics/initializer/templates/apiotics.rb.erb +10 -0
- data/lib/generators/apiotics/initializer/templates/apiotics_module.rb.erb +6 -0
- data/lib/generators/apiotics/initializer/templates/apiotics_settings.rb.erb +9 -0
- data/lib/generators/apiotics/initializer/templates/apiotics_targets.rb.erb +3 -0
- data/lib/generators/apiotics/initializer/templates/setting.rb.erb +3 -0
- data/lib/generators/apiotics/install/USAGE +11 -0
- data/lib/generators/apiotics/install/install_generator.rb +11 -0
- data/lib/generators/apiotics/migration/USAGE +10 -0
- data/lib/generators/apiotics/migration/migration_generator.rb +54 -0
- data/lib/generators/apiotics/migration/templates/create_logs_table.rb.erb +14 -0
- data/lib/generators/apiotics/migration/templates/migrate_table.rb.erb +12 -0
- data/lib/generators/apiotics/model/USAGE +11 -0
- data/lib/generators/apiotics/model/model_generator.rb +58 -0
- data/lib/generators/apiotics/script/USAGE +8 -0
- data/lib/generators/apiotics/script/script_generator.rb +44 -0
- data/lib/generators/apiotics/script/templates/comm_server.rake +19 -0
- data/lib/generators/apiotics/script/templates/dev_comm_server.rake +19 -0
- data/lib/generators/apiotics/script/templates/dev_server.rb +8 -0
- data/lib/generators/apiotics/script/templates/dev_server_control.rb +7 -0
- data/lib/generators/apiotics/script/templates/publish_script.rake +6 -0
- data/lib/generators/apiotics/script/templates/script.rb.erb +12 -0
- data/lib/generators/apiotics/script/templates/server.rb +8 -0
- data/lib/generators/apiotics/script/templates/server_control.rb +7 -0
- data/lib/generators/apiotics/script/templates/test_comm_server.rake +19 -0
- data/lib/generators/apiotics/script/templates/test_server.rb +8 -0
- data/lib/generators/apiotics/script/templates/test_server_control.rb +7 -0
- data/lib/generators/apiotics/view/USAGE +12 -0
- data/lib/generators/apiotics/view/templates/default.css.erb +18 -0
- data/lib/generators/apiotics/view/templates/edit.html.erb +6 -0
- data/lib/generators/apiotics/view/templates/form.html.erb +36 -0
- data/lib/generators/apiotics/view/templates/index.html.erb +57 -0
- data/lib/generators/apiotics/view/templates/show.html.erb +47 -0
- data/lib/generators/apiotics/view/view_generator.rb +26 -0
- data/lib/tasks/simbiotes_tasks.rake +4 -0
- metadata +237 -0
@@ -0,0 +1,105 @@
|
|
1
|
+
# This class takes ruby hashes and saves them to the appropriate database table.
|
2
|
+
# All model methods that have corresponding IoT interfaces have six database fields associated with them.
|
3
|
+
# The first is a field named the same as the method. The second is name_ack, and third is name_complete, the fourth is name_timestamp, the fifth is name_status, the sixth is name_action.
|
4
|
+
# In the hash, instance is the record id (not necessarily the id column), driver is the model, interface is the method.
|
5
|
+
# Data should be saved both to the model's database table and to the corresponding log table (name_method_logs).
|
6
|
+
|
7
|
+
module Apiotics
|
8
|
+
class Insert
|
9
|
+
def initialize(hash = {"action" => "set-complete", "instance" => 1, "driver" => "test_driver", "interface" => "control", "value" => 72, "timestamp" => "1000000000000", "status" => "ok"})
|
10
|
+
@action = hash["action"]
|
11
|
+
@id = hash["instance"]
|
12
|
+
@class = hash["driver"]
|
13
|
+
@methods = hash["interface"]
|
14
|
+
@value = hash["value"]
|
15
|
+
@timestamp = hash["timestamp"]
|
16
|
+
@status = hash["status"]
|
17
|
+
find_record
|
18
|
+
@methods.each do |k,v|
|
19
|
+
@record.send(("#{k}_action=").to_sym, @action)
|
20
|
+
@type = @record.class.columns_hash[k].type
|
21
|
+
#change_value
|
22
|
+
@record.send("#{k}=".to_sym, v)
|
23
|
+
@record.send("#{k}_timestamp=".to_sym, @timestamp)
|
24
|
+
@record.send("#{k}_status=".to_sym, @status)
|
25
|
+
end
|
26
|
+
if @action == "set-complete"
|
27
|
+
set_complete
|
28
|
+
elsif @action == "set-request-ack"
|
29
|
+
set_ack
|
30
|
+
elsif @action == "get-ack"
|
31
|
+
get_ack
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def find_record
|
36
|
+
begin
|
37
|
+
klass = @class.classify.constantize
|
38
|
+
master_klass = (klass.parent.to_s + "::" + klass.parent.to_s).classify.constantize
|
39
|
+
master_record = master_klass.find_by(apiotics_instance: @id)
|
40
|
+
@record = master_record.send(@class.demodulize.underscore.downcase)
|
41
|
+
#puts e
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def set_ack
|
46
|
+
@methods.each do |k,v|
|
47
|
+
@record.send("#{k}_ack=".to_sym, true)
|
48
|
+
@record.send("#{k}_complete=".to_sym, false)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def set_complete
|
53
|
+
@methods.each do |k,v|
|
54
|
+
@record.send("#{k}_ack=".to_sym, true)
|
55
|
+
@record.send("#{k}_complete=".to_sym, true)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_ack
|
60
|
+
@methods.each do |k,v|
|
61
|
+
@record.send("#{k}_ack=".to_sym, true)
|
62
|
+
@record.send("#{k}_complete=".to_sym, false)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def save
|
67
|
+
@record.skip_extract = true
|
68
|
+
@record.save
|
69
|
+
@record.skip_extract = false
|
70
|
+
end
|
71
|
+
|
72
|
+
def action
|
73
|
+
@action.to_s
|
74
|
+
end
|
75
|
+
|
76
|
+
def save_log
|
77
|
+
@methods.each do |k,v|
|
78
|
+
klass = "#{@class}_#{k}_log".classify.constantize
|
79
|
+
r = klass.new
|
80
|
+
r.send(("#{k}_action=").to_sym, @action)
|
81
|
+
r.send("#{k}=".to_sym, v)
|
82
|
+
r.send("#{k}_timestamp=".to_sym, @timestamp)
|
83
|
+
r.send("#{k}_status=".to_sym, @status)
|
84
|
+
r.send("#{k}_ack=".to_sym, @record.send("#{k}_ack"))
|
85
|
+
r.send("#{k}_complete=".to_sym, @record.send("#{k}_complete"))
|
86
|
+
r.send("#{@class.classify.demodulize.underscore.gsub("/","_")}_id=".to_sym, @record.id)
|
87
|
+
r.save
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def change_value
|
92
|
+
if @type == :boolean
|
93
|
+
if @value == "true"
|
94
|
+
@value = true
|
95
|
+
elsif @value == "false"
|
96
|
+
@value = false
|
97
|
+
end
|
98
|
+
elsif @type == :integer
|
99
|
+
@value = @value.to_i
|
100
|
+
elsif @type == :string
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# This class is responsible for parsing JSON messages and configuration files into ruby hashes.
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Apiotics
|
6
|
+
class Parse
|
7
|
+
|
8
|
+
def self.message(string)
|
9
|
+
JSON.parse(string)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.config(string)
|
13
|
+
JSON.parse(string)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.portal(string)
|
17
|
+
JSON.parse(string)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
|
2
|
+
require 'httparty'
|
3
|
+
require 'rest-client'
|
4
|
+
|
5
|
+
module Apiotics
|
6
|
+
class Portal
|
7
|
+
|
8
|
+
def self.get_attributes(parent_name, model_name)
|
9
|
+
configuration = Portal.retrieve_configuration
|
10
|
+
attributes = Portal.parse_drivers_and_scripts(configuration, parent_name, model_name)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.parse_drivers_and_scripts(hash, parent_name, model_name)
|
14
|
+
attributes_hash = nil
|
15
|
+
hash["workers"][parent_name]["drivers"].each do |k,v|
|
16
|
+
name = v["metadata"]["common name"].classify
|
17
|
+
if name == model_name.classify
|
18
|
+
attributes_hash = Hash.new
|
19
|
+
attributes_hash[:kind] = "driver"
|
20
|
+
attributes_hash[:attributes] = Hash.new
|
21
|
+
v["interfaces"].each do |k,v|
|
22
|
+
attributes_hash[:attributes][k] = {
|
23
|
+
type: v["type"],
|
24
|
+
accessor: v["accessor type"],
|
25
|
+
units: v["units"],
|
26
|
+
noise: v["noise threshold"],
|
27
|
+
values: v["values"],
|
28
|
+
range: v["range"]
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
hash["workers"][parent_name]["scripts"].each do |k,v|
|
34
|
+
name = v["metadata"]["common name"].classify
|
35
|
+
if name == model_name.classify
|
36
|
+
attributes_hash = Hash.new
|
37
|
+
attributes_hash[:kind] = "script"
|
38
|
+
attributes_hash[:attributes] = Hash.new
|
39
|
+
v["interfaces"].each do |key,value|
|
40
|
+
attributes_hash[:attributes][key] = {
|
41
|
+
type: value["type"],
|
42
|
+
accessor: value["accessor type"],
|
43
|
+
units: value["units"],
|
44
|
+
noise: value["noise threshold"],
|
45
|
+
values: value["values"],
|
46
|
+
range: value["range"]
|
47
|
+
}
|
48
|
+
end
|
49
|
+
attributes_hash[:inputs] = Hash.new
|
50
|
+
v["inputs"].each do |key,value|
|
51
|
+
attributes_hash[:inputs][key] = value
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
return attributes_hash
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.retrieve_configuration
|
59
|
+
json = HTTParty.post("#{Apiotics.configuration.portal}api/hive", :query => {:public_key => Apiotics.configuration.public_key, :private_key => Apiotics.configuration.private_key}).body
|
60
|
+
hash = Apiotics::Parse.portal(json)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.parse_all_interfaces
|
64
|
+
configuration = Portal.retrieve_configuration
|
65
|
+
hash = Hash.new
|
66
|
+
configuration["workers"].each do |key, value|
|
67
|
+
hash[key] = Hash.new
|
68
|
+
configuration["workers"][key]["drivers"].each do |k,v|
|
69
|
+
a = Array.new
|
70
|
+
if v["interfaces"] != nil
|
71
|
+
v["interfaces"].each do |key, value|
|
72
|
+
a << key
|
73
|
+
end
|
74
|
+
end
|
75
|
+
hash[key][v["metadata"]["common name"]] = a
|
76
|
+
end
|
77
|
+
configuration["workers"][key]["scripts"].each do |k,v|
|
78
|
+
a = Array.new
|
79
|
+
if v["interfaces"] != nil
|
80
|
+
v["interfaces"].each do |key, value|
|
81
|
+
a << key
|
82
|
+
end
|
83
|
+
end
|
84
|
+
hash[key][v["metadata"]["common name"]] = a
|
85
|
+
end
|
86
|
+
end
|
87
|
+
hash
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.sync_device_instances(worker_name)
|
91
|
+
instance_hash = JSON.parse(HTTParty.post("#{Apiotics.configuration.portal}api/workers", :query => {:public_key => Apiotics.configuration.public_key, :private_key => Apiotics.configuration.private_key}).body)
|
92
|
+
klass = (worker_name.to_s + "::" + worker_name.to_s).constantize rescue nil
|
93
|
+
unless klass == nil
|
94
|
+
instance_ids = Array.new
|
95
|
+
instance_hash[worker_name].each do |instance_id,status|
|
96
|
+
instance_ids << instance_id
|
97
|
+
end
|
98
|
+
stale_instances = klass.where.not(apiotics_instance: instance_ids)
|
99
|
+
stale_instances.destroy_all
|
100
|
+
instance_ids.each do |instance_id|
|
101
|
+
i = klass.find_by(apiotics_instance: instance_id)
|
102
|
+
if i == nil
|
103
|
+
i = klass.new
|
104
|
+
i.apiotics_instance = instance_id
|
105
|
+
i.save(:validate => false)
|
106
|
+
Apiotics.configuration.targets[worker_name].keys.each do |key|
|
107
|
+
subklass = (worker_name + "::" + key).constantize rescue nil
|
108
|
+
unless subklass == nil
|
109
|
+
s = subklass.new
|
110
|
+
k = worker_name.underscore.gsub(" ","_").to_s + "_id="
|
111
|
+
s.send((k).to_sym, i.id)
|
112
|
+
s.skip_extract = true
|
113
|
+
s.save(:validate => false)
|
114
|
+
s.skip_extract = false
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.upload_script(worker, script)
|
123
|
+
payload = {
|
124
|
+
:multipart => true,
|
125
|
+
:script_file => File.open("#{Rails.root}/lib/scripts/apiotics/#{worker.underscore.downcase}/#{script.underscore.downcase}.rb", 'rb'),
|
126
|
+
:public_key => Apiotics.configuration.public_key,
|
127
|
+
:private_key => Apiotics.configuration.private_key,
|
128
|
+
:worker_name => worker,
|
129
|
+
:script_name => script
|
130
|
+
}
|
131
|
+
r = RestClient.post("#{Apiotics.configuration.portal}api/upload_script", payload)
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.generate_certificate(csr)
|
135
|
+
csr_file = Tempfile.new
|
136
|
+
csr_file.write(csr)
|
137
|
+
csr_file.rewind
|
138
|
+
payload = {
|
139
|
+
:multipart => true,
|
140
|
+
:csr => csr_file,
|
141
|
+
:public_key => Apiotics.configuration.public_key,
|
142
|
+
:private_key => Apiotics.configuration.private_key
|
143
|
+
}
|
144
|
+
r = RestClient.post("#{Apiotics.configuration.portal}api/generate_certificate", payload)
|
145
|
+
instance_hash = JSON.parse(r.body)
|
146
|
+
return instance_hash["certificate"]
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.ca_certificate
|
150
|
+
response = HTTParty.post("#{Apiotics.configuration.portal}api/ca_certificate", :query => {:public_key => Apiotics.configuration.public_key, :private_key => Apiotics.configuration.private_key}).body
|
151
|
+
hash = JSON.parse(response)
|
152
|
+
return hash["ca_certificate"]
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'apiotics'
|
2
|
+
require 'rails'
|
3
|
+
|
4
|
+
module Apiotics
|
5
|
+
class Railtie < Rails::Railtie
|
6
|
+
generators do
|
7
|
+
require 'lib/generators/apiotics/model'
|
8
|
+
require 'lib/generators/apiotics/create_table'
|
9
|
+
require 'lib/generators/apiotics/create_model'
|
10
|
+
require 'lib/generators/apiotics/initializer'
|
11
|
+
require 'lib/generators/apiotics/migration'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,236 @@
|
|
1
|
+
|
2
|
+
# This class creates a local server listening on port 8001, and connects to a remote server on port 8000. Messages sent to the local server are transmitted
|
3
|
+
# to the remote server. Messages received from the remote server are forwarded to the appropriate logic.
|
4
|
+
|
5
|
+
require "socket"
|
6
|
+
require 'openssl'
|
7
|
+
require 'json'
|
8
|
+
|
9
|
+
module Apiotics
|
10
|
+
class Server
|
11
|
+
def initialize
|
12
|
+
@error_msg = nil
|
13
|
+
server_details = Server.lookup
|
14
|
+
rgs = ApioticsSetting.find_by(key: "server")
|
15
|
+
rgs_port = ApioticsSetting.find_by(key: "port")
|
16
|
+
if rgs == nil
|
17
|
+
if server_details["status"] == "ok"
|
18
|
+
rgs = server_details["ip"]
|
19
|
+
c = ApioticsSetting.new
|
20
|
+
c.key = "server"
|
21
|
+
c.value = rgs
|
22
|
+
c.save
|
23
|
+
rgs_port = server_details["port"]
|
24
|
+
c = ApioticsSetting.new
|
25
|
+
c.key = "port"
|
26
|
+
c.value = rgs_port
|
27
|
+
c.save
|
28
|
+
else
|
29
|
+
@error_msg = server_details["status_msg"]
|
30
|
+
end
|
31
|
+
else
|
32
|
+
if server_details["status"] == "ok"
|
33
|
+
rgs.value = server_details["ip"]
|
34
|
+
rgs.save
|
35
|
+
rgs = rgs.value
|
36
|
+
rgs_port.value = server_details["port"]
|
37
|
+
rgs_port.save
|
38
|
+
rgs_port = rgs_port.value
|
39
|
+
else
|
40
|
+
@error_msg = server_details["status_msg"]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
if Apiotics.configuration.tls == true
|
44
|
+
socket = TCPSocket.new(rgs, rgs_port)
|
45
|
+
context = OpenSSL::SSL::SSLContext.new
|
46
|
+
context.key = Server.key
|
47
|
+
context.cert = Server.cert
|
48
|
+
if Apiotics.configuration.verify_peer == true
|
49
|
+
ca_tempfile = Tempfile.new
|
50
|
+
ca_tempfile.write Server.ca_cert.to_pem
|
51
|
+
ca_tempfile.rewind
|
52
|
+
context.ca_file = ca_tempfile.path
|
53
|
+
context.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
54
|
+
end
|
55
|
+
server = OpenSSL::SSL::SSLSocket.new socket, context
|
56
|
+
server.sync_close = true
|
57
|
+
server.connect
|
58
|
+
if Apiotics.configuration.verify_peer == true
|
59
|
+
ca_tempfile.close(true)
|
60
|
+
end
|
61
|
+
else
|
62
|
+
server = TCPSocket.open(rgs, rgs_port)
|
63
|
+
end
|
64
|
+
@server = server
|
65
|
+
@localport = Apiotics.configuration.local_port
|
66
|
+
listen_remote
|
67
|
+
listen_local
|
68
|
+
end
|
69
|
+
|
70
|
+
def send(msg)
|
71
|
+
puts "Message sent: #{msg}"
|
72
|
+
@server.puts( msg )
|
73
|
+
end
|
74
|
+
|
75
|
+
def close
|
76
|
+
@server.close
|
77
|
+
end
|
78
|
+
|
79
|
+
def listen_remote
|
80
|
+
begin
|
81
|
+
Thread.new do
|
82
|
+
loop do
|
83
|
+
msg = @server.gets
|
84
|
+
puts msg
|
85
|
+
msg_hash = Apiotics::Parse.message(msg)
|
86
|
+
r = Apiotics::Insert.new(msg_hash)
|
87
|
+
puts "Message received": msg_hash
|
88
|
+
if r.action == "set-request-ack" || r.action == "set-complete" || r.action == "get-ack"
|
89
|
+
r.save
|
90
|
+
unless Apiotics.configuration.local_logging == false
|
91
|
+
r.save_log
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
rescue => e
|
97
|
+
puts e
|
98
|
+
listen_remote
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
def listen_local
|
104
|
+
begin
|
105
|
+
server = TCPServer.open(@localport)
|
106
|
+
if Apiotics.configuration.handshake == true
|
107
|
+
self.send('{"action":"connect"}')
|
108
|
+
end
|
109
|
+
loop do
|
110
|
+
Thread.fork(server.accept) do |client|
|
111
|
+
s = client.gets
|
112
|
+
if @error_msg != nil
|
113
|
+
string = '{"error":"' + error_msg + '"}'
|
114
|
+
client.puts(string)
|
115
|
+
end
|
116
|
+
#puts s
|
117
|
+
self.send(s)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
rescue => e
|
121
|
+
puts e
|
122
|
+
listen_local
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.lookup
|
127
|
+
if Apiotics.configuration.tls == true
|
128
|
+
socket = TCPSocket.new(Apiotics.configuration.server, Apiotics.configuration.server_port)
|
129
|
+
context = OpenSSL::SSL::SSLContext.new
|
130
|
+
context.key = Server.key
|
131
|
+
context.cert = Server.cert
|
132
|
+
if Apiotics.configuration.verify_peer == true
|
133
|
+
ca_tempfile = Tempfile.new
|
134
|
+
ca_tempfile.write Server.ca_cert.to_pem
|
135
|
+
ca_tempfile.rewind
|
136
|
+
context.ca_file = ca_tempfile.path
|
137
|
+
context.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
138
|
+
end
|
139
|
+
server = OpenSSL::SSL::SSLSocket.new socket, context
|
140
|
+
server.sync_close = true
|
141
|
+
server.connect
|
142
|
+
else
|
143
|
+
server = TCPSocket.open(Apiotics.configuration.server, Apiotics.configuration.server_port)
|
144
|
+
end
|
145
|
+
server.puts('{"action":"lookup"}')
|
146
|
+
msg = server.gets
|
147
|
+
hash = JSON.parse(msg)
|
148
|
+
server.close
|
149
|
+
if Apiotics.configuration.verify_peer == true
|
150
|
+
ca_tempfile.close(true)
|
151
|
+
end
|
152
|
+
return hash
|
153
|
+
end
|
154
|
+
|
155
|
+
def self.key
|
156
|
+
key = ApioticsSetting.find_by(key: "key")
|
157
|
+
if key == nil
|
158
|
+
key = Server.generate_key
|
159
|
+
else
|
160
|
+
key = key.value
|
161
|
+
end
|
162
|
+
pass_phrase = ApioticsSetting.find_by(key: "key_pass_phrase").value
|
163
|
+
key = OpenSSL::PKey::RSA.new key, pass_phrase
|
164
|
+
return key
|
165
|
+
end
|
166
|
+
|
167
|
+
def self.cert
|
168
|
+
cert = ApioticsSetting.find_by(key: "cert")
|
169
|
+
if cert == nil
|
170
|
+
key = Server.key
|
171
|
+
public_key = key.public_key
|
172
|
+
cert = Server.generate_cert(key, public_key)
|
173
|
+
c = ApioticsSetting.new
|
174
|
+
c.key = "cert"
|
175
|
+
c.value = cert
|
176
|
+
c.save
|
177
|
+
else
|
178
|
+
cert = cert.value
|
179
|
+
end
|
180
|
+
cert = OpenSSL::X509::Certificate.new cert
|
181
|
+
return cert
|
182
|
+
end
|
183
|
+
|
184
|
+
def self.generate_key
|
185
|
+
key = OpenSSL::PKey::RSA.new 2048
|
186
|
+
pass_phrase = 'simbiotes'
|
187
|
+
cipher = OpenSSL::Cipher.new 'AES-128-CBC'
|
188
|
+
s = ApioticsSetting.new
|
189
|
+
s.key = "key_cipher"
|
190
|
+
s.value = "OpenSSL::Cipher.new 'AES-128-CBC'"
|
191
|
+
s.save
|
192
|
+
s = ApioticsSetting.new
|
193
|
+
s.key = "key_pass_phrase"
|
194
|
+
s.value = 'simbiotes'
|
195
|
+
s.save
|
196
|
+
s = ApioticsSetting.new
|
197
|
+
s.key = "public_key"
|
198
|
+
s.value = key.public_key.to_pem
|
199
|
+
s.save
|
200
|
+
s = ApioticsSetting.new
|
201
|
+
s.key = "key"
|
202
|
+
s.value = key.export(cipher, pass_phrase)
|
203
|
+
s.save
|
204
|
+
return s.value
|
205
|
+
end
|
206
|
+
|
207
|
+
def self.generate_cert(key, public_key)
|
208
|
+
csr = OpenSSL::X509::Request.new
|
209
|
+
csr.version = 0
|
210
|
+
csr.subject = OpenSSL::X509::Name.parse "CN=simbiotes.com/O=#{Apiotics.configuration.public_key}/OU=#{Apiotics.configuration.private_key}"
|
211
|
+
csr.public_key = key.public_key
|
212
|
+
csr.sign key, OpenSSL::Digest::SHA1.new
|
213
|
+
cert = Apiotics::Portal.generate_certificate(csr)
|
214
|
+
return cert
|
215
|
+
end
|
216
|
+
|
217
|
+
def self.ca_cert
|
218
|
+
ca_cert = ApioticsSetting.find_by(key: "ca_cert")
|
219
|
+
if ca_cert == nil
|
220
|
+
ca_cert = Apiotics::Portal.ca_certificate
|
221
|
+
c = ApioticsSetting.new
|
222
|
+
c.key = "ca_cert"
|
223
|
+
c.value = ca_cert
|
224
|
+
c.save
|
225
|
+
else
|
226
|
+
ca_cert = ca_cert.value
|
227
|
+
end
|
228
|
+
ca_cert = OpenSSL::X509::Certificate.new ca_cert
|
229
|
+
return ca_cert
|
230
|
+
end
|
231
|
+
|
232
|
+
def do_at_exit
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
236
|
+
end
|