hyper-operation 1.0.alpha1.8 → 1.0.0.lap28
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 +4 -4
- data/.gitignore +2 -7
- data/.travis.yml +9 -21
- data/CODE_OF_CONDUCT.md +49 -0
- data/DOCS-POLICIES.md +582 -0
- data/DOCS.md +869 -0
- data/Gemfile +1 -5
- data/LICENSE.txt +21 -0
- data/README.md +77 -0
- data/Rakefile +2 -1
- data/dciy.toml +3 -0
- data/hyper-operation.gemspec +15 -19
- data/lib/hyper-operation.rb +6 -10
- data/lib/hyper-operation/api.rb +4 -8
- data/lib/hyper-operation/boot.rb +2 -3
- data/lib/hyper-operation/delay_and_interval.rb +9 -0
- data/lib/hyper-operation/engine.rb +2 -2
- data/lib/hyper-operation/exception.rb +4 -30
- data/lib/hyper-operation/filters/acting_user.rb +1 -1
- data/lib/hyper-operation/http.rb +2 -2
- data/lib/hyper-operation/promise.rb +2 -32
- data/lib/hyper-operation/railway.rb +1 -1
- data/lib/hyper-operation/railway/dispatcher.rb +5 -8
- data/lib/hyper-operation/railway/params_wrapper.rb +2 -2
- data/lib/hyper-operation/railway/run.rb +49 -58
- data/lib/hyper-operation/railway/validations.rb +3 -10
- data/lib/hyper-operation/server_op.rb +20 -46
- data/lib/hyper-operation/transport/action_cable.rb +8 -8
- data/lib/hyper-operation/transport/client_drivers.rb +55 -96
- data/lib/hyper-operation/transport/connection.rb +136 -58
- data/lib/hyper-operation/transport/{hyperstack.rb → hyperloop.rb} +15 -28
- data/lib/hyper-operation/transport/{hyperstack_controller.rb → hyperloop_controller.rb} +53 -59
- data/lib/hyper-operation/transport/policy.rb +49 -50
- data/lib/hyper-operation/version.rb +2 -2
- data/lib/sources/{hyperstack → hyperloop}/pusher.js +0 -0
- metadata +73 -94
- data/lib/hyper-operation/async_sleep.rb +0 -23
- data/lib/hyper-operation/transport/connection_adapter/active_record.rb +0 -113
- data/lib/hyper-operation/transport/connection_adapter/active_record/auto_create.rb +0 -26
- data/lib/hyper-operation/transport/connection_adapter/active_record/connection.rb +0 -47
- data/lib/hyper-operation/transport/connection_adapter/active_record/queued_message.rb +0 -42
- data/lib/hyper-operation/transport/connection_adapter/redis.rb +0 -94
- data/lib/hyper-operation/transport/connection_adapter/redis/connection.rb +0 -85
- data/lib/hyper-operation/transport/connection_adapter/redis/queued_message.rb +0 -34
- data/lib/hyper-operation/transport/connection_adapter/redis/redis_record.rb +0 -158
- data/lib/hyper-operation/transport/policy_diagnostics.rb +0 -106
@@ -1,158 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Hyperstack
|
4
|
-
module ConnectionAdapter
|
5
|
-
module Redis
|
6
|
-
module RedisRecord
|
7
|
-
class Base
|
8
|
-
class << self
|
9
|
-
attr_accessor :table_name, :column_names
|
10
|
-
|
11
|
-
def client
|
12
|
-
@client ||= ::Redis.new(url: Hyperstack.connection[:redis_url])
|
13
|
-
end
|
14
|
-
|
15
|
-
def scope(&block)
|
16
|
-
ids = client.smembers(table_name)
|
17
|
-
|
18
|
-
ids = ids.map(&block) if block
|
19
|
-
|
20
|
-
ids.compact.map { |id| instantiate(id) }
|
21
|
-
end
|
22
|
-
|
23
|
-
def all
|
24
|
-
scope
|
25
|
-
end
|
26
|
-
|
27
|
-
def first
|
28
|
-
id = client.smembers(table_name).first
|
29
|
-
|
30
|
-
instantiate(id)
|
31
|
-
end
|
32
|
-
|
33
|
-
def last
|
34
|
-
id = client.smembers(table_name).last
|
35
|
-
|
36
|
-
instantiate(id)
|
37
|
-
end
|
38
|
-
|
39
|
-
def find(id)
|
40
|
-
return unless client.smembers(table_name).include?(id)
|
41
|
-
|
42
|
-
instantiate(id)
|
43
|
-
end
|
44
|
-
|
45
|
-
def find_by(opts)
|
46
|
-
found = nil
|
47
|
-
|
48
|
-
client.smembers(table_name).each do |id|
|
49
|
-
unless opts.map { |k, v| get_dejsonized_attribute(id, k) == v }.include?(false)
|
50
|
-
found = instantiate(id)
|
51
|
-
break
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
found
|
56
|
-
end
|
57
|
-
|
58
|
-
def find_or_create_by(opts = {})
|
59
|
-
if (existing = find_by(opts))
|
60
|
-
existing
|
61
|
-
else
|
62
|
-
create(opts)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def where(opts = {})
|
67
|
-
scope do |id|
|
68
|
-
unless opts.map { |k, v| get_dejsonized_attribute(id, k) == v }.include?(false)
|
69
|
-
id
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def exists?(opts = {})
|
75
|
-
!!client.smembers(table_name).detect do |id|
|
76
|
-
!opts.map { |k, v| get_dejsonized_attribute(id, k) == v }.include?(false)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def create(opts = {})
|
81
|
-
record = new({ id: SecureRandom.uuid }.merge(opts))
|
82
|
-
|
83
|
-
record.save
|
84
|
-
|
85
|
-
record
|
86
|
-
end
|
87
|
-
|
88
|
-
def destroy_all
|
89
|
-
all.each(&:destroy)
|
90
|
-
|
91
|
-
true
|
92
|
-
end
|
93
|
-
|
94
|
-
def jsonize_attributes(attrs)
|
95
|
-
attrs.map do |attr, value|
|
96
|
-
[attr, value.to_json]
|
97
|
-
end.to_h
|
98
|
-
end
|
99
|
-
|
100
|
-
def dejsonize_attributes(attrs)
|
101
|
-
attrs.map do |attr, value|
|
102
|
-
[attr, value && JSON.parse(value)]
|
103
|
-
end.to_h
|
104
|
-
end
|
105
|
-
|
106
|
-
protected
|
107
|
-
|
108
|
-
def instantiate(id)
|
109
|
-
new(dejsonize_attributes(client.hgetall("#{table_name}:#{id}")))
|
110
|
-
end
|
111
|
-
|
112
|
-
def get_dejsonized_attribute(id, attr)
|
113
|
-
value = client.hget("#{table_name}:#{id}", attr)
|
114
|
-
JSON.parse(value) if value
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
def initialize(opts = {})
|
119
|
-
opts.each { |k, v| send(:"#{k}=", v) }
|
120
|
-
end
|
121
|
-
|
122
|
-
def save
|
123
|
-
self.class.client.hmset("#{table_name}:#{id}", *self.class.jsonize_attributes(attributes))
|
124
|
-
|
125
|
-
unless self.class.client.smembers(table_name).include?(id)
|
126
|
-
self.class.client.sadd(table_name, id)
|
127
|
-
end
|
128
|
-
|
129
|
-
true
|
130
|
-
end
|
131
|
-
|
132
|
-
def update(opts = {})
|
133
|
-
opts.each { |k, v| send(:"#{k}=", v) }
|
134
|
-
save
|
135
|
-
end
|
136
|
-
|
137
|
-
def destroy
|
138
|
-
self.class.client.srem(table_name, id)
|
139
|
-
|
140
|
-
self.class.client.hdel("#{table_name}:#{id}", attributes.keys)
|
141
|
-
|
142
|
-
true
|
143
|
-
end
|
144
|
-
|
145
|
-
def attributes
|
146
|
-
self.class.column_names.map do |column_name|
|
147
|
-
[column_name, instance_variable_get("@#{column_name}")]
|
148
|
-
end.to_h
|
149
|
-
end
|
150
|
-
|
151
|
-
def table_name
|
152
|
-
self.class.table_name
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
@@ -1,106 +0,0 @@
|
|
1
|
-
module Hyperstack
|
2
|
-
class ClassConnectionRegulation
|
3
|
-
def self.connections(acting_user)
|
4
|
-
regulations.collect do |channel, regulation|
|
5
|
-
status = regulation.connectable?(acting_user) ? :allowed : :denied
|
6
|
-
{ type: :class, owner: channel, channel: InternalPolicy.channel_to_string(channel), auto_connect: !regulation.auto_connect_disabled?, status: status }
|
7
|
-
end
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
class InstanceConnectionRegulation
|
12
|
-
def self.connections(acting_user)
|
13
|
-
regulations.collect do |channel, regulation|
|
14
|
-
regulation.connectable_to(acting_user, false).collect do |obj|
|
15
|
-
{ type: :instance, owner: channel, channel: InternalPolicy.channel_to_string(obj), auto_connect: !regulation.auto_connect_disabled?, status: :allowed }
|
16
|
-
end
|
17
|
-
end.flatten(1)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
class InternalPolicy
|
22
|
-
def attribute_dump(acting_user)
|
23
|
-
# dump[channel]['@channel_status'] -> [owner, type, auto_connect, falsy/no connection/allowed]
|
24
|
-
# dump[channel][attribute] -> 'no connection/no channel/no policy/allowed'
|
25
|
-
dump = Hash.new { |h, k| h[k] = Hash.new }
|
26
|
-
connections = ClassConnectionRegulation.connections(acting_user) +
|
27
|
-
InstanceConnectionRegulation.connections(acting_user)
|
28
|
-
connections.each do |status|
|
29
|
-
status[:status] = 'allowed' if status[:status]
|
30
|
-
status[:status] ||= 'no connection'
|
31
|
-
dump[status[:channel]]['@channel_status'] = status
|
32
|
-
end
|
33
|
-
@channel_sets.each do |channel, attribute_set|
|
34
|
-
channel = InternalPolicy.channel_to_string(channel)
|
35
|
-
attribute_set.each do |attribute|
|
36
|
-
dump[channel]['@channel_status'] ||= { type: 'no channel' }
|
37
|
-
dump[channel][attribute] = dump[channel]['@channel_status'][:status] || 'no channel'
|
38
|
-
end
|
39
|
-
end
|
40
|
-
dump.each_key do |channel|
|
41
|
-
@attribute_names.each do |attribute|
|
42
|
-
dump[channel][attribute] ||= 'no policy'
|
43
|
-
end
|
44
|
-
end
|
45
|
-
dump
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
module PolicyDiagnostics
|
50
|
-
def self.policy_dump_hash(model, acting_user)
|
51
|
-
internal_policy = InternalPolicy.new(model, model.attribute_names, :all)
|
52
|
-
ChannelBroadcastRegulation.broadcast(internal_policy)
|
53
|
-
InstanceBroadcastRegulation.broadcast(model, internal_policy)
|
54
|
-
internal_policy.attribute_dump(acting_user)
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.policy_dump_for(model, acting_user)
|
58
|
-
dump = policy_dump_hash(model, acting_user)
|
59
|
-
attributes = model.attribute_names.map(&:to_sym)
|
60
|
-
acting_user_channel = InternalPolicy.channel_to_string(acting_user) if acting_user
|
61
|
-
pastel = Pastel.new
|
62
|
-
channels = dump.keys.collect do |channel|
|
63
|
-
c = channel == acting_user_channel ? "* #{channel} *" : channel
|
64
|
-
if dump[channel]['@channel_status'][:status] != 'allowed'
|
65
|
-
pastel.red(c)
|
66
|
-
elsif channel == acting_user_channel
|
67
|
-
pastel.blue(c)
|
68
|
-
else
|
69
|
-
c
|
70
|
-
end
|
71
|
-
end
|
72
|
-
table = TTY::Table.new header: [''] + channels
|
73
|
-
types = dump.keys.collect do |channel|
|
74
|
-
type = dump[channel]['@channel_status'][:type]
|
75
|
-
type = pastel.red(type) if type == 'no policy'
|
76
|
-
type
|
77
|
-
end
|
78
|
-
table << ['type'] + types
|
79
|
-
table << ['auto connect'] + dump.keys.collect { |channel| dump[channel]['@channel_status'][:auto_connect] }
|
80
|
-
table << ['status'] + dump.keys.collect { |channel| dump[channel]['@channel_status'][:status] }
|
81
|
-
attributes.each do |attribute|
|
82
|
-
allowed = false
|
83
|
-
statuses = dump.keys.collect do |channel|
|
84
|
-
status = dump[channel][attribute]
|
85
|
-
if status == 'allowed'
|
86
|
-
allowed = true
|
87
|
-
status
|
88
|
-
else
|
89
|
-
pastel.red(status)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
attribute = pastel.red(attribute) unless allowed
|
93
|
-
table << [attribute] + statuses
|
94
|
-
end
|
95
|
-
rendered = table.render(:unicode, indent: 4).split("\n")
|
96
|
-
rendered = rendered.insert(6, rendered[2]).join("\n")
|
97
|
-
model_string = "<##{model.class} id: #{model.id}>"
|
98
|
-
if acting_user
|
99
|
-
id = "id: #{acting_user.id}" if acting_user.respond_to? :id
|
100
|
-
acting_user_string = "by acting_user <##{acting_user.class} id: #{id}>"
|
101
|
-
end
|
102
|
-
" Attribute access policies for #{model_string} #{acting_user_string || 'with no acting_user'}:\n\n"\
|
103
|
-
"#{rendered}"
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|