card 1.101.3 → 1.101.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|