stormpath-sdk 1.6.0 → 1.7.0

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 (147) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +21 -0
  3. data/CHANGES.md +11 -0
  4. data/README.md +23 -25
  5. data/lib/stormpath-sdk.rb +11 -2
  6. data/lib/stormpath-sdk/api_key.rb +0 -1
  7. data/lib/stormpath-sdk/auth/basic_authenticator.rb +7 -7
  8. data/lib/stormpath-sdk/auth/basic_login_attempt.rb +7 -11
  9. data/lib/stormpath-sdk/auth/create_factor.rb +1 -1
  10. data/lib/stormpath-sdk/auth/register_service_provider.rb +41 -0
  11. data/lib/stormpath-sdk/auth/username_password_request.rb +3 -5
  12. data/lib/stormpath-sdk/cache/cache.rb +3 -3
  13. data/lib/stormpath-sdk/cache/cache_entry.rb +2 -2
  14. data/lib/stormpath-sdk/cache/cache_manager.rb +3 -4
  15. data/lib/stormpath-sdk/cache/cache_stats.rb +1 -3
  16. data/lib/stormpath-sdk/cache/disabled_cache_store.rb +5 -8
  17. data/lib/stormpath-sdk/cache/memory_store.rb +1 -1
  18. data/lib/stormpath-sdk/cache/redis_store.rb +4 -4
  19. data/lib/stormpath-sdk/client.rb +35 -33
  20. data/lib/stormpath-sdk/data_store.rb +278 -257
  21. data/lib/stormpath-sdk/error.rb +18 -7
  22. data/lib/stormpath-sdk/http/authc/sauthc1_signer.rb +76 -82
  23. data/lib/stormpath-sdk/http/http_client_request_executor.rb +10 -8
  24. data/lib/stormpath-sdk/http/response.rb +5 -7
  25. data/lib/stormpath-sdk/id_site/id_site_result.rb +5 -6
  26. data/lib/stormpath-sdk/oauth/access_token_authentication_result.rb +5 -9
  27. data/lib/stormpath-sdk/oauth/authenticator.rb +2 -2
  28. data/lib/stormpath-sdk/oauth/error.rb +4 -4
  29. data/lib/stormpath-sdk/oauth/id_site_grant_request.rb +1 -1
  30. data/lib/stormpath-sdk/oauth/password_grant_request.rb +1 -1
  31. data/lib/stormpath-sdk/oauth/refresh_grant_request.rb +2 -2
  32. data/lib/stormpath-sdk/oauth/stormpath_grant_request.rb +2 -2
  33. data/lib/stormpath-sdk/provider/account_access.rb +0 -2
  34. data/lib/stormpath-sdk/provider/account_result.rb +1 -2
  35. data/lib/stormpath-sdk/provider/facebook/facebook_provider.rb +6 -2
  36. data/lib/stormpath-sdk/provider/facebook/facebook_provider_data.rb +7 -3
  37. data/lib/stormpath-sdk/provider/github/github_provider.rb +6 -2
  38. data/lib/stormpath-sdk/provider/github/github_provider_data.rb +6 -2
  39. data/lib/stormpath-sdk/provider/google/google_provider.rb +7 -3
  40. data/lib/stormpath-sdk/provider/google/google_provider_data.rb +6 -2
  41. data/lib/stormpath-sdk/provider/linkedin/linkedin_provider.rb +6 -2
  42. data/lib/stormpath-sdk/provider/linkedin/linkedin_provider_data.rb +6 -2
  43. data/lib/stormpath-sdk/provider/provider.rb +8 -4
  44. data/lib/stormpath-sdk/provider/provider_data.rb +6 -2
  45. data/lib/stormpath-sdk/provider/saml/saml_provider.rb +10 -4
  46. data/lib/stormpath-sdk/provider/saml/saml_provider_data.rb +6 -3
  47. data/lib/stormpath-sdk/provider/stormpath/stormpath_provider.rb +6 -2
  48. data/lib/stormpath-sdk/provider/stormpath/stormpath_provider_data.rb +6 -2
  49. data/lib/stormpath-sdk/provider/twitter/twitter_provider.rb +6 -2
  50. data/lib/stormpath-sdk/provider/twitter/twitter_provider_data.rb +6 -2
  51. data/lib/stormpath-sdk/resource/account.rb +46 -40
  52. data/lib/stormpath-sdk/resource/account_link.rb +9 -5
  53. data/lib/stormpath-sdk/resource/account_linking_policy.rb +8 -4
  54. data/lib/stormpath-sdk/resource/account_membership.rb +1 -1
  55. data/lib/stormpath-sdk/resource/account_overrides.rb +20 -16
  56. data/lib/stormpath-sdk/resource/account_store.rb +15 -11
  57. data/lib/stormpath-sdk/resource/account_store_mapping.rb +14 -13
  58. data/lib/stormpath-sdk/resource/application.rb +147 -136
  59. data/lib/stormpath-sdk/resource/application_web_config.rb +11 -7
  60. data/lib/stormpath-sdk/resource/associations.rb +36 -43
  61. data/lib/stormpath-sdk/resource/attribute_statement_mapping_rules.rb +8 -0
  62. data/lib/stormpath-sdk/resource/base.rb +201 -200
  63. data/lib/stormpath-sdk/resource/challenge.rb +12 -8
  64. data/lib/stormpath-sdk/resource/collection.rb +77 -76
  65. data/lib/stormpath-sdk/resource/custom_data.rb +60 -61
  66. data/lib/stormpath-sdk/resource/custom_data_hash_methods.rb +28 -25
  67. data/lib/stormpath-sdk/resource/custom_data_storage.rb +18 -16
  68. data/lib/stormpath-sdk/resource/directory.rb +37 -60
  69. data/lib/stormpath-sdk/resource/email_verification_token.rb +7 -3
  70. data/lib/stormpath-sdk/resource/error.rb +8 -4
  71. data/lib/stormpath-sdk/resource/expansion.rb +22 -20
  72. data/lib/stormpath-sdk/resource/factor.rb +12 -8
  73. data/lib/stormpath-sdk/resource/field.rb +8 -4
  74. data/lib/stormpath-sdk/resource/group.rb +21 -16
  75. data/lib/stormpath-sdk/resource/group_membership.rb +7 -5
  76. data/lib/stormpath-sdk/resource/instance.rb +10 -6
  77. data/lib/stormpath-sdk/resource/linked_account.rb +7 -3
  78. data/lib/stormpath-sdk/resource/oauth_policy.rb +7 -3
  79. data/lib/stormpath-sdk/resource/organization.rb +14 -10
  80. data/lib/stormpath-sdk/resource/organization_account_store_mapping.rb +8 -4
  81. data/lib/stormpath-sdk/resource/password_reset_token.rb +9 -5
  82. data/lib/stormpath-sdk/resource/phone.rb +8 -4
  83. data/lib/stormpath-sdk/resource/registered_saml_service_provider.rb +8 -0
  84. data/lib/stormpath-sdk/resource/saml_identity_provider.rb +14 -0
  85. data/lib/stormpath-sdk/resource/saml_identity_provider_metadata.rb +9 -0
  86. data/lib/stormpath-sdk/resource/saml_policy.rb +10 -0
  87. data/lib/stormpath-sdk/resource/saml_service_provider.rb +7 -0
  88. data/lib/stormpath-sdk/{provider/saml/saml_mapping_rules.rb → resource/saml_service_provider_metadata.rb} +6 -5
  89. data/lib/stormpath-sdk/resource/saml_service_provider_registration.rb +11 -0
  90. data/lib/stormpath-sdk/resource/schema.rb +8 -4
  91. data/lib/stormpath-sdk/resource/tenant.rb +11 -8
  92. data/lib/stormpath-sdk/resource/user_info_mapping_rules.rb +7 -3
  93. data/lib/stormpath-sdk/resource/utils.rb +7 -10
  94. data/lib/stormpath-sdk/resource/verification_email.rb +7 -3
  95. data/lib/stormpath-sdk/resource/x_509_certificate.rb +7 -0
  96. data/lib/stormpath-sdk/util/assert.rb +1 -3
  97. data/lib/stormpath-sdk/version.rb +2 -2
  98. data/spec/auth/basic_authenticator_spec.rb +28 -24
  99. data/spec/auth/register_service_provider_spec.rb +68 -0
  100. data/spec/auth/sauthc1_signer_spec.rb +8 -4
  101. data/spec/cache/cache_entry_spec.rb +28 -29
  102. data/spec/cache/cache_spec.rb +9 -9
  103. data/spec/cache/cache_stats_spec.rb +1 -1
  104. data/spec/client_spec.rb +63 -63
  105. data/spec/data_store_spec.rb +23 -14
  106. data/spec/oauth/access_token_authentication_result_spec.rb +8 -2
  107. data/spec/provider/account_resolver_spec.rb +6 -4
  108. data/spec/provider/provider_spec.rb +6 -6
  109. data/spec/resource/account_creation_policy_spec.rb +1 -1
  110. data/spec/resource/account_link_spec.rb +7 -15
  111. data/spec/resource/account_spec.rb +17 -17
  112. data/spec/resource/account_store_mapping_spec.rb +16 -22
  113. data/spec/resource/account_store_spec.rb +3 -3
  114. data/spec/resource/application_spec.rb +324 -330
  115. data/spec/resource/base_spec.rb +7 -31
  116. data/spec/resource/collection_spec.rb +63 -114
  117. data/spec/resource/custom_data_spec.rb +1 -1
  118. data/spec/resource/directory_spec.rb +91 -87
  119. data/spec/resource/expansion_spec.rb +10 -10
  120. data/spec/resource/factor_spec.rb +1 -1
  121. data/spec/resource/group_spec.rb +1 -1
  122. data/spec/resource/linked_account_spec.rb +7 -7
  123. data/spec/resource/organization_spec.rb +12 -11
  124. data/spec/resource/phone_spec.rb +1 -1
  125. data/spec/resource/registered_saml_service_provider_spec.rb +35 -0
  126. data/spec/resource/saml_identity_provider_metadata_spec.rb +27 -0
  127. data/spec/resource/saml_identity_provider_spec.rb +94 -0
  128. data/spec/resource/saml_policy_spec.rb +27 -0
  129. data/spec/resource/saml_service_provider_registration_spec.rb +58 -0
  130. data/spec/resource/saml_service_provider_spec.rb +19 -0
  131. data/spec/resource/status_spec.rb +4 -3
  132. data/spec/resource/tenant_spec.rb +4 -6
  133. data/spec/spec_helper.rb +1 -1
  134. data/spec/support/custom_data_save_period.rb +4 -0
  135. data/spec/support/custom_data_storage_behavior.rb +7 -8
  136. data/spec/support/mocked_provider_accounts.rb +101 -101
  137. data/spec/support/mocked_saml_responses.rb +130 -0
  138. data/spec/support/resource_factory.rb +4 -4
  139. data/spec/support/resource_helpers.rb +10 -4
  140. data/spec/support/resource_matchers.rb +4 -4
  141. data/spec/support/test_request_executor.rb +2 -2
  142. metadata +21 -8
  143. data/lib/stormpath-sdk/provider/saml/saml_provider_metadata.rb +0 -19
  144. data/spec/fixtures/response/create_saml_directory.json +0 -26
  145. data/spec/fixtures/response/create_saml_directory_mapping_rules.json +0 -12
  146. data/spec/fixtures/response/get_saml_directory_provider.json +0 -16
  147. data/spec/fixtures/response/get_saml_directory_provider_metadata.json +0 -12
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2012 Stormpath, Inc.
2
+ # Copyright 2016 Stormpath, Inc.
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -13,14 +13,18 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
- class Stormpath::Resource::Challenge < Stormpath::Resource::Instance
17
- prop_accessor :message
18
- prop_reader :status, :created_at, :modified_at
16
+ module Stormpath
17
+ module Resource
18
+ class Challenge < Stormpath::Resource::Instance
19
+ prop_accessor :message
20
+ prop_reader :status, :created_at, :modified_at
19
21
 
