stormpath-rails 1.1.2.beta → 2.0.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 (130) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rspec +1 -1
  4. data/.rubocop.yml +22 -0
  5. data/.travis.yml +6 -3
  6. data/Gemfile +10 -3
  7. data/README.md +139 -142
  8. data/Rakefile +9 -9
  9. data/app/assets/stylesheets/stormpath.css.scss +3 -2
  10. data/app/controllers/stormpath/rails/base_controller.rb +25 -6
  11. data/app/controllers/stormpath/rails/change_password/create_controller.rb +68 -0
  12. data/app/controllers/stormpath/rails/change_password/new_controller.rb +38 -0
  13. data/app/controllers/stormpath/rails/forgot_password/create_controller.rb +37 -0
  14. data/app/controllers/stormpath/rails/forgot_password/new_controller.rb +14 -0
  15. data/app/controllers/stormpath/rails/login/create_controller.rb +60 -0
  16. data/app/controllers/stormpath/rails/login/new_controller.rb +20 -0
  17. data/app/controllers/stormpath/rails/logout/create_controller.rb +61 -0
  18. data/app/controllers/stormpath/rails/oauth2/create_controller.rb +82 -0
  19. data/app/controllers/stormpath/rails/oauth2/new_controller.rb +11 -0
  20. data/app/controllers/stormpath/rails/profile/show_controller.rb +15 -0
  21. data/app/controllers/stormpath/rails/register/create_controller.rb +86 -0
  22. data/app/controllers/stormpath/rails/register/new_controller.rb +20 -0
  23. data/app/controllers/stormpath/rails/verify_email/create_controller.rb +37 -0
  24. data/app/controllers/stormpath/rails/verify_email/show_controller.rb +51 -0
  25. data/app/forms/stormpath/rails/login_form.rb +60 -0
  26. data/app/forms/stormpath/rails/registration_form.rb +106 -0
  27. data/app/forms/stormpath/rails/registration_form_fields.rb +71 -0
  28. data/app/helpers/social_helper.rb +2 -1
  29. data/app/serializers/stormpath/rails/account_serializer.rb +32 -0
  30. data/app/serializers/stormpath/rails/form_serializer.rb +37 -0
  31. data/app/serializers/stormpath/rails/login_new_serializer.rb +11 -0
  32. data/app/serializers/stormpath/rails/profile_serializer.rb +71 -0
  33. data/app/serializers/stormpath/rails/registration_form_serializer.rb +11 -0
  34. data/app/services/stormpath/rails/account_from_access_token/local_account_resolution.rb +48 -0
  35. data/app/services/stormpath/rails/account_from_access_token/stormpath_account_resolution.rb +27 -0
  36. data/app/services/stormpath/rails/account_from_access_token.rb +33 -0
  37. data/app/services/stormpath/rails/account_login.rb +28 -0
  38. data/app/services/stormpath/rails/account_login_with_stormpath_token.rb +32 -0
  39. data/app/services/stormpath/rails/client_credentials_authentication.rb +40 -0
  40. data/app/services/stormpath/rails/controller_authentication/from_basic_auth.rb +45 -0
  41. data/app/services/stormpath/rails/controller_authentication/from_bearer_auth.rb +34 -0
  42. data/app/services/stormpath/rails/controller_authentication/from_cookies.rb +71 -0
  43. data/app/services/stormpath/rails/controller_authentication.rb +44 -0
  44. data/app/services/stormpath/rails/delete_access_token.rb +48 -0
  45. data/app/services/stormpath/rails/delete_refresh_token.rb +11 -0
  46. data/app/services/stormpath/rails/forgot_password_token_verification.rb +31 -0
  47. data/app/services/stormpath/rails/password_change.rb +17 -0
  48. data/app/services/stormpath/rails/refresh_token_authentication.rb +28 -0
  49. data/app/services/stormpath/rails/resend_email_verification.rb +33 -0
  50. data/app/services/stormpath/rails/send_password_reset_email.rb +33 -0
  51. data/app/services/stormpath/rails/token_cookie_setter.rb +84 -0
  52. data/app/services/stormpath/rails/verify_email_token.rb +27 -0
  53. data/app/views/{passwords/forgot_change.html.erb → stormpath/rails/change_password/new.html.erb} +4 -10
  54. data/app/views/{passwords/forgot.html.erb → stormpath/rails/forgot_password/new.html.erb} +14 -4
  55. data/app/views/{layouts → stormpath/rails/layouts}/stormpath.html.erb +3 -3
  56. data/app/views/stormpath/rails/login/_form.html.erb +45 -0
  57. data/app/views/stormpath/rails/login/new.html.erb +12 -0
  58. data/app/views/stormpath/rails/register/_form.html.erb +19 -0
  59. data/app/views/{users → stormpath/rails/register}/new.html.erb +3 -3
  60. data/app/views/stormpath/rails/shared/_input.html.erb +15 -0
  61. data/app/views/stormpath/rails/verify_email/new.html.erb +49 -0
  62. data/bin/console +3 -3
  63. data/bin/rails +1 -1
  64. data/bin/rake +2 -2
  65. data/bin/rspec +2 -2
  66. data/config/initializers/assets.rb +3 -1
  67. data/lib/generators/stormpath/install/install_generator.rb +1 -92
  68. data/lib/generators/stormpath/install/templates/default_config.yml +229 -0
  69. data/lib/generators/stormpath/views/USAGE +0 -0
  70. data/lib/generators/stormpath/views/views_generator.rb +2 -2
  71. data/lib/stormpath/rails/client.rb +8 -85
  72. data/lib/stormpath/rails/config/account_store_verification.rb +45 -0
  73. data/lib/stormpath/rails/config/application_resolution.rb +76 -0
  74. data/lib/stormpath/rails/config/dynamic_configuration.rb +50 -0
  75. data/lib/stormpath/rails/config/read_file.rb +35 -0
  76. data/lib/stormpath/rails/configuration.rb +30 -35
  77. data/lib/stormpath/rails/content_type_negotiator.rb +50 -0
  78. data/lib/stormpath/rails/controller.rb +36 -5
  79. data/lib/stormpath/rails/errors/invalid_sptoken_error.rb +9 -0
  80. data/lib/stormpath/rails/errors/no_sptoken_error.rb +13 -0
  81. data/lib/stormpath/rails/router.rb +75 -0
  82. data/lib/stormpath/rails/routing_constraint.rb +9 -0
  83. data/lib/stormpath/rails/social.rb +6 -6
  84. data/lib/stormpath/rails/version.rb +2 -1
  85. data/lib/stormpath/rails.rb +9 -19
  86. data/lib/stormpath-rails.rb +1 -0
  87. data/stormpath-rails.gemspec +13 -11
  88. metadata +96 -54
  89. data/app/controllers/stormpath/rails/omniauth_controller.rb +0 -11
  90. data/app/controllers/stormpath/rails/passwords_controller.rb +0 -56
  91. data/app/controllers/stormpath/rails/sessions_controller.rb +0 -52
  92. data/app/controllers/stormpath/rails/users_controller.rb +0 -65
  93. data/app/views/passwords/edit.html.erb +0 -0
  94. data/app/views/passwords/email_sent.html.erb +0 -15
  95. data/app/views/passwords/forgot_change_failed.html.erb +0 -14
  96. data/app/views/passwords/forgot_complete.html.erb +0 -19
  97. data/app/views/sessions/_facebook_login_form.erb +0 -31
  98. data/app/views/sessions/_form.html.erb +0 -31
  99. data/app/views/sessions/_google_login_form.html.erb +0 -3
  100. data/app/views/sessions/_social_auth.html.erb +0 -7
  101. data/app/views/sessions/new.html.erb +0 -21
  102. data/app/views/users/_form.html.erb +0 -43
  103. data/app/views/users/verification_complete.html.erb +0 -20
  104. data/app/views/users/verification_email_sent.html.erb +0 -15
  105. data/app/views/users/verification_failed.html.erb +0 -14
  106. data/app/views/users/verification_resend.html.erb +0 -14
  107. data/config/routes.rb +0 -16
  108. data/lib/generators/stormpath/install/templates/db/migrate/add_stormpath_to_users.rb +0 -21
  109. data/lib/generators/stormpath/install/templates/db/migrate/create_users.rb +0 -12
  110. data/lib/generators/stormpath/install/templates/stormpath.rb +0 -4
  111. data/lib/generators/stormpath/install/templates/user.rb +0 -3
  112. data/lib/generators/stormpath/routes/routes_generator.rb +0 -23
  113. data/lib/generators/stormpath/routes/templates/routes.rb +0 -5
  114. data/lib/stormpath/rails/account.rb +0 -6
  115. data/lib/stormpath/rails/account_status.rb +0 -28
  116. data/lib/stormpath/rails/authentication.rb +0 -72
  117. data/lib/stormpath/rails/authentication_status.rb +0 -22
  118. data/lib/stormpath/rails/session.rb +0 -37
  119. data/lib/stormpath/rails/user.rb +0 -25
  120. data/lib/stormpath/rails/user_config/api_key.rb +0 -17
  121. data/lib/stormpath/rails/user_config/application.rb +0 -12
  122. data/lib/stormpath/rails/user_config/facebook.rb +0 -16
  123. data/lib/stormpath/rails/user_config/forgot_password.rb +0 -12
  124. data/lib/stormpath/rails/user_config/google.rb +0 -16
  125. data/lib/stormpath/rails/user_config/id_site.rb +0 -13
  126. data/lib/stormpath/rails/user_config/login.rb +0 -13
  127. data/lib/stormpath/rails/user_config/logout.rb +0 -13
  128. data/lib/stormpath/rails/user_config/register.rb +0 -13
  129. data/lib/stormpath/rails/user_config/verify_email.rb +0 -14
  130. data/lib/stormpath/testing/helpers.rb +0 -49
