card 1.16.12 → 1.16.13

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/card.gemspec +1 -1
  4. data/db/migrate_core_cards/20130823192433_add_style_cards.rb +39 -24
  5. data/db/migrate_core_cards/20140629222005_add_email_cards.rb +6 -11
  6. data/db/migrate_core_cards/20151120180631_add_token_expiration.rb +7 -0
  7. data/db/seed/new/card_actions.yml +396 -388
  8. data/db/seed/new/card_acts.yml +1 -595
  9. data/db/seed/new/card_changes.yml +8154 -23619
  10. data/db/seed/new/card_references.yml +1009 -988
  11. data/db/seed/new/cards.yml +1445 -1423
  12. data/db/seed/test/fixtures/card_actions.yml +1375 -1399
  13. data/db/seed/test/fixtures/card_acts.yml +445 -1063
  14. data/db/seed/test/fixtures/card_changes.yml +11440 -26881
  15. data/db/seed/test/fixtures/card_references.yml +1523 -1502
  16. data/db/seed/test/fixtures/cards.yml +2736 -2715
  17. data/db/seed/test/seed.rb +7 -10
  18. data/db/version_core_cards.txt +1 -1
  19. data/lib/card/auth.rb +65 -19
  20. data/lib/card/cache.rb +18 -18
  21. data/lib/card/env.rb +10 -10
  22. data/lib/card/format.rb +41 -30
  23. data/lib/card/location.rb +3 -5
  24. data/lib/card/subcards.rb +0 -3
  25. data/lib/card/success.rb +14 -11
  26. data/mod/01_core/set/all/subcards.rb +4 -2
  27. data/mod/01_core/set/all/trash.rb +4 -1
  28. data/mod/02_basic_types/set/type/pointer.rb +5 -2
  29. data/mod/05_email/set/all/notify.rb +85 -73
  30. data/mod/05_email/spec/set/all/notify_spec.rb +74 -55
  31. data/mod/05_standard/set/all/comment.rb +18 -12
  32. data/mod/05_standard/set/all/error.rb +5 -1
  33. data/mod/05_standard/set/right/account.rb +50 -73
  34. data/mod/05_standard/set/right/token.rb +49 -2
  35. data/mod/05_standard/set/self/signin.rb +14 -12
  36. data/mod/05_standard/set/type/signup.rb +17 -21
  37. data/mod/05_standard/spec/set/all/account_spec.rb +1 -1
  38. data/mod/05_standard/spec/set/right/account_spec.rb +76 -52
  39. data/mod/05_standard/spec/set/right/password_spec.rb +10 -11
  40. data/mod/05_standard/spec/set/right/token_spec.rb +19 -1
  41. data/mod/05_standard/spec/set/type/signup_spec.rb +3 -4
  42. data/spec/lib/card/auth_spec.rb +46 -5
  43. metadata +5 -4
@@ -2,19 +2,17 @@
2
2
  require 'timecop'
3
3
 
4
4
  class SharedData
5
- #attr_accessor :users
6
5
  USERS = [
7
- 'Joe User', 'Joe Admin', 'Joe Camel', 'Sample User', 'No count',
8
- 'u1', 'u2', 'u3',
9
- 'Big Brother', 'Optic fan', 'Sunglasses fan', 'Narcissist'
10
- ]
6
+ 'Joe User', 'Joe Admin', 'Joe Camel', 'Sample User', 'No count',
7
+ 'u1', 'u2', 'u3',
8
+ 'Big Brother', 'Optic fan', 'Sunglasses fan', 'Narcissist'
9
+ ]
11
10
 
12
11
  def self.account_args hash
13
- { "+*account" => { "+*password" =>'joe_pass' }.merge( hash ) }
12
+ { "+*account" => { "+*password" => 'joe_pass' }.merge(hash) }
14
13
  end
15
14
 
16
15
  def self.add_test_data
17
-
18
16
  Card::Cache.reset_global
19
17
  Card::Env.reset
20
18
  Card::Auth.as_bot
@@ -52,13 +50,12 @@ class SharedData
52
50
  #above still necessary? try commenting out above and 'Sign up' below
53
51
  Card::Auth.current_id = Card::WagnBotID # need to reset after creating sign up, which changes current_id for extend phase
54
52
 