20
- belongs_to :factor
21
- belongs_to :account
22
+ belongs_to :factor
23
+ belongs_to :account
22
24
 
23
- def validate(code)
24
- data_store.execute_raw_request href, { code: code }, Stormpath::Resource::Challenge
25
+ def validate(code)
26
+ data_store.execute_raw_request(href, { code: code }, Stormpath::Resource::Challenge)
27
+ end
28
+ end
25
29
  end
26
30
  end
@@ -13,101 +13,102 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
- class Stormpath::Resource::Collection
17
- include Enumerable
18
-
19
- attr_reader :href, :client, :item_class, :collection_href, :criteria
20
-
21
- def initialize(href, item_class, client, options={})
22
- @client = client
23
- @href = href
24
- @item_class = item_class
25
- @collection_href = options[:collection_href] || @href
26
- @criteria ||= {}
27
- end
28
-
29
- def data_store
30
- client.data_store
31
- end
16
+ module Stormpath
17
+ module Resource
18
+ class Collection
19
+ include Enumerable
20
+
21
+ attr_reader :href, :client, :item_class, :collection_href, :criteria
22
+
23
+ def initialize(href, item_class, client, options = {})
24
+ @client = client
25
+ @href = href
26
+ @item_class = item_class
27
+ @collection_href = options[:collection_href] || @href
28
+ @criteria ||= {}
29
+ end
32
30
 