@@ -8,7 +8,7 @@ module Stormpath
8
8
  source_root File.expand_path('../templates', __FILE__)
9
9
 
10
10
  def create_stormpath_configuration_file
11
- copy_file 'stormpath.rb', 'config/initializers/stormpath.rb'
11
+ copy_file 'default_config.yml', 'config/stormpath.yml'
12
12
  end
13
13
 
14
14
  def inject_stormpath_into_application_controller
@@ -18,97 +18,6 @@ module Stormpath
18
18
  " include Stormpath::Rails::Controller\n"
19
19
  )
20
20
  end
21
-
22
- def create_user_model
23
- if File.exist?(destination_root + '/app/models/user.rb')
24
- inject_into_file(
25
- 'app/models/user.rb',
26
- "include Stormpath::Rails::User\n\n",
27
- after: "class User < ActiveRecord::Base\n"
28
- )
29
- else
30
- copy_file 'user.rb', 'app/models/user.rb'
31
- end
32
- end
33
-
34
- def create_stormpath_migration
35
- if user_table_exists?
36
- create_add_columns_migration
37
- else
38
- copy_migration 'create_users.rb'
39
- end
40
- end
41
-
42
- private
43
-
44
- def create_add_columns_migration
45
- return unless migration_needed?
46
-
47
- config = {
48
- new_columns: new_columns,
49
- new_indexes: new_indexes
50
- }
51
-
52
- copy_migration('add_stormpath_to_users.rb', config)
53
- end
54
-
55
- def migration_needed?
56
- new_columns.any? || new_indexes.any?
57
- end
58
-
59
- def new_columns
60
- @new_columns ||= {
61
- email: 't.string :email, null: false',
62
- given_name: 't.string :given_name, null: false',
63
- surname: 't.string :surname, null: false'
64
- }.reject { |column| existing_users_columns.include?(column.to_s) }
65
- end
66
-
67
- def new_indexes
68
- @new_indexes ||= {
69
- index_users_on_email: 'add_index :users, :email'
70
- }.reject { |index| existing_users_indexes.include?(index.to_s) }
71
- end
72
-
73
- def user_table_exists?
74
- ActiveRecord::Base.connection.table_exists?(:users)
75
- end
76
-
77
- def copy_migration(migration_name, config = {})
78
- return if migration_exists?(migration_name)
79
- migration_template(
80
- "db/migrate/#{migration_name}",
81
- "db/migrate/#{migration_name}",
82
- config
83
- )
84
- end
85
-
86
- def migration_exists?(name)
87
- existing_migrations.include?(name)
88
- end
89
-
90
- def existing_migrations
91
- @existing_migrations ||= Dir.glob('db/migrate/*.rb').map do |file|
92
- migration_name_without_timestamp(file)
93
- end
94
- end
95
-
96
- def migration_name_without_timestamp(file)
97
- file.sub(%r{^.*(db/migrate/)(?:\d+_)?}, '')
98
- end
99
-
100
- # for generating a timestamp when using `create_migration`
101
- def self.next_migration_number(dir)
102
- ActiveRecord::Generators::Base.next_migration_number(dir)
103
- end
104
-
105
- def existing_users_columns
106
- ActiveRecord::Base.connection.columns(:users).map(&:name)
107
- end
108
-
109
- def existing_users_indexes
110
- ActiveRecord::Base.connection.indexes(:users).map(&:name)
111
- end
112
21
  end