53
+ no_samples = %( user sign_up set number list listed_by )
55
54
  Card::Auth.createable_types.each do |type|
56
- next if ['User', 'Sign up', 'Set', 'Number', 'List', 'Listed by'].include? type
55
+ next if no_samples.include? type.to_name.key
57
56
  Card.create! type: type, name: "Sample #{type}"
58
57
  end
59
58
 
60
-
61
-
62
59
  # data for role_test.rb
63
60
 
64
61
  Card.create! name: 'u1', type_code: 'user', subcards: account_args('+*email'=>'u1@user.com', '+*password'=>'u1_pass')
@@ -1 +1 @@
1
- 20150910085603
1
+ 20151120180631
@@ -13,33 +13,67 @@ class Card
13
13
  class << self
14
14
  # Authenticates a user by their login name and unencrypted password.
15
15
  def authenticate email, password
16
- accounted = Auth[email]
17
- return unless accounted && (account = accounted.account) &&
18
- account.active?
19
- if Card.config.no_authentication ||
20
- password_authenticated?(account, password.strip)
21
- accounted.id
16
+ account = Auth[email]
17
+ case
18
+ when !account then nil
19
+ when !account.active? then nil
20
+ when Card.config.no_authentication then account
21
+ when password_valid?(account, password.strip) then account
22
22
  end
23
23
  end
24
24
 
25
- def password_authenticated? account, password
25
+ def password_valid? account, password
26
26
  account.password == encrypt(password, account.salt)
27
27
  end
28
28
 
29
+ def set_current_from_token token, current=nil
30
+ account = find_by_token token
31
+ if account && account.validate_token!(token)
32
+ unless current && always_ok_usr_id?(account.left_id)
33
+ current = account.left_id
34
+ end
35
+ set_current_from_mark current
36
+ elsif Env.params[:live_token]
37
+ true
38
+ # Used for activations and resets.
39
+ # Continue as anonymous and address problem later
40
+ else
41
+ false
42
+ end
43
+ end
44
+
45
+ def set_current_from_mark mark
46
+ self.current_id =
47
+ if mark.to_s =~ /@/
48
+ account = Auth[mark.downcase]
49
+ account && account.active? ? account.left_id : Card::AnonymousID
50
+ else
51
+ mark
52
+ end
53
+ end
54
+
55
+ def find_by_token token
56
+ Auth.as_bot do
57
+ Card.search(
58
+ right_id: Card::AccountID,
59
+ right_plus: [{ id: Card::TokenID }, { content: token.strip }]
60
+ ).first
61
+ end
62
+ end
63
+
29
64
  # Encrypts some data with the salt.
30
65
  def encrypt password, salt
31
66
  Digest::SHA1.hexdigest "#{salt}--#{password}--"
32
67
  end
33
68
 
34
- # find accounted by email
69
+ # find account by email
35
70
  def [] email
71
+ email = email.strip.downcase
36
72
  Auth.as_bot do
37
- Card.search(right_plus: [
38
- { id: Card::AccountID },
39
- { right_plus: [
40
- { id: Card::EmailID }, { content: email.strip.downcase }
41
- ] }
42
- ]).first
73
+ Card.search(
74
+ right_id: Card::AccountID,
75
+ right_plus: [{ id: Card::EmailID }, { content: email }]
76
+ ).first
43
77
  end
44
78
  end
45
79
 
@@ -78,6 +112,7 @@ class Card
78
112
 
79
113
  def current_id= card_id
80
114
  @@current = @@as_id = @@as_card = nil
115
+ card_id = card_id.to_i if card_id.present?
81
116
  @@current_id = card_id
82
117
  end
83
118
 
@@ -90,15 +125,21 @@ class Card
90
125
  end
91
126
 
92
127
  def as given_user
93
- tmp_id, tmp_card = @@as_id, @@as_card
128
+ tmp_id = @@as_id
129
+ tmp_card = @@as_card
130
+
131
+ @@as_id = get_user_id(given_user)
132
+ @@as_card = nil
94
133
  # we could go ahead and set as_card if given a card...
95
- @@as_id, @@as_card = get_user_id(given_user), nil
96
134
 
97
135
  @@current_id = @@as_id if @@current_id.nil?
98
136
 
99
137
  return unless block_given?
100
138
  value = yield