33
- def search query
34
- query_hash = if query.is_a? String
35
- { q: query }
36
- elsif query.is_a? Hash
37
- query
38
- end
31
+ def data_store
32
+ client.data_store
33
+ end
39
34
 
40
- criteria.merge! query_hash
41
- self
42
- end
35
+ def search(query)
36
+ query_hash = if query.is_a? String
37
+ { q: query }
38
+ elsif query.is_a? Hash
39
+ query
40
+ end
43
41
 
44
- def offset offset
45
- criteria.merge! offset: offset
46
- self
47
- end
42
+ criteria.merge! query_hash
43
+ self
44
+ end
48
45
 
49
- def limit limit
50
- criteria.merge! limit: limit
51
- self
52
- end
46
+ def offset(offset)
47
+ criteria[:offset] = offset
48
+ self
49
+ end
53
50
 
54
- def order statement
55
- criteria.merge! order_by: statement
56
- self
57
- end
51
+ def limit(limit)
52
+ criteria[:limit] = limit
53
+ self
54
+ end
58
55
 
59
- def each(&block)
60
- PaginatedIterator.iterate(collection_href, client, item_class, @criteria, &block)
61
- end
56
+ def order(statement)
57
+ criteria[:order_by] = statement
58
+ self
59
+ end
62
60
 