113
22
  end
114
23
  end
@@ -0,0 +1,229 @@
1
+ stormpath:
2
+ application:
3
+ href: null
4
+ name: null
5
+
6
+ web:
7
+ basePath: null
8
+
9
+ oauth2:
10
+ enabled: true
11
+ uri: "/oauth/token"
12
+ client_credentials:
13
+ enabled: true
14
+ accessToken:
15
+ ttl: 3600 # seconds
16
+ password:
17
+ enabled: true
18
+ validationStrategy: "local"
19
+
20
+ accessTokenCookie:
21
+ name: "access_token"
22
+ httpOnly: true
23
+
24
+ # See cookie-authentication.md for explanation of
25
+ # how `null` values behave for these properties.
26
+ secure: null
27
+ path: null
28
+ domain: null
29
+
30
+ refreshTokenCookie:
31
+ name: "refresh_token"
32
+ httpOnly: true
33
+
34
+ # See cookie-authentication.md for explanation of
35
+ # how `null` values behave for these properties.
36
+ secure: null
37
+ path: null
38
+ domain: null
39
+
40
+ # By default the Stormpath integration will respond to JSON and HTML
41
+ # requests. If a requested type is not in this list, the Stormpath
42
+ # integration should pass on the request, and allow the developer or base
43
+ # framework to handle the response.
44
+ #
45
+ # If the request does not specify an Accept header, or the preferred content
46
+ # type is */*, the Stormpath integration will respond with the first type in
47
+ # this list.
48
+ produces:
49
+ - application/json
50
+ - text/html
51
+
52
+ register:
53
+ enabled: true
54
+ uri: "/register"
55
+ nextUri: "/"
56
+ autoLogin: false
57
+ form:
58
+ fields:
59
+ givenName:
60
+ enabled: true
61
+ visible: true
62
+ label: "First Name"
63
+ placeholder: "First Name"
64
+ required: true
65
+ type: "text"
66
+ middleName:
67
+ enabled: false
68
+ visible: true
69
+ label: "Middle Name"
70
+ placeholder: "Middle Name"
71
+ required: true
72
+ type: "text"
73
+ surname:
74
+ enabled: true
75
+ visible: true
76
+ label: "Last Name"
77
+ placeholder: "Last Name"
78
+ required: true
79
+ type: "text"
80
+ username:
81
+ enabled: false
82
+ visible: true
83
+ label: "Username"
84
+ placeholder: "Username"
85
+ required: true
86
+ type: "text"
87
+ email:
88
+ enabled: true
89
+ visible: true
90
+ label: "Email"
91
+ placeholder: "Email"
92
+ required: true
93
+ type: "email"
94
+ password:
95
+ enabled: true
96
+ visible: true
97
+ label: "Password"
98
+ placeholder: "Password"
99
+ required: true
100
+ type: "password"
101
+ confirmPassword:
102
+ enabled: false
103
+ visible: true
104
+ label: "Confirm Password"
105
+ placeholder: "Confirm Password"
106
+ required: true
107
+ type: "password"
108
+ fieldOrder:
109
+ - "username"
110
+ - "givenName"
111
+ - "middleName"
112
+ - "surname"
113
+ - "email"
114
+ - "password"
115
+ - "confirmPassword"
116
+ view: "stormpath/rails/register/new"
117
+
118
+ # Unless verifyEmail.enabled is specifically set to false, the email
119
+ # verification feature must be automatically enabled if the default account
120
+ # store for the defined Stormpath application has the email verification
121
+ # workflow enabled.
122
+ verifyEmail:
123
+ enabled: null
124
+ uri: "/verify"
125
+ nextUri: "/login?status=verified"
126
+ view: "stormpath/rails/verify_email/new"
127
+
128
+ login:
129
+ enabled: true
130
+ uri: "/login"
131
+ nextUri: "/"
132
+ view: "stormpath/rails/login/new"
133
+ form:
134
+ fields:
135
+ login:
136
+ enabled: true
137
+ visible: true
138
+ label: "Username or Email"
139
+ placeholder: "Username or Email"
140
+ required: true
141
+ type: "text"
142
+ password:
143
+ enabled: true
144
+ visible: true
145
+ label: "Password"
146
+ placeholder: "Password"
147
+ required: true
148
+ type: "password"
149
+ fieldOrder:
150
+ - "login"
151
+ - "password"
152
+
153
+ logout:
154
+ enabled: true
155
+ uri: "/logout"
156
+ nextUri: "/"
157
+
158
+ # Unless forgotPassword.enabled is explicitly set to false, this feature
159
+ # will be automatically enabled if the default account store for the defined
160
+ # Stormpath application has the password reset workflow enabled.
161
+ forgotPassword:
162
+ enabled: null
163
+ uri: "/forgot"
164
+ view: "stormpath/rails/forgot_password/new"
165
+ nextUri: "/login?status=forgot"
166
+
167
+ # Unless changePassword.enabled is explicitly set to false, this feature
168
+ # will be automatically enabled if the default account store for the defined
169
+ # Stormpath application has the password reset workflow enabled.
170
+ changePassword:
171
+ enabled: null
172
+ autoLogin: false
173
+ uri: "/change"
174
+ nextUri: "/login?status=reset"
175
+ view: "stormpath/rails/change_password/new"
176
+ errorUri: "/forgot?status=invalid_sptoken"
177
+
178
+ # If idSite.enabled is true, the user should be redirected to ID site for
179
+ # login, registration, and password reset. They should also be redirected
180
+ # through ID Site on logout.
181
+ idSite:
182
+ enabled: false
183
+ loginUri: ""
184
+ forgotUri: "/#/forgot"
185
+ registerUri: "/#/register"
186
+
187
+ # A callback so Stormpath can pass information to the web application. This is
188
+ # currently being used for ID Site, but may be used in the future for SAML,
189
+ # Stormpath handled social login, webhooks, and other messages from Stormpath.
190
+ callback:
191
+ enabled: true
192
+ uri: "/stormpathCallback"
193
+
194
+ # Social login configuration. This defines the callback URIs for OAuth
195
+ # flows, and the scope that is requested of each provider. Some providers
196
+ # want space-separated scopes, some want comma-separated. As such, these
197
+ # string values should be passed directly, as defined.
198
+ #
199
+ # These settings have no affect if the application does not have an account
200
+ # store for the given provider.
201
+ social:
202
+ facebook:
203
+ uri: "/callbacks/facebook"
204
+ scope: "email"
205
+ github:
206
+ uri: "/callbacks/github"
207
+ scope: "user:email"
208
+ google:
209
+ uri: "/callbacks/google"
210
+ scope: "email profile"
211
+ linkedin:
212
+ uri: "/callbacks/linkedin"
213
+ scope: "r_basicprofile r_emailaddress"
214
+
215
+ # The /me route is for front-end applications, it returns a JSON object with
216
+ # the current user object. The developer can opt-in to expanding account
217
+ # resources on this enpdoint.
218
+ me:
219
+ enabled: true
220
+ uri: "/me"
221
+ expand:
222
+ apiKeys: false
223
+ applications: false
224
+ customData: false
225
+ directory: false
226
+ groupMemberships: false
227
+ groups: false
228
+ providerData: false
229
+ tenant: false
File without changes
@@ -14,7 +14,7 @@ module Stormpath
14
14
  private
