hyper-operation 1.0.alpha1.8 → 1.0.0.lap28
Sign up to get free protection for your applications and to get access to all the features.
- 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
|