63
- def current_page
64
- page = CollectionPage.new(collection_href, client, criteria)
65
- page.item_type = item_class
66
- page
67
- end
61
+ def each(&block)
62
+ PaginatedIterator.iterate(collection_href, client, item_class, @criteria, &block)
63
+ end
68
64
 
69
- private
65
+ def current_page
66
+ page = CollectionPage.new(collection_href, client, criteria)
67
+ page.item_type = item_class
68
+ page
69
+ end
70
70
 
71
- module PaginatedIterator
71
+ private
72
72
 
73
- def self.iterate(collection_href, client, item_class, criteria, &block)
74
- page = CollectionPage.new collection_href, client, criteria
75
- page.item_type = item_class
73
+ module PaginatedIterator
74
+ def self.iterate(collection_href, client, item_class, criteria, &block)
75
+ page = CollectionPage.new(collection_href, client, criteria)
76
+ page.item_type = item_class
76
77
 
77
- unless page.items.count.zero?
78
- page.items.each(&block)
79
- criteria[:offset] = page.offset + page.limit
80
- iterate(collection_href, client, item_class, criteria, &block)
78
+ unless page.items.count.zero?
79
+ page.items.each(&block)
80
+ criteria[:offset] = page.offset + page.limit
81
+ iterate(collection_href, client, item_class, criteria, &block)
82
+ end
81
83
  end
82
84
  end
83
- end
84
85
 
85
- class CollectionPage < Stormpath::Resource::Base
86
- ITEMS = 'items'
86
+ class CollectionPage < Stormpath::Resource::Base
87
+ ITEMS = 'items'.freeze
87
88
 
88
- prop_accessor :offset, :limit, :size
89
+ prop_accessor :offset, :limit, :size
89
90
 
90
- attr_accessor :item_type
91
+ attr_accessor :item_type
91
92
 