15
15
 
16
16
  def views
17
- files_within_root('.', 'app/views/**/*.*')
17
+ files_within_root('.', 'app/views/stormpath/rails/**/*.*')
18
18
  end
19
19
 
20
20
  def files_within_root(prefix, glob)
@@ -26,4 +26,4 @@ module Stormpath
26
26
  end
27
27
  end
28
28
  end
29
- end
29
+ end
@@ -5,46 +5,6 @@ module Stormpath
5
5
  attr_accessor :connection
6
6
  end
7
7
 
8
- def self.create_stormpath_account(user)
9
- begin
10
- result = application.accounts.create build_account(user)
11
- rescue Stormpath::Error => error
12
- result = error.message
13
- end
14
-
15
- AccountStatus.new(result)
16
- end
17
-
18
- def self.authenticate(user)
19
- begin
20
- result = application.authenticate_account build_username_password_request(user)
21
- rescue Stormpath::Error => error
22
- result = error.message
23
- end
24
-
25
- AuthenticationStatus.new(result)
26
- end
27
-
28
- def self.reset_password(email)
29
- begin
30
- result = application.send_password_reset_email email
31
- rescue Stormpath::Error => error
32
- result = error.message
33
- end
34
-
35
- AccountStatus.new(result)
36
- end
37
-
38
- def self.verify_email_token(token)
39
- begin
40
- result = client.accounts.verify_email_token token
41
- rescue Stormpath::Error => error
42
- result = error.message
43
- end
44
-
45
- AccountStatus.new(result)
46
- end
47
-
48
8
  def self.handle_id_site_callback(url)