101
- @@as_id, @@as_card = tmp_id, tmp_card
139
+
140
+ @@as_id = tmp_id
141
+ @@as_card = tmp_card
142
+
102
143
  value
103
144
  end
104
145
 
@@ -146,8 +187,12 @@ class Card
146
187
  end
147
188
 
148
189
  def always_ok?
149
- # warn Rails.logger.warn("aok? #{as_id}, #{as_id&&Card[as_id].id}")
150
- return false unless (usr_id = as_id)
190
+ usr_id = as_id
191
+ return false if !usr_id
192
+ always_ok_usr_id? usr_id
193
+ end
194
+
195
+ def always_ok_usr_id? usr_id
151
196
  return true if usr_id == Card::WagnBotID # cannot disable
152
197
 
153
198
  always = Card.cache.read('ALWAYS') || {}
@@ -163,6 +208,7 @@ class Card
163
208
  # warn Rails.logger.warn("aok? #{usr_id}, #{always[usr_id]}")
164
209
  always[usr_id]
165
210
  end
211
+
166
212
  # PERMISSIONS
167
213
 
168
214
  def createable_types
@@ -54,11 +54,13 @@ class Card
54
54
  end
55
55
 
56
56
  def generate_cache_id
57
- ((Time.now.to_f * 100).to_i).to_s + ('a'..'z').to_a[rand(26)] + ('a'..'z').to_a[rand(26)]
57
+ ((Time.now.to_f * 100).to_i).to_s +
58
+ ('a'..'z').to_a[rand(26)] +
59
+ ('a'..'z').to_a[rand(26)]
58
60
  end
59
61
 
60
62
  def reset_global
61
- cache_by_class.each do |klass, cache|
63
+ cache_by_class.each do |_klass, cache|
62
64
  cache.reset hard=true
63
65
  end
64
66
  Card::Codename.reset_cache
@@ -67,9 +69,11 @@ class Card
67
69
 
68
70
  def reset_local
69
71
  cache_by_class.each do |cc, cache|
70
- if Card::Cache===cache
72
+ if Card::Cache === cache
71
73
  cache.reset_local
72
- else warn "reset class #{cc}, #{cache.class} #{caller[0..8]*"\n"} ???" end
74
+ else
75
+ warn "reset class #{cc}, #{cache.class} #{caller[0..8] * "\n"} ???"
76
+ end
73
77
  end
74
78
  end
75
79
 
@@ -91,20 +95,16 @@ class Card
91
95
  private
92
96
 
93
97
  def prepopulate
94
- if @@prepopulating
95
- @@rule_cache ||= Card.rule_cache
96
- @@read_rule_cache ||= Card.read_rule_cache
97
- @@user_ids_cache ||= Card.user_ids_cache
98
- @@rule_keys_cache ||= Card.rule_keys_cache
99
- Card.cache.write_local 'RULES', @@rule_cache
100
- Card.cache.write_local 'READRULES', @@read_rule_cache
101
- Card.cache.write_local 'USER_IDS', @@user_ids_cache
102
- Card.cache.write_local 'RULE_KEYS', @@rule_keys_cache
103
- end
98
+ return unless @@prepopulating
99
+ @@rule_cache ||= Card.rule_cache
100
+ @@user_ids_cache ||= Card.user_ids_cache
101
+ @@read_rule_cache ||= Card.read_rule_cache
102
+ @@rule_keys_cache ||= Card.rule_keys_cache
103
+ Card.cache.write_local 'RULES', @@rule_cache
104
+ Card.cache.write_local 'READRULES', @@read_rule_cache
105
+ Card.cache.write_local 'USER_IDS', @@user_ids_cache
106
+ Card.cache.write_local 'RULE_KEYS', @@rule_keys_cache
104
107
  end
105
-
106
-
107
-
108
108
  end
109
109
 
110
110
  attr_reader :prefix, :store, :klass
@@ -179,7 +179,7 @@ class Card
179
179
 
180
180
  def delete key
181
181
  @store.delete(@prefix + key) if @store
182
- @local.delete key
182
+ delete_local key
183
183
  end
184
184
 
185
185
  def delete_local key
@@ -66,29 +66,29 @@ class Card
66
66
  #include Card::Location
67
67
 
68
68
  def location_history
