card 1.101.3 → 1.101.4

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