92
- def items
93
- to_resource_array get_property(ITEMS)
94
- end
93
+ def items
94
+ to_resource_array(get_property(ITEMS))
95
+ end
95
96
 
96
- def to_resource properties
97
- data_store.instantiate item_type, properties
98
- end
97
+ def to_resource(properties)
98
+ data_store.instantiate(item_type, properties)
99
+ end
99
100
 
100
- def to_resource_array vals
101
- Array.new.tap do |items|
102
- if vals.is_a? Array
103
- vals.each do |val|
104
- resource = to_resource val
105
- items << resource
101
+ def to_resource_array(vals)
102
+ [].tap do |items|
103
+ if vals.is_a? Array
104
+ vals.each do |val|
105
+ resource = to_resource val
106
+ items << resource
107
+ end
106
108
  end
107
109
  end
108
110
  end
109
- end
110
-
111
- end#class Stormpath::Resource::Collection::CollectionPage
112
-
113
- end#Stormpath::Resource::Collection
111
+ end # class Stormpath::Resource::Collection::CollectionPage
112
+ end # Stormpath::Resource::Collection
113
+ end
114
+ end
@@ -13,82 +13,81 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
- class Stormpath::Resource::CustomData < Stormpath::Resource::Instance
17
- include Stormpath::Resource::CustomDataHashMethods
16
+ module Stormpath
17
+ module Resource
18
+ class CustomData < Stormpath::Resource::Instance
19
+ include Stormpath::Resource::CustomDataHashMethods
18
20
 
19
- prop_reader :created_at, :modified_at
21
+ prop_reader :created_at, :modified_at
20
22
 
21
- def [](property_name)
22
- get_property property_name, ignore_camelcasing: true
23
- end
23
+ def [](property_name)
24
+ get_property property_name, ignore_camelcasing: true
25
+ end
24
26
 
25
- def []=(property_name, property_value)
26
- set_property property_name, property_value, ignore_camelcasing: true
27
- end
27
+ def []=(property_name, property_value)
28
+ set_property property_name, property_value, ignore_camelcasing: true
29
+ end
28
30
 
29
- def save
30
- if has_removed_properties?
31
- delete_removed_properties
32
- end
33
- if has_new_properties?
34
- super
35
- end
36
- end
31
+ def save
32
+ delete_removed_properties if has_removed_properties?
33
+ super if has_new_properties?
34
+ end
37
35
 
38
- def delete(name = nil)
39
- if name.nil?
40
- @properties = { HREF_PROP_NAME => @properties[HREF_PROP_NAME] }
41
- @dirty_properties.clear
42
- @deleted_properties.clear
43
- return super()
44
- end
36
+ def delete(name = nil)
37
+ if name.nil?
38
+ @properties = { HREF_PROP_NAME => @properties[HREF_PROP_NAME] }
39
+ @dirty_properties.clear
40
+ @deleted_properties.clear
41
+ return super()
42
+ end
45
43
 
46
- @write_lock.lock
47
- property_name = name.to_s
48
- begin
49
- @properties.delete(property_name)
50
- @dirty_properties.delete(property_name)
51
- @deleted_properties << property_name
52
- @dirty = true
53
- ensure
54
- @write_lock.unlock
55
- end
56
- end
44
+ @write_lock.lock
45
+ property_name = name.to_s
46
+ begin
47
+ @properties.delete(property_name)
48
+ @dirty_properties.delete(property_name)
49
+ @deleted_properties << property_name
50
+ @dirty = true
51
+ ensure
52
+ @write_lock.unlock
53
+ end
54
+ end
57
55
 
58
- private
56
+ private
59
57
 
60
- def sanitize(properties)
61
- {}.tap do |sanitized_properties|
62
- properties.map do |key, value|
63
- property_name = key.to_s
64
- sanitized_properties[property_name] = value
58
+ def sanitize(properties)
59
+ {}.tap do |sanitized_properties|
60
+ properties.map do |key, value|
61
+ property_name = key.to_s
62
+ sanitized_properties[property_name] = value
63
+ end
65
64
  end
66
65
  end
67
- end
68
66
 