49
9
  response = application.handle_id_site_callback(url)
50
10
  client.accounts.get response.account_href
@@ -54,59 +14,22 @@ module Stormpath
54
14
  application.create_id_site_url callback_uri: options[:callback_uri], path: options[:path]
55
15
  end
56
16
 
57
- def self.account_params(user)
58
- account_params = user.attributes.select do |k, v|
59
- %W[given_name surname email username password].include?(k) && !v.nil?
60
- end
61
-
62
- account_params.merge!("password" => user.password) unless user.password.blank?
63
- end
64
-
65
- def self.update_password(account, password)
66
- begin
67
- account = client.accounts.get account
68
- account.password = password
69
- result = account.save
70
- rescue Stormpath::Error => error
71
- result = error.message
72
- end
73
-
74
- AccountStatus.new(result)
75
- end
76
-
77
17
  def self.create_omniauth_user(provider, access_token)
78
18
  request = Stormpath::Provider::AccountRequest.new(provider, :access_token, access_token)
79
19
  application.get_provider_account(request)
80
- end
20
+ end
81
21
 
82
22
  def self.application
83
- self.client.applications.get Stormpath::Rails.config.application.href
23
+ client.applications.get Stormpath::Rails.config.application.href
84
24
  end
85
25
 
86
26
  def self.client