69
- #warn "sess #{session.class}, #{session.object_id}"
70
69
  session[:history] ||= [Card::Location.card_path('')]
71
- if session[:history]
72
- session[:history].shift if session[:history].size > 5
73
- session[:history]
74
- end
70
+ session[:history].shift if session[:history].size > 5
71
+ session[:history]
75
72
  end
76
73
 
77
74
  def save_location card
78
- return if Env.ajax? || !Env.html? || !card.known? || (card.codename == 'signin')
75
+ return if Env.ajax? || !Env.html? || !card.known? ||
76
+ (card.codename == 'signin')
79
77
  discard_locations_for card
80
- session[:previous_location] = Card::Location.card_path card.cardname.url_key
78
+ session[:previous_location] =
79
+ Card::Location.card_path card.cardname.url_key
81
80
  location_history.push previous_location
82
81
  end
83
82
 
84
83
  def previous_location
85
- session[:previous_location] ||= location_history.last if location_history
84
+ return unless location_history
85
+ session[:previous_location] ||= location_history.last
86
86
  end
87
87
 
88
- def discard_locations_for(card)
88
+ def discard_locations_for card
89
89
  # quoting necessary because cards have things like "+*" in the names..
90
90
  session[:history] = location_history.reject do |loc|
91
- if url_key = url_key_for_location(loc)
91
+ if (url_key = url_key_for_location(loc))
92
92
  url_key.to_name.key == card.key
93
93
  end
94
94
  end.compact
@@ -443,8 +443,9 @@ class Card
443
443
  end
444
444
 
445
445
  def nest nested_card, opts={}
446
- #ActiveSupport::Notifications.instrument('card', message: "nest: #{nested_card.name}, #{opts}") do
447
- opts.delete_if { |k,v| v.nil? }
446
+ # ActiveSupport::Notifications.instrument('card', message:
447
+ # "nest: #{nested_card.name}, #{opts}") do
448
+ opts.delete_if { |_k, v| v.nil? }
448
449
  opts.reverse_merge! inclusion_defaults(nested_card)
449
450
 
450
451
  sub = nil
@@ -455,37 +456,48 @@ class Card
455
456
  sub.inclusion_opts = opts[:items] ? opts[:items].clone : {}
456
457
  end
457
458
 
458
-
459
459
  view = canonicalize_view opts.delete :view
460
460
  opts[:home_view] = [:closed, :edit].member?(view) ? :open : view
461
461
  # FIXME: special views should be represented in view definitions
462
462
 
463
- view = case @mode
464
- when :edit
465
- not_ready_for_form = @@perms[view]==:none || nested_card.structure || nested_card.key.blank? # eg {{_self|type}} on new cards
466
- not_ready_for_form ? :blank : :edit_in_form
467
- when :template
468
- :template_rule
469
- when :closed
470
- case
471
- when @@closed_views[view] == true || @@error_codes[view] ; view
472
- when specified_view = @@closed_views[view] ; specified_view
473
- when !nested_card.known? ; :closed_missing
474
- else ; :closed_content
463
+ view =
464
+ case @mode
465
+ when :edit then view_in_edit_mode(view, nested_card)
466
+ when :template then :template_rule
467
+ when :closed then view_in_closed_mode(view, nested_card)
468
+ else view
475
469
  end
476
- else
477
- view
478
- end
479
470
 
480
471
  sub.optional_render view, opts
481
- #end
472
+ # end
473
+ end
474
+
475
+ def view_in_edit_mode homeview, nested_card
476
+ not_in_form =
477
+ @@perms[homeview] == :none || # view configured not to keep in form
478
+ nested_card.structure || # not yet nesting structures
479
+ nested_card.key.blank? # eg {{_self|type}} on new cards
480
+
481
+ not_in_form ? :blank : :edit_in_form
482
+ end
483
+
484
+ def view_in_closed_mode homeview, nested_card
485
+ approved_view = @@closed_views[homeview]
486
+ case
487
+ when approved_view == true then homeview
488
+ when @@error_codes[homeview] then homeview
489
+ when approved_view then approved_view
490
+ when !nested_card.known? then :closed_missing
491
+ else :closed_content
492
+ end
482
493
  end
483
494
 
484
495
  def get_inclusion_content cardname