69
- def has_removed_properties?
70
- @read_lock.lock
71
- begin
72
- !@deleted_properties.empty?
73
- ensure
74
- @read_lock.unlock
67
+ def has_removed_properties?
68
+ @read_lock.lock
69
+ begin
70
+ !@deleted_properties.empty?
71
+ ensure
72
+ @read_lock.unlock
73
+ end
75
74
  end
76
- end
77
75
 
78
- def has_new_properties?
79
- @read_lock.lock
80
- begin
81
- !@dirty_properties.empty?
82
- ensure
83
- @read_lock.unlock
76
+ def has_new_properties?
77
+ @read_lock.lock
78
+ begin
79
+ !@dirty_properties.empty?
80
+ ensure
81
+ @read_lock.unlock
82
+ end
84
83
  end
85
- end
86
84
 
87
- def delete_removed_properties
88
- @deleted_properties.delete_if do |deleted_property_name|
89
- data_store.delete self, deleted_property_name
90
- true
85
+ def delete_removed_properties
86
+ @deleted_properties.delete_if do |deleted_property_name|
87
+ data_store.delete(self, deleted_property_name)
88
+ true
89
+ end
91
90
  end
92
91
  end
93
-
92
+ end
94
93
  end
@@ -1,33 +1,36 @@
1
- module Stormpath::Resource::CustomDataHashMethods
2
- extend ActiveSupport::Concern
1
+ module Stormpath
2
+ module Resource
3
+ module CustomDataHashMethods
4
+ extend ActiveSupport::Concern
3
5
 
4
- included do
5
- def has_key?(key)
6
- materialize unless materialized?
7
- properties.has_key? key.to_s
8
- end
6
+ included do
7
+ def has_key?(key)
8
+ materialize unless materialized?
9
+ properties.key? key.to_s
10
+ end
9
11
 
10
- alias_method :include?, :has_key?
12
+ alias_method :include?, :has_key?
11
13
 
12
- def has_value?(value)
13
- materialize unless materialized?
14
- properties.has_value? value
15
- end
14
+ def has_value?(value)
15
+ materialize unless materialized?
16
+ properties.value? value
17
+ end
16
18
 
17
- def store(key, value)
18
- materialize unless materialized?
19
- self[key] = value
20
- end
19
+ def store(key, value)
20
+ materialize unless materialized?
21
+ self[key] = value
22
+ end
21
23
 
22
- def keys
23
- materialize unless materialized?
24
- properties.keys
25
- end
24
+ def keys
25
+ materialize unless materialized?
26
+ properties.keys
27
+ end
26
28
 
27
- def values
28
- materialize unless materialized?
29
- properties.values
29
+ def values
30
+ materialize unless materialized?
31
+ properties.values
32
+ end
33
+ end
30
34
  end
31
35
  end
32
-
33
- end
36
+ end
@@ -13,27 +13,29 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
- module Stormpath::Resource::CustomDataStorage
17
- extend ActiveSupport::Concern
16
+ module Stormpath
17
+ module Resource
18
+ module CustomDataStorage
19
+ extend ActiveSupport::Concern
18
20
 
19
- CUSTOM_DATA = "custom_data"
21
+ CUSTOM_DATA = 'custom_data'.freeze
20
22
 
21
- included do
23
+ included do
24
+ def save
25
+ apply_custom_data_updates_if_necessary
26
+ super
27
+ end
22
28
 
23
- def save
24
- apply_custom_data_updates_if_necessary
25
- super
26
- end
29
+ def apply_custom_data_updates_if_necessary
30
+ if custom_data.send(:has_removed_properties?)
31
+ custom_data.send(:delete_removed_properties)
32
+ end
27
33
 
28
- def apply_custom_data_updates_if_necessary
29
- if custom_data.send :has_removed_properties?
30
- custom_data.send :delete_removed_properties
31
- end
32
- if custom_data.send :has_new_properties?
33
- self.set_property CUSTOM_DATA, custom_data.dirty_properties
34
+ if custom_data.send(:has_new_properties?)
35
+ set_property(CUSTOM_DATA, custom_data.dirty_properties)
36
+ end
37
+ end
34
38
  end
35
39
  end
36
-
37
40
  end
38
-
39
41
  end