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.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/config/initializers/02_patches/active_record.rb +1 -1
  4. data/config/locales/en.yml +155 -378
  5. data/db/migrate_core_cards/20150202143810_import_bootstrap_layout.rb +1 -1
  6. data/lib/card.rb +15 -2
  7. data/lib/card/auth.rb +5 -2
  8. data/lib/card/auth/current.rb +39 -100
  9. data/lib/card/auth/proxy.rb +36 -16
  10. data/lib/card/auth/token.rb +6 -0
  11. data/lib/card/cache/all.rb +83 -0
  12. data/lib/card/cache/card_class.rb +41 -0
  13. data/lib/card/cache/persistent.rb +3 -34
  14. data/lib/card/cache/persistent_class.rb +28 -0
  15. data/lib/card/codename.rb +1 -1
  16. data/lib/card/content.rb +16 -2
  17. data/lib/card/content/all.rb +59 -0
  18. data/lib/card/director/act_direction.rb +4 -0
  19. data/lib/card/director/all.rb +61 -0
  20. data/lib/card/director/card_class.rb +18 -0
  21. data/lib/card/director/phases.rb +0 -1
  22. data/lib/card/dirty.rb +13 -3
  23. data/lib/card/env/success.rb +14 -14
  24. data/lib/card/env/success/target.rb +9 -11
  25. data/lib/card/error.rb +1 -1
  26. data/lib/card/fetch/all.rb +32 -0
  27. data/lib/card/fetch/card_class.rb +147 -0
  28. data/lib/card/format.rb +1 -1
  29. data/lib/card/format/error.rb +3 -3
  30. data/lib/card/format/nest.rb +1 -1
  31. data/lib/card/format/nest/fetch.rb +1 -1
  32. data/lib/card/lexicon.rb +2 -2
  33. data/lib/card/name/all.rb +8 -0
  34. data/lib/card/name/all/descendants.rb +6 -3
  35. data/lib/card/name/card_class.rb +26 -0
  36. data/lib/card/reference/all.rb +131 -0
  37. data/lib/card/rule/all.rb +75 -0
  38. data/lib/card/set/event/all.rb +95 -0
  39. data/lib/card/set/event/skip_and_trigger.rb +89 -0
  40. data/lib/card/set/pattern/all.rb +63 -0
  41. data/lib/card/subcards/all.rb +103 -0
  42. data/lib/cardio/migration/import.rb +1 -1
  43. data/lib/cardio/utils.rb +5 -3
  44. data/mod/admin/set/self/admin_info.rb +3 -5
  45. data/mod/admin/set/self/trash.rb +2 -2
  46. data/mod/core/set/all/autoname.rb +17 -0
  47. data/mod/core/set/all/codename.rb +2 -2
  48. data/mod/core/set/all/content.rb +52 -97
  49. data/mod/core/set/all/name_events.rb +69 -58
  50. data/mod/core/set/all/reference_events.rb +67 -0
  51. data/mod/core/set/all/states.rb +2 -2
  52. data/mod/core/set/all/subcards.rb +0 -100
  53. data/mod/core/set/all/trash.rb +11 -13
  54. data/mod/core/set/all/type.rb +7 -9
  55. data/mod/core/set/all/utils.rb +3 -0
  56. data/mod/core/set/type/cardtype.rb +3 -3
  57. data/mod/core/set_pattern/06_rule.rb +1 -1
  58. data/mod/core/spec/set/all/{rules2_spec.rb → clean_me_spec.rb} +0 -0
  59. data/mod/core/spec/set/all/name_events_spec.rb +204 -0
  60. metadata +30 -37
  61. data/lib/card/mod_inflector.rb +0 -16
  62. data/lib/card/name/all/class_methods.rb +0 -28
  63. data/mod/core/set/all/actify.rb +0 -68
  64. data/mod/core/set/all/cache.rb +0 -109
  65. data/mod/core/set/all/event_conditions.rb +0 -172
  66. data/mod/core/set/all/fetch.rb +0 -122
  67. data/mod/core/set/all/fetch_helper.rb +0 -35
  68. data/mod/core/set/all/i18n.rb +0 -9
  69. data/mod/core/set/all/pattern.rb +0 -54
  70. data/mod/core/set/all/references.rb +0 -191
  71. data/mod/core/set/all/rename.rb +0 -33
  72. data/mod/core/set/all/rules.rb +0 -81
  73. data/mod/core/spec/set/all/actify_spec.rb +0 -58
  74. data/mod/core/spec/set/all/content_spec.rb +0 -15
  75. data/mod/core/spec/set/all/event_conditions_spec.rb +0 -217
  76. data/mod/core/spec/set/all/fetch_helper_spec.rb +0 -65
  77. data/mod/core/spec/set/all/fetch_spec.rb +0 -338
  78. data/mod/core/spec/set/all/i18n_spec.rb +0 -17
  79. data/mod/core/spec/set/all/pattern_spec.rb +0 -101
  80. data/mod/core/spec/set/all/permissions/reader_rules_spec.rb +0 -166
  81. data/mod/core/spec/set/all/references_spec.rb +0 -62
  82. data/mod/core/spec/set/all/rename_spec.rb +0 -189
  83. data/mod/core/spec/set/all/rules_spec.rb +0 -100
  84. 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(Card::Content::Chunk::Nest).each do |nest|
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::All::ClassMethods
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
@@ -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 current
27
- if @current && @current.id == current_id
28
- @current
29
- else
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
- def serialize
40
- { as_id: as_id, current_id: current_id }
41
- end
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
- # get session object from Env
70
- # return [Session]
71
- def session
72
- Card::Env.session
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 opts={}
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 = session_user
105
- signin(card_id && Card.exists?(card_id) ? card_id : nil)
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
- # find +\*account card by +\*api card
109
- # @param api_key [String]
110
- # @return [+*account card, nil]
111
- def find_account_by_api_key api_key
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
@@ -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 = @as_id
7
+ tmp_id = @as_id
8
8
  tmp_card = @as_card
9
9
 
10
- @as_id = get_user_id(given_user)
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 = tmp_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
- if @as_card && @as_card.id == as_id
41
- @as_card
42
- else
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
- # get card id from args of unknown type
48
- # @todo replace with general mechanism, eg #quick_fetch
49
- def get_user_id user
50
- case user
51
- when NilClass then nil
52
- when Card then user.id
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
@@ -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