485
- content = params[cardname.to_s.gsub(/\+/,'_')]
496
+ content = params[cardname.to_s.tr('+', '_')]
486
497
 
487
- # CLEANME This is a hack to get it so plus cards re-populate on failed signups
488
- if p = params['subcards'] and card_params = p[cardname.to_s]
498
+ # CLEANME This is a hack so plus cards re-populate on failed signups
499
+ p = params['subcards']
500
+ if p && card_params = p[cardname.to_s]
489
501
  content = card_params['content']
490
502
  end
491
503
  content if content.present? # why is this necessary? - efm
@@ -510,26 +522,26 @@ class Card
510
522
  :name
511
523
  end
512
524
 
513
-
514
525
  #
515
526
  # ------------ LINKS ---------------
516
527
  #
517
528
 
518
529
  def add_class options, klass
519
- options[:class] = [ options[:class], klass ].flatten.compact * ' '
530
+ options[:class] = [options[:class], klass].flatten.compact * ' '
520
531
  end
521
532
 
522
-
523
533
  def unique_id
524
534
  "#{card.key}-#{Time.now.to_i}-#{rand(3)}"
525
535
  end
526
536
 
527
- def format_date date, include_time = true
528
- # Must use DateTime because Time doesn't support %e on at least some platforms
537
+ def format_date date, include_time=true
538
+ # using DateTime because Time doesn't support %e on some platforms
529
539
  if include_time
530
- DateTime.new(date.year, date.mon, date.day, date.hour, date.min, date.sec).strftime("%B %e, %Y %H:%M:%S")
540
+ DateTime.new(
541
+ date.year, date.mon, date.day, date.hour, date.min, date.sec
542
+ ).strftime('%B %e, %Y %H:%M:%S')
531
543
  else
532
- DateTime.new(date.year, date.mon, date.day).strftime("%B %e, %Y")
544
+ DateTime.new(date.year, date.mon, date.day).strftime('%B %e, %Y')
533
545
  end
534
546
  end
535
547
 
@@ -538,7 +550,6 @@ class Card
538
550
  @context_names += name.to_name.part_names
539
551
  @context_names.uniq!
540
552
  end
541
-
542
553
  end
543
554
  end
544
555
 
@@ -1,8 +1,7 @@
1
1
  class Card
2
-
3
2
  module Location
4
- #
5
- # page_path takes a Card::Name, adds the format and query string to url_key (site-absolute)
3
+ # page_path takes a Card::Name, adds the format and query string to
4
+ # url_key (site-absolute)
6
5
  # card_path makes a relative path site-absolute (if not already)
7
6
  # card_url makes it a full url (if not already)
8
7
 
@@ -34,5 +33,4 @@ class Card
34
33
 
35
34
  extend Location
36
35
  end
37
-
38
- end
36
+ end
@@ -98,11 +98,8 @@ class Card
98
98
 
99
99
  def rename old_name, new_name
100
100
  return unless @keys.include? old_name.to_name.key
101
-
102
101
  end
103
102
 
104
-
105
-
106
103
  def << value
107
104
  add value
108
105
  end
@@ -11,9 +11,6 @@ class Card
11
11
  case success_params
12
12
  when Hash
13
13
  apply(success_params)
14
- when /^REDIRECT:\s*(.+)/
15
- @redirect=true
16
- self.target = $1
17
14
  when nil ; self.name = '_self'
18
15
  else ; self.target = success_params
19
16
  end
@@ -59,14 +56,20 @@ class Card
59
56
 
60
57
  def target= value
61
58
  @id = @name = @card = nil
62
- @target =
63
- case value
64
- when '*previous', :previous ; :previous
65
- when /^(http|\/)/ ; value
66
- when /^TEXT:\s*(.+)/ ; $1
67
- when '' ; ''
68
- else ; self.mark = value
69
- end
59
+ @target = process_target value
60
+ end
61
+
62
+ def process_target value
63
+ case value
64
+ when '' then ''
65
+ when '*previous', :previous then :previous
66
+ when /^(http|\/)/ then value
67
+ when /^TEXT:\s*(.+)/ then $1
68
+ when /^REDIRECT:\s*(.+)/
69
+ @redirect = true
70
+ process_target $1
71
+ else self.mark = value
72
+ end
70
73
  end
71
74
 
72
75
  def apply args