card 1.101.3 → 1.101.4
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/VERSION +1 -1
- data/config/initializers/02_patches/active_record.rb +1 -1
- data/config/locales/en.yml +155 -378
- data/db/migrate_core_cards/20150202143810_import_bootstrap_layout.rb +1 -1
- data/lib/card.rb +15 -2
- data/lib/card/auth.rb +5 -2
- data/lib/card/auth/current.rb +39 -100
- data/lib/card/auth/proxy.rb +36 -16
- data/lib/card/auth/token.rb +6 -0
- data/lib/card/cache/all.rb +83 -0
- data/lib/card/cache/card_class.rb +41 -0
- data/lib/card/cache/persistent.rb +3 -34
- data/lib/card/cache/persistent_class.rb +28 -0
- data/lib/card/codename.rb +1 -1
- data/lib/card/content.rb +16 -2
- data/lib/card/content/all.rb +59 -0
- data/lib/card/director/act_direction.rb +4 -0
- data/lib/card/director/all.rb +61 -0
- data/lib/card/director/card_class.rb +18 -0
- data/lib/card/director/phases.rb +0 -1
- data/lib/card/dirty.rb +13 -3
- data/lib/card/env/success.rb +14 -14
- data/lib/card/env/success/target.rb +9 -11
- data/lib/card/error.rb +1 -1
- data/lib/card/fetch/all.rb +32 -0
- data/lib/card/fetch/card_class.rb +147 -0
- data/lib/card/format.rb +1 -1
- data/lib/card/format/error.rb +3 -3
- data/lib/card/format/nest.rb +1 -1
- data/lib/card/format/nest/fetch.rb +1 -1
- data/lib/card/lexicon.rb +2 -2
- data/lib/card/name/all.rb +8 -0
- data/lib/card/name/all/descendants.rb +6 -3
- data/lib/card/name/card_class.rb +26 -0
- data/lib/card/reference/all.rb +131 -0
- data/lib/card/rule/all.rb +75 -0
- data/lib/card/set/event/all.rb +95 -0
- data/lib/card/set/event/skip_and_trigger.rb +89 -0
- data/lib/card/set/pattern/all.rb +63 -0
- data/lib/card/subcards/all.rb +103 -0
- data/lib/cardio/migration/import.rb +1 -1
- data/lib/cardio/utils.rb +5 -3
- data/mod/admin/set/self/admin_info.rb +3 -5
- data/mod/admin/set/self/trash.rb +2 -2
- data/mod/core/set/all/autoname.rb +17 -0
- data/mod/core/set/all/codename.rb +2 -2
- data/mod/core/set/all/content.rb +52 -97
- data/mod/core/set/all/name_events.rb +69 -58
- data/mod/core/set/all/reference_events.rb +67 -0
- data/mod/core/set/all/states.rb +2 -2
- data/mod/core/set/all/subcards.rb +0 -100
- data/mod/core/set/all/trash.rb +11 -13
- data/mod/core/set/all/type.rb +7 -9
- data/mod/core/set/all/utils.rb +3 -0
- data/mod/core/set/type/cardtype.rb +3 -3
- data/mod/core/set_pattern/06_rule.rb +1 -1
- data/mod/core/spec/set/all/{rules2_spec.rb → clean_me_spec.rb} +0 -0
- data/mod/core/spec/set/all/name_events_spec.rb +204 -0
- metadata +30 -37
- data/lib/card/mod_inflector.rb +0 -16
- data/lib/card/name/all/class_methods.rb +0 -28
- data/mod/core/set/all/actify.rb +0 -68
- data/mod/core/set/all/cache.rb +0 -109
- data/mod/core/set/all/event_conditions.rb +0 -172
- data/mod/core/set/all/fetch.rb +0 -122
- data/mod/core/set/all/fetch_helper.rb +0 -35
- data/mod/core/set/all/i18n.rb +0 -9
- data/mod/core/set/all/pattern.rb +0 -54
- data/mod/core/set/all/references.rb +0 -191
- data/mod/core/set/all/rename.rb +0 -33
- data/mod/core/set/all/rules.rb +0 -81
- data/mod/core/spec/set/all/actify_spec.rb +0 -58
- data/mod/core/spec/set/all/content_spec.rb +0 -15
- data/mod/core/spec/set/all/event_conditions_spec.rb +0 -217
- data/mod/core/spec/set/all/fetch_helper_spec.rb +0 -65
- data/mod/core/spec/set/all/fetch_spec.rb +0 -338
- data/mod/core/spec/set/all/i18n_spec.rb +0 -17
- data/mod/core/spec/set/all/pattern_spec.rb +0 -101
- data/mod/core/spec/set/all/permissions/reader_rules_spec.rb +0 -166
- data/mod/core/spec/set/all/references_spec.rb +0 -62
- data/mod/core/spec/set/all/rename_spec.rb +0 -189
- data/mod/core/spec/set/all/rules_spec.rb +0 -100
- data/mod/core/spec/set/all/subcards_spec.rb +0 -102
@@ -66,7 +66,7 @@ class ImportBootstrapLayout < Cardio::Migration::Core
|
|
66
66
|
# update layouts to have explicit views in nests
|
67
67
|
Card.search(type_id: Card::LayoutTypeID) do |lcard|
|
68
68
|
lcontent = Card::Content.new lcard.db_content, lcard
|
69
|
-
lcontent.find_chunks(
|
69
|
+
lcontent.find_chunks(:Nest).each do |nest|
|
70
70
|
nest.explicit_view =
|
71
71
|
nest.options[:nest_name] == "_main" ? "open" : "core"
|
72
72
|
end
|
data/lib/card.rb
CHANGED
@@ -113,12 +113,24 @@ ActiveSupport.run_load_hooks(:before_card, self)
|
|
113
113
|
class Card < ApplicationRecord
|
114
114
|
extend Mark
|
115
115
|
extend Dirty::MethodFactory
|
116
|
-
extend Name::
|
116
|
+
extend Name::CardClass
|
117
|
+
extend Cache::CardClass
|
118
|
+
extend Director::CardClass
|
119
|
+
extend Fetch::CardClass
|
117
120
|
|
118
121
|
include Dirty
|
119
122
|
include DirtyNames
|
120
123
|
include Director::CardMethods
|
121
124
|
include Name::All
|
125
|
+
include Content::All
|
126
|
+
include Set::Event::All
|
127
|
+
include Set::Pattern::All
|
128
|
+
include Cache::All
|
129
|
+
include Director::All
|
130
|
+
include Reference::All
|
131
|
+
include Rule::All
|
132
|
+
include Fetch::All
|
133
|
+
include Subcards::All
|
122
134
|
|
123
135
|
Card::Cache # trigger autoload
|
124
136
|
|
@@ -146,7 +158,6 @@ class Card < ApplicationRecord
|
|
146
158
|
:skip_in_action, # skip event for just this card
|
147
159
|
:trigger, # trigger event(s) for all cards in act
|
148
160
|
:trigger_in_action, # trigger event for just this card
|
149
|
-
|
150
161
|
:comment, # obviated soon
|
151
162
|
|
152
163
|
# TODO: refactor following to use skip/trigger
|
@@ -156,6 +167,8 @@ class Card < ApplicationRecord
|
|
156
167
|
]
|
157
168
|
|
158
169
|
attr_accessor(*action_specific_attributes)
|
170
|
+
self.action_specific_attributes +=
|
171
|
+
%i[skip_hash full_skip_hash trigger_hash full_trigger_hash]
|
159
172
|
|
160
173
|
define_callbacks :select_action, :show_page, :act
|
161
174
|
|
data/lib/card/auth.rb
CHANGED
@@ -10,8 +10,7 @@ class Card
|
|
10
10
|
extend Proxy
|
11
11
|
extend Setup
|
12
12
|
extend Current
|
13
|
-
|
14
|
-
@as_card = @as_id = @current_id = @current = nil
|
13
|
+
extend Token
|
15
14
|
|
16
15
|
class << self
|
17
16
|
# authenticate a user by their login name and unencrypted password.
|
@@ -40,6 +39,10 @@ class Card
|
|
40
39
|
def encrypt password, salt
|
41
40
|
Digest::SHA1.hexdigest "#{salt}--#{password}--"
|
42
41
|
end
|
42
|
+
|
43
|
+
def serialize
|
44
|
+
{ as_id: as_id, current_id: current_id }
|
45
|
+
end
|
43
46
|
end
|
44
47
|
end
|
45
48
|
end
|
data/lib/card/auth/current.rb
CHANGED
@@ -2,114 +2,66 @@ class Card
|
|
2
2
|
module Auth
|
3
3
|
# methods for setting current account
|
4
4
|
module Current
|
5
|
-
# set current user in process and session
|
6
|
-
def signin cardish
|
7
|
-
signin_id = Card.id(cardish) || Card::AnonymousID
|
8
|
-
self.current_id = signin_id
|
9
|
-
set_session_user signin_id
|
10
|
-
end
|
11
|
-
|
12
|
-
# current user is not anonymous
|
13
|
-
# @return [true/false]
|
14
|
-
def signed_in?
|
15
|
-
current_id != Card::AnonymousID
|
16
|
-
end
|
17
|
-
|
18
5
|
# id of current user card.
|
19
6
|
# @return [Integer]
|
20
7
|
def current_id
|
21
8
|
@current_id ||= Card::AnonymousID
|
22
9
|
end
|
23
10
|
|
11
|
+
# set the id of the current user.
|
12
|
+
# @return [Integer]
|
13
|
+
def current_id= card_id
|
14
|
+
reset
|
15
|
+
card_id = card_id.to_i if card_id.present?
|
16
|
+
@current_id = card_id
|
17
|
+
end
|
18
|
+
|
24
19
|
# current accounted card (must have +\*account)
|
25
20
|
# @return [Card]
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
@current = Card[current_id]
|
31
|
-
end
|
21
|
+
def current_card
|
22
|
+
return @current_card if @current_card&.id == current_id
|
23
|
+
|
24
|
+
@current_card = Card[current_id]
|
32
25
|
end
|
26
|
+
alias_method :current, :current_card
|
33
27
|
|
34
28
|
def current_roles
|
35
29
|
@current_roles ||= [Card.fetch_name(:anyone_signed_in),
|
36
30
|
current.fetch(:roles)&.item_names].flatten.compact
|
37
31
|
end
|
38
32
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
# @param auth_data [Integer|Hash] user id, user name, or a hash
|
44
|
-
# @option auth_data [Integer] current_id
|
45
|
-
# @option auth_data [Integer] as_id
|
46
|
-
def with auth_data
|
47
|
-
if auth_data.is_a?(Integer) || auth_data.is_a?(String)
|
48
|
-
auth_data = { current_id: Card.id(auth_data) }
|
49
|
-
end
|
50
|
-
|
51
|
-
tmp_current_id = current_id
|
52
|
-
tmp_as_id = as_id
|
53
|
-
tmp_current = @current
|
54
|
-
tmp_as_card = @as_card
|
55
|
-
tmp_current_roles = @current_roles
|
56
|
-
|
57
|
-
# resets @as and @as_card
|
58
|
-
self.current_id = auth_data[:current_id]
|
59
|
-
@as_id = auth_data[:as_id] if auth_data[:as_id]
|
60
|
-
yield
|
61
|
-
ensure
|
62
|
-
@current_id = tmp_current_id
|
63
|
-
@as_id = tmp_as_id
|
64
|
-
@current = tmp_current
|
65
|
-
@as_card = tmp_as_card
|
66
|
-
@current_roles = tmp_current_roles
|
33
|
+
# set current user in process and session
|
34
|
+
def signin cardish
|
35
|
+
session[session_user_key] =
|
36
|
+
self.current_id = Card.id(cardish) || Card::AnonymousID
|
67
37
|
end
|
68
38
|
|
69
|
-
#
|
70
|
-
# return [
|
71
|
-
def
|
72
|
-
Card::
|
39
|
+
# current user is not anonymous
|
40
|
+
# @return [true/false]
|
41
|
+
def signed_in?
|
42
|
+
current_id != Card::AnonymousID
|
73
43
|
end
|
74
44
|
|
75
45
|
# set current from token, api_key, or session
|
76
|
-
def signin_with
|
46
|
+
def signin_with _opts={}
|
77
47
|
if opts[:token]
|
78
48
|
signin_with_token opts[:token]
|
79
|
-
elsif opts[:api_key]
|
80
|
-
signin_with_api_key opts[:api_key]
|
81
49
|
else
|
82
50
|
signin_with_session
|
83
51
|
end
|
84
52
|
end
|
85
53
|
|
86
|
-
# set the current user based on token
|
87
|
-
def signin_with_token token
|
88
|
-
payload = Token.validate! token
|
89
|
-
signin payload[:anonymous] ? Card::AnonymousID : payload[:user_id]
|
90
|
-
end
|
91
|
-
|
92
|
-
# set the current user based on api_key
|
93
|
-
def signin_with_api_key api_key
|
94
|
-
account = find_account_by_api_key api_key
|
95
|
-
unless account&.validate_api_key! api_key
|
96
|
-
raise Card::Error::PermissionDenied, "API key authentication failed"
|
97
|
-
end
|
98
|
-
|
99
|
-
signin account.left_id
|
100
|
-
end
|
101
|
-
|
102
54
|
# get :user id from session and set Auth.current_id
|
103
55
|
def signin_with_session
|
104
|
-
card_id =
|
105
|
-
|
56
|
+
card_id = session[session_user_key]
|
57
|
+
card_id = nil unless Card.exists? card_id
|
58
|
+
signin card_id
|
106
59
|
end
|
107
60
|
|
108
|
-
#
|
109
|
-
#
|
110
|
-
|
111
|
-
|
112
|
-
find_account_by :api_key, api_key.strip
|
61
|
+
# get session object from Env
|
62
|
+
# return [Session]
|
63
|
+
def session
|
64
|
+
Card::Env.session
|
113
65
|
end
|
114
66
|
|
115
67
|
# find +\*account card by +\*email card
|
@@ -119,6 +71,16 @@ class Card
|
|
119
71
|
find_account_by :email, email.strip.downcase
|
120
72
|
end
|
121
73
|
|
74
|
+
def reset
|
75
|
+
@as_id = @as_card = @current_id = @current_card = @current_roles = nil
|
76
|
+
end
|
77
|
+
|
78
|
+
def session_user_key
|
79
|
+
"user_#{Cardio.database_name.underscore}".to_sym
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
122
84
|
# general pattern for finding +\*account card based on field cards
|
123
85
|
# @param fieldcode [Symbol] code of account field
|
124
86
|
# @param value [String] content of field
|
@@ -130,29 +92,6 @@ class Card
|
|
130
92
|
"find +:account with +#{fieldcode} (#{value})").first
|
131
93
|
end
|
132
94
|
end
|
133
|
-
|
134
|
-
def session_user
|
135
|
-
session[session_user_key]
|
136
|
-
end
|
137
|
-
|
138
|
-
def set_session_user card_id
|
139
|
-
session[session_user_key] = card_id
|
140
|
-
end
|
141
|
-
|
142
|
-
def session_user_key
|
143
|
-
"user_#{database.underscore}".to_sym
|
144
|
-
end
|
145
|
-
|
146
|
-
def database
|
147
|
-
Rails.configuration.database_configuration.dig Rails.env, "database"
|
148
|
-
end
|
149
|
-
|
150
|
-
# set the id of the current user.
|
151
|
-
def current_id= card_id
|
152
|
-
@current = @as_id = @as_card = @current_roles = nil
|
153
|
-
card_id = card_id.to_i if card_id.present?
|
154
|
-
@current_id = card_id
|
155
|
-
end
|
156
95
|
end
|
157
96
|
end
|
158
97
|
end
|
data/lib/card/auth/proxy.rb
CHANGED
@@ -4,10 +4,10 @@ class Card
|
|
4
4
|
module Proxy
|
5
5
|
# operate with the permissions of another "proxy" user
|
6
6
|
def as given_user
|
7
|
-
tmp_id
|
7
|
+
tmp_id = @as_id
|
8
8
|
tmp_card = @as_card
|
9
9
|
|
10
|
-
@as_id
|
10
|
+
@as_id = Card.id given_user
|
11
11
|
@as_card = nil
|
12
12
|
# we could go ahead and set as_card if given a card...
|
13
13
|
|
@@ -18,7 +18,7 @@ class Card
|
|
18
18
|
yield
|
19
19
|
ensure
|
20
20
|
if block_given?
|
21
|
-
@as_id
|
21
|
+
@as_id = tmp_id
|
22
22
|
@as_card = tmp_card
|
23
23
|
end
|
24
24
|
end
|
@@ -37,22 +37,42 @@ class Card
|
|
37
37
|
# proxy user card
|
38
38
|
# @return [Card]
|
39
39
|
def as_card
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
@as_card = Card[as_id]
|
44
|
-
end
|
40
|
+
return @as_card if @as_card&.id == as_id
|
41
|
+
|
42
|
+
@as_card = Card[as_id]
|
45
43
|
end
|
46
44
|
|
47
|
-
#
|
48
|
-
# @
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
when Integer then user
|
54
|
-
else Card.fetch_id(user)
|
45
|
+
# @param auth_data [Integer|Hash] user id, user name, or a hash
|
46
|
+
# @option auth_data [Integer] current_id
|
47
|
+
# @option auth_data [Integer] as_id
|
48
|
+
def with auth_data
|
49
|
+
if auth_data.is_a?(Integer) || auth_data.is_a?(String)
|
50
|
+
auth_data = { current_id: Card.id(auth_data) }
|
55
51
|
end
|
52
|
+
|
53
|
+
temporarily do
|
54
|
+
# resets @as and @as_card
|
55
|
+
self.current_id = auth_data[:current_id]
|
56
|
+
@as_id = auth_data[:as_id] if auth_data[:as_id]
|
57
|
+
yield
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def temporarily
|
64
|
+
tmp_current_id = current_id
|
65
|
+
tmp_as_id = as_id
|
66
|
+
tmp_current_card = @current_card
|
67
|
+
tmp_as_card = @as_card
|
68
|
+
tmp_current_roles = @current_roles
|
69
|
+
yield
|
70
|
+
ensure
|
71
|
+
@current_id = tmp_current_id
|
72
|
+
@as_id = tmp_as_id
|
73
|
+
@current = tmp_current_card
|
74
|
+
@as_card = tmp_as_card
|
75
|
+
@current_roles = tmp_current_roles
|
56
76
|
end
|
57
77
|
end
|
58
78
|
end
|
data/lib/card/auth/token.rb
CHANGED
@@ -33,6 +33,12 @@ class Card
|
|
33
33
|
Card.config.token_expiry.from_now.to_i
|
34
34
|
end
|
35
35
|
end
|
36
|
+
|
37
|
+
# set the current user based on token
|
38
|
+
def signin_with_token token
|
39
|
+
payload = Token.validate! token
|
40
|
+
signin payload[:anonymous] ? Card::AnonymousID : payload[:user_id]
|
41
|
+
end
|
36
42
|
end
|
37
43
|
end
|
38
44
|
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
class Card
|
2
|
+
class Cache
|
3
|
+
# cache-related instance methods available to all Cards
|
4
|
+
module All
|
5
|
+
def expire cache_type=nil
|
6
|
+
return unless (cache_class = cache_class_from_type cache_type)
|
7
|
+
expire_views
|
8
|
+
expire_names cache_class
|
9
|
+
expire_id cache_class
|
10
|
+
end
|
11
|
+
|
12
|
+
def view_cache_clean?
|
13
|
+
!db_content_changed?
|
14
|
+
end
|
15
|
+
|
16
|
+
def ensure_view_cache_key cache_key
|
17
|
+
return if view_cache_keys.include? cache_key
|
18
|
+
|
19
|
+
view_cache_keys << cache_key
|
20
|
+
hard_write_view_cache_keys
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def hard_read_view_cache_keys key_root=key
|
26
|
+
Card.cache.hard&.read_attribute key_root, :view_cache_keys
|
27
|
+
end
|
28
|
+
|
29
|
+
def hard_write_view_cache_keys
|
30
|
+
# puts "WRITE VIEW CACHE KEYS (#{name}): #{view_cache_keys}"
|
31
|
+
Card.cache.hard&.write_attribute key, :view_cache_keys, view_cache_keys
|
32
|
+
end
|
33
|
+
|
34
|
+
def cache_class_from_type cache_type
|
35
|
+
cache_type ? Card.cache.send(cache_type) : Card.cache
|
36
|
+
end
|
37
|
+
|
38
|
+
def view_cache_keys
|
39
|
+
@view_cache_keys ||= hard_read_view_cache_keys(key) || []
|
40
|
+
end
|
41
|
+
|
42
|
+
def expire_names cache
|
43
|
+
each_key_version do |key_version|
|
44
|
+
expire_name key_version, cache
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def expire_name name_version, cache
|
49
|
+
return unless name_version.present?
|
50
|
+
key_version = name_version.to_name.key
|
51
|
+
return unless key_version.present?
|
52
|
+
cache.delete key_version
|
53
|
+
end
|
54
|
+
|
55
|
+
def expire_views
|
56
|
+
each_key_version do |key|
|
57
|
+
# puts "EXPIRE VIEW CACHE (#{name}): #{view_cache_keys}"
|
58
|
+
view_keys = hard_read_view_cache_keys key
|
59
|
+
next unless view_keys.present?
|
60
|
+
expire_view_cache_keys view_keys
|
61
|
+
end
|
62
|
+
@view_cache_keys = []
|
63
|
+
end
|
64
|
+
|
65
|
+
def expire_id cache
|
66
|
+
return unless id.present?
|
67
|
+
cache.delete "~#{id}"
|
68
|
+
end
|
69
|
+
|
70
|
+
def expire_view_cache_keys view_keys
|
71
|
+
Array.wrap(view_keys).each do |view_key|
|
72
|
+
Card::View.cache.delete view_key
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def each_key_version
|
77
|
+
[name, name_before_act].uniq.compact.each do |name_version|
|
78
|
+
yield name_version.to_name.key
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class Card
|
2
|
+
class Cache
|
3
|
+
# cache-related class methods
|
4
|
+
module CardClass
|
5
|
+
def retrieve_from_cache cache_key, local_only=false
|
6
|
+
return unless cache
|
7
|
+
local_only ? cache.soft.read(cache_key) : cache.read(cache_key)
|
8
|
+
end
|
9
|
+
|
10
|
+
def retrieve_from_cache_by_id id, local_only=false
|
11
|
+
key = Card::Lexicon.name(id)&.key
|
12
|
+
return unless key.present?
|
13
|
+
|
14
|
+
retrieve_from_cache key, local_only if key
|
15
|
+
end
|
16
|
+
|
17
|
+
def retrieve_from_cache_by_key key, local_only=false
|
18
|
+
retrieve_from_cache key, local_only
|
19
|
+
end
|
20
|
+
|
21
|
+
def write_to_cache card, local_only=false
|
22
|
+
if local_only
|
23
|
+
write_to_soft_cache card
|
24
|
+
elsif cache
|
25
|
+
cache.write card.key, card
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def write_to_soft_cache card
|
30
|
+
return unless cache
|
31
|
+
cache.soft.write card.key, card
|
32
|
+
end
|
33
|
+
|
34
|
+
def expire name
|
35
|
+
key = name.to_name.key
|
36
|
+
return unless (card = Card.cache.read key)
|
37
|
+
card.expire
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|