87
- self.connection ||= Stormpath::Client.new(client_options)
88
- end
89
-
90
- def self.client_options
91
- if Stormpath::Rails.config.api_key.file_location_provided?
92
- Hash.new.tap { |options| options[:api_key_file_location] = Stormpath::Rails.config.api_key.file }
93
- else
94
- Hash.new.tap do |options|
95
- options[:api_key] = {}
96
- options[:api_key][:id] = Stormpath::Rails.config.api_key.id
97
- options[:api_key][:secret] = Stormpath::Rails.config.api_key.secret
98
- end
99
- end
100
- end
101
-
102
- private
103
-
104
- def self.build_username_password_request(user)
105
- Stormpath::Authentication::UsernamePasswordRequest.new user.email, user.password
106
- end
107
-
108
- def self.build_account(user)
109
- Stormpath::Resource::Account.new account_params(user)
27
+ self.connection ||= Stormpath::Client.new(
28
+ api_key: {
29
+ id: ENV['STORMPATH_API_KEY_ID'],
30
+ secret: ENV['STORMPATH_API_KEY_SECRET']
31
+ }
32
+ )
110
33
  end
111
34
  end
112
35
  end
@@ -0,0 +1,45 @@
1
+ module Stormpath
2
+ module Rails
3
+ module Config
4
+ class AccountStoreVerification
5
+ attr_reader :app, :register_is_enabled
6
+
7
+ def initialize(app_href, register_is_enabled)
8
+ @app = Stormpath::Rails::Client.client.applications.get(app_href)
9
+ @register_is_enabled = register_is_enabled
10
+ end
11
+
12
+ def call
13
+ verify_there_are_any_account_store_mappings
14
+ verify_there_is_a_default_account_store if register_is_enabled
15
+ end
16
+
17
+ private
18
+
19
+ def verify_there_are_any_account_store_mappings
20
+ return if app_has_account_store_mappings?
21
+ raise(
22
+ InvalidConfiguration,
23
+ 'No account stores are mapped to the specified application. Account stores are required for login and registration.'
24
+ )
25
+ end
26
+
27
+ def verify_there_is_a_default_account_store
28
+ return if app_has_default_account_store_mapping?
29
+ raise(
30
+ InvalidConfiguration,
31
+ 'No default account store is mapped to the specified application. A default account store is required for registration.'
32
+ )
33
+ end
34
+
35
+ def app_has_account_store_mappings?
36
+ app.account_store_mappings.any?
37
+ end
38
+
39
+ def app_has_default_account_store_mapping?
40
+ app.default_account_store_mapping.present?
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,76 @@
1
+ module Stormpath
2
+ module Rails
3
+ module Config
4
+ class ApplicationResolution
5
+ attr_reader :href, :name
6
+
7
+ AUTOMATIC_RESOLUTION_ERROR_MESSAGE =
8
+ 'Could not automatically resolve a Stormpath Application. '\
9
+ 'Please specify your Stormpath Application in your configuration.'.freeze
10
+
11
+ def initialize(href, name)
12
+ @href = href
13
+ @name = name
14
+ end
15
+
16
+ def app
17
+ if href.present?
18
+ app_from_href
19
+ elsif name.present?
20
+ app_from_name
21
+ else
22
+ automatic_resolution
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def automatic_resolution
29
+ if client_has_exactly_two_applications?
30
+ client_applications.find { |app| app.name != 'Stormpath' }
31
+ else
32
+ raise(InvalidConfiguration, AUTOMATIC_RESOLUTION_ERROR_MESSAGE)
33
+ end
34
+ end
35
+
36
+ def client_has_exactly_two_applications?
37
+ client_applications.count == 2
38
+ end
39
+
40
+ def client_applications
41
+ Stormpath::Rails::Client.client.applications
42
+ end
43
+
44
+ def app_from_href
45
+ verify_application_href
46
+ begin
47
+ Stormpath::Rails::Client.client.applications.get(href)
48
+ rescue Stormpath::Error => error
49
+ raise if error.status != 404
50
+ raise(
51
+ InvalidConfiguration,
52
+ "The provided application could not be found. The provided application href was: #{href}"
53
+ )
54
+ end
55
+ end
56
+
57
+ def verify_application_href
58
+ if href && href !~ /applications/
59
+ raise(
60
+ InvalidConfiguration,
61
+ "#{href} is not a valid Stormpath Application href."
62
+ )
63
+ end
64
+ end
65
+
66
+ def app_from_name
67
+ application = Stormpath::Rails::Client.client.applications.search(name: name).first
68
+ application || raise(
69
+ InvalidConfiguration,
70
+ "The provided application could not be found. The provided application name was: #{name}"
71
+ )
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,50 @@
1
+ module Stormpath
2
+ module Rails
3
+ module Config
4
+ class DynamicConfiguration
5
+ attr_reader :static_config
6
+
7
+ def initialize(static_config)
8
+ @static_config = static_config
9
+ proccess_account_store_verification
10
+ end
11
+
12
+ def app
13
+ @app ||= Config::ApplicationResolution.new(
14
+ static_config.stormpath.application.href,
15
+ static_config.stormpath.application.name
16
+ ).app
17
+ end
18
+
19
+ def forgot_password_enabled?
20
+ return false if static_config.stormpath.web.forgot_password.enabled == false
21
+ password_reset_enabled?
22
+ end
23
+
24
+ def change_password_enabled?
25
+ return false if static_config.stormpath.web.change_password.enabled == false
26
+ password_reset_enabled?
27
+ end
28
+
29
+ private
30
+
31
+ def password_reset_enabled?
32
+ return false if default_account_store.nil?
33
+ default_account_store.password_policy.reset_email_status == 'ENABLED'
34
+ end
35
+
36
+ def default_account_store
37
+ @default_account_store ||=
38
+ app.default_account_store_mapping && app.default_account_store_mapping.account_store
39
+ end
40
+
41
+ def proccess_account_store_verification
42
+ AccountStoreVerification.new(
43
+ app.href,
44
+ static_config.stormpath.web.register.enabled
45
+ ).call
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,35 @@
1
+ module Stormpath
2
+ module Rails
3
+ module Config
4
+ class ReadFile
5
+ attr_reader :file_path
6
+
7
+ def initialize(file_path)
8
+ @file_path = file_path
9
+ end
10
+
11
+ def hash
12
+ @hash ||= snakecased_hash
13
+ end
14
+
15
+ private
16
+
17
+ def snakecased_hash
18
+ camelized_hash.deep_transform_keys(&:underscore)
19
+ end
20
+
21
+ def camelized_hash
22
+ YAML.load(evaluated_file)
23
+ end
24
+
25
+ def evaluated_file
26
+ ERB.new(file).result(binding)
27
+ end
28
+
29
+ def file
30
+ File.read(file_path)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end