stormpath-rails 0.4.4 → 1.0.0.beta
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.
- data/.gitignore +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +22 -3
- data/CHANGES.md +11 -0
- data/README.md +82 -24
- data/lib/stormpath/rails/account.rb +85 -30
- data/lib/stormpath/rails/client.rb +56 -27
- data/lib/stormpath/rails/railtie.rb +13 -0
- data/lib/stormpath/rails/version.rb +2 -1
- data/spec/client_spec.rb +222 -0
- data/spec/generators/migration_generator_spec.rb +1 -1
- data/spec/spec_helper.rb +91 -0
- data/spec/support/stormpath_account_shared_examples.rb +141 -49
- data/stormpath-rails.gemspec +14 -8
- metadata +98 -23
- data/lib/generators/stormpath/rails/install/install_generator.rb +0 -13
- data/lib/generators/stormpath/rails/templates/stormpath.yml +0 -11
- data/lib/stormpath/rails/config.rb +0 -14
- data/spec/fixtures/config/stormpath.yml +0 -12
- data/spec/generators/install_generator_spec.rb +0 -17
- data/spec/stormpath/rails/config_spec.rb +0 -41
- data/spec/support/rails.rb +0 -6
data/.gitignore
CHANGED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
stormpath-rails
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.9.3-p429
|
data/.travis.yml
CHANGED
@@ -1,8 +1,27 @@
|
|
1
|
+
---
|
1
2
|
language: ruby
|
2
3
|
rvm:
|
3
|
-
|
4
|
+
- 1.9.3
|
4
5
|
gemfile:
|
5
|
-
|
6
|
+
- Gemfile
|
6
7
|
script: bundle exec rake spec
|
7
8
|
services:
|
8
|
-
|
9
|
+
- mongodb
|
10
|
+
env:
|
11
|
+
global:
|
12
|
+
- secure: |-
|
13
|
+
TFLI7BpxBBSoVV5x/tyr1iCqcQHcbzJeQPSR67J32VWbMDjM3mA9mz4SERvK
|
14
|
+
j9VD7pEAknEBNpYUYdBR4Ut0m5/0F+XiX1eDOVMbfpmEefJ8e38CgGz7HZbu
|
15
|
+
KdaWJhxTL8k/efyvJ+/UVPyzM4M0ADdyZIoDCDgRhj6AG5DqDJs=
|
16
|
+
- secure: |-
|
17
|
+
eu8VkY1iR5RYHvOobDQ7Miz8aG894F/BR/zEH8c3gpIhs7kItkBy0SKEMi5J
|
18
|
+
A1yMlQsONU7aq6pbqiJEiBKSDWf9OOoFBxHYm46fop+xaLVLuuK484O9VzDW
|
19
|
+
P6lV6Z06LolZaZsc2ENKf+2qfoO1XdN9gMTWD7QkT4x6OgRWiok=
|
20
|
+
- secure: |-
|
21
|
+
fMUOQUfUNkEDWmx5d4vIMIbqTuHIX1lu1PmbUnR25hHN9JFZnroxSvsvUlvH
|
22
|
+
qB+GCk5q7kMuvqYC+Mbx0Ndb3NSuLSKYGYhHw/39ZyMPHgBhPKQyZuDiK3OJ
|
23
|
+
g3Pv8Ot3lScgATu1lm5EzoGfN3ZVlSgmg5PJOwsafVaRlAUaHz4=
|
24
|
+
- secure: |-
|
25
|
+
UDTunvFjUyTaLHPa3iNOVwdAg37FzfKHRYdOiUoPH3aNA6pOgrtQYzkbhbJA
|
26
|
+
chBcZBdD+SnEyY6PmI1NsLzcNrqBP3tdyH4c5vVy3KQAzc5TfU6RocWTrqRP
|
27
|
+
FQKm/r0cbpjdydkpEzOKMk77Y56g6MTEk5cGFZjYoqhGKdz66O0=
|
data/CHANGES.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
stormpath-rails Changelog
|
2
|
+
=========================
|
3
|
+
|
4
|
+
Version 1.0.0.beta
|
5
|
+
------------------
|
6
|
+
|
7
|
+
Released on June 12, 2013
|
8
|
+
|
9
|
+
- Removed YML-generator in favor of reading APPLICATION_URL from ENV
|
10
|
+
- Allow flexible configuration of API key information (same as SDK client)
|
11
|
+
- Using new SDK (1.0.0.beta) API
|
data/README.md
CHANGED
@@ -1,36 +1,88 @@
|
|
1
1
|
[](http://travis-ci.org/stormpath/stormpath-rails)
|
2
2
|
[](https://codeclimate.com/github/stormpath/stormpath-rails)
|
3
|
+
# Stormpath Rails Gem
|
3
4
|
|
4
|
-
|
5
|
+
Stormpath is the first easy, secure user management and authentication service for developers.
|
6
|
+
This is the Rails gem to ease integration of its features with any Rails-based application.
|
5
7
|
|
6
|
-
##
|
8
|
+
## Setup
|
7
9
|
|
8
|
-
|
10
|
+
1. Install the <code>stormpath-rails</code> gem, either via the command line:
|
9
11
|
|
10
|
-
```
|
11
|
-
|
12
|
-
```
|
12
|
+
```
|
13
|
+
$ gem install stormpath-rails
|
14
|
+
```
|
13
15
|
|
14
|
-
|
16
|
+
or adding the gem to your [Bundler][bundler] Gemspec:
|
15
17
|
|
16
|
-
```
|
17
|
-
|
18
|
-
```
|
18
|
+
```
|
19
|
+
gem 'stormpath-rails'
|
20
|
+
```
|
21
|
+
|
22
|
+
or any other preferred dependency.
|
23
|
+
|
24
|
+
2. Create a [Stormpath][stormpath] developer account and [create your API Keys][create-api-keys]
|
25
|
+
downloading the <code>apiKey.properties</code> file into a <code>.stormpath</code>
|
26
|
+
folder under your local home directory. So that the Rails gem knows where to find this file,
|
27
|
+
add an environment variable called STORMPATH\_API\_KEY\_FILE\_LOCATION whose value is the full
|
28
|
+
path to this new .properties file:
|
29
|
+
|
30
|
+
```sh
|
31
|
+
export STORMPATH_API_KEY_FILE_LOCATION="/Users/john/.stormpath/apiKey.properties"
|
32
|
+
```
|
19
33
|
|
34
|
+
3. Create an application and a directory to store your users' accounts through the
|
35
|
+
[Stormpath Admin][stormpath-admin] interface. Make sure to add the newly-created
|
36
|
+
directory as a Login Source for your newly-created Application.
|
20
37
|
|
21
|
-
|
38
|
+
4. Through the [Stormpath Admin][stormpath-admin] interface, note your application's REST URL.
|
39
|
+
You'll want to create an environment variable called STORMPATH\_APPLICATION\_URL whose value
|
40
|
+
is this URL.
|
41
|
+
|
42
|
+
5. Generate and run migration, if you're on ActiveRecord. Skip this step for Mongoid.
|
43
|
+
```sh
|
44
|
+
rails g stormpath:rails:migration user
|
45
|
+
rake db:migrate
|
46
|
+
```
|
47
|
+
|
48
|
+
6. Update your model file.
|
49
|
+
```ruby
|
50
|
+
class User < ActiveRecord:Base
|
51
|
+
include Stormpath::Rails::Account
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
## Testing
|
56
|
+
|
57
|
+
To run the test suite, simple run:
|
22
58
|
|
23
59
|
```sh
|
24
|
-
|
25
|
-
rake db:migrate
|
60
|
+
$ rake spec
|
26
61
|
```
|
27
62
|
|
28
|
-
|
63
|
+
Note that this will make requests to the Stormpath API; you'll need to have set
|
64
|
+
environment variables enabling the client to interact with your Stormpath
|
65
|
+
account. You'll also need to have environment variables set that will enable
|
66
|
+
the client to interact with a test directory and application.
|
67
|
+
|
68
|
+
The test run will also generate a code-coverage report, viewable in the
|
69
|
+
coverage subdirectory.
|
70
|
+
|
71
|
+
## Contributing
|
72
|
+
|
73
|
+
You can make your own contributions by forking the <code>development</code>
|
74
|
+
branch, making your changes, and issuing pull-requests on the
|
75
|
+
<code>development</code> branch.
|
76
|
+
|
77
|
+
## Building the Gem
|
78
|
+
|
79
|
+
To build and install the development branch yourself from the latest source:
|
29
80
|
|
30
|
-
```
|
31
|
-
|
32
|
-
|
33
|
-
|
81
|
+
```
|
82
|
+
$ git clone git@github.com:stormpath/stormpath-rails.git
|
83
|
+
$ cd stormpath-rails
|
84
|
+
$ rake gem
|
85
|
+
$ gem install pkg/stormpath-rails-{version}.gem
|
34
86
|
```
|
35
87
|
|
36
88
|
## TODO
|
@@ -40,10 +92,16 @@ end
|
|
40
92
|
+ Preventive validation to not send invalid data to stormpath.
|
41
93
|
+ Solve n+1 request problem when requesting account collection.
|
42
94
|
|
43
|
-
##
|
95
|
+
## Copyright & Licensing
|
96
|
+
|
97
|
+
Copyright © 2012 Stormpath, Inc. and contributors.
|
98
|
+
|
99
|
+
This project is licensed under the [Apache 2.0 Open Source License](http://www.apache.org/licenses/LICENSE-2.0).
|
100
|
+
|
101
|
+
For additional information, please see the full [Project Documentation](https://www.stormpath.com/docs/ruby/product-guide).
|
44
102
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
103
|
+
[bundler]: http://gembundler.com/
|
104
|
+
[stormpath]: http://stormpath.com/
|
105
|
+
[create-api-keys]: http://www.stormpath.com/docs/ruby/product-guide#AssignAPIkeys
|
106
|
+
[stormpath_bootstrap]: https://github.com/stormpath/stormpath-sdk-ruby/wiki/Bootstrapping-Stormpath
|
107
|
+
[stormpath-admin]: https://api.stormpath.com/login
|
@@ -1,7 +1,5 @@
|
|
1
1
|
require 'active_support/concern'
|
2
2
|
require "stormpath-sdk"
|
3
|
-
include Stormpath::Client
|
4
|
-
include Stormpath::Resource
|
5
3
|
|
6
4
|
module Stormpath
|
7
5
|
module Rails
|
@@ -10,6 +8,28 @@ module Stormpath
|
|
10
8
|
|
11
9
|
STORMPATH_FIELDS = [ :email, :password, :username, :given_name, :middle_name, :surname, :status ]
|
12
10
|
|
11
|
+
module ClassMethods
|
12
|
+
def authenticate username, password
|
13
|
+
account = Stormpath::Rails::Client.authenticate_account username, password
|
14
|
+
self.where(stormpath_url: account.href).first
|
15
|
+
end
|
16
|
+
|
17
|
+
def send_password_reset_email email
|
18
|
+
account = Stormpath::Rails::Client.send_password_reset_email email
|
19
|
+
self.where(stormpath_url: account.href).first
|
20
|
+
end
|
21
|
+
|
22
|
+
def verify_password_reset_token token
|
23
|
+
account = Stormpath::Rails::Client.verify_password_reset_token token
|
24
|
+
self.where(stormpath_url: account.href).first
|
25
|
+
end
|
26
|
+
|
27
|
+
def verify_account_email token
|
28
|
+
account = Stormpath::Rails::Client.verify_account_email token
|
29
|
+
self.where(stormpath_url: account.href).first
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
13
33
|
included do
|
14
34
|
#AR specific workaround
|
15
35
|
self.partial_updates = false if self.respond_to?(:partial_updates)
|
@@ -18,48 +38,83 @@ module Stormpath
|
|
18
38
|
field(:stormpath_url, type: String) if self.respond_to?(:field)
|
19
39
|
index({ stormpath_url: 1 }, { unique: true }) if self.respond_to?(:index)
|
20
40
|
|
21
|
-
attr_accessor
|
22
|
-
attr_accessible
|
41
|
+
attr_accessor(*STORMPATH_FIELDS)
|
42
|
+
attr_accessible(*STORMPATH_FIELDS)
|
23
43
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
44
|
+
before_create :create_account_on_stormpath
|
45
|
+
before_update :update_account_on_stormpath
|
46
|
+
after_destroy :delete_account_on_stormpath
|
47
|
+
|
48
|
+
def stormpath_account
|
49
|
+
if stormpath_url
|
50
|
+
@stormpath_account ||= begin
|
51
|
+
Stormpath::Rails::Client.find_account(stormpath_url)
|
52
|
+
rescue Stormpath::Error => error
|
53
|
+
Stormpath::Rails.logger.warn "Error loading Stormpath account (#{error})"
|
54
|
+
end
|
31
55
|
end
|
32
56
|
end
|
33
57
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
58
|
+
def stormpath_pre_create_attrs
|
59
|
+
@stormpath_pre_create_attrs ||= {}
|
60
|
+
end
|
61
|
+
|
62
|
+
(STORMPATH_FIELDS - [:password]).each do |name|
|
63
|
+
define_method(name) do
|
64
|
+
if stormpath_account.present?
|
65
|
+
stormpath_account.send(name)
|
66
|
+
else
|
67
|
+
stormpath_pre_create_attrs[name]
|
68
|
+
end
|
40
69
|
end
|
41
|
-
self.stormpath_url = account.get_href
|
42
70
|
end
|
43
71
|
|
44
|
-
|
45
|
-
|
72
|
+
STORMPATH_FIELDS.each do |name|
|
73
|
+
define_method("#{name}=") do |val|
|
74
|
+
if stormpath_account.present?
|
75
|
+
stormpath_account.send("#{name}=", val)
|
76
|
+
else
|
77
|
+
stormpath_pre_create_attrs[name] = val
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def create_account_on_stormpath
|
46
83
|
begin
|
47
|
-
Client.
|
48
|
-
|
84
|
+
@stormpath_account = Stormpath::Rails::Client.create_account! stormpath_pre_create_attrs
|
85
|
+
stormpath_pre_create_attrs.clear
|
86
|
+
self.stormpath_url = @stormpath_account.href
|
87
|
+
rescue Stormpath::Error => error
|
49
88
|
self.errors[:base] << error.to_s
|
50
|
-
|
89
|
+
false
|
51
90
|
end
|
52
91
|
end
|
53
92
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
93
|
+
def update_account_on_stormpath
|
94
|
+
if self.stormpath_url.present?
|
95
|
+
begin
|
96
|
+
stormpath_account.save
|
97
|
+
rescue Stormpath::Error => error
|
98
|
+
self.errors[:base] << error.to_s
|
99
|
+
false
|
100
|
+
end
|
101
|
+
else
|
102
|
+
true
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def delete_account_on_stormpath
|
107
|
+
if self.stormpath_url.present?
|
108
|
+
begin
|
109
|
+
stormpath_account.delete
|
110
|
+
rescue Stormpath::Error => error
|
111
|
+
Stormpath::Rails.logger.warn "Error destroying Stormpath account (#{error})"
|
112
|
+
end
|
113
|
+
else
|
114
|
+
true
|
60
115
|
end
|
61
116
|
end
|
62
117
|
end
|
63
118
|
end
|
64
119
|
end
|
65
|
-
end
|
120
|
+
end
|
@@ -1,70 +1,99 @@
|
|
1
1
|
require "stormpath-sdk"
|
2
|
-
include Stormpath::Client
|
3
|
-
include Stormpath::Resource
|
4
|
-
include Stormpath::Authentication
|
5
2
|
|
6
3
|
module Stormpath
|
7
4
|
module Rails
|
5
|
+
class ConfigurationError < StandardError; end
|
6
|
+
|
8
7
|
class Client
|
9
8
|
class << self
|
10
|
-
attr_accessor :connection
|
9
|
+
attr_accessor :connection, :root_application
|
11
10
|
end
|
12
11
|
|
13
|
-
def self.authenticate_account(
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
def self.authenticate_account(username, password)
|
13
|
+
auth_result = application.authenticate_account(
|
14
|
+
Stormpath::Authentication::UsernamePasswordRequest.new(username, password)
|
15
|
+
)
|
16
|
+
auth_result.account
|
17
17
|
end
|
18
18
|
|
19
|
-
def self.send_password_reset_email(
|
20
|
-
application
|
21
|
-
application.send_password_reset_email login_or_email
|
19
|
+
def self.send_password_reset_email(email)
|
20
|
+
application.send_password_reset_email email
|
22
21
|
end
|
23
22
|
|
24
23
|
def self.verify_password_reset_token(token)
|
25
|
-
application = self.ds.get_resource Config[:stormpath_url], ::Application
|
26
24
|
application.verify_password_reset_token token
|
27
25
|
end
|
28
26
|
|
29
27
|
def self.verify_account_email(token)
|
30
|
-
self.client.
|
28
|
+
self.client.accounts.verify_email_token token
|
31
29
|
end
|
32
30
|
|
33
31
|
def self.create_account!(attributes)
|
34
|
-
|
35
|
-
attributes.each { |field, value| account.send("set_#{field}", value) }
|
36
|
-
self.root_directory.create_account account
|
32
|
+
self.application.accounts.create attributes
|
37
33
|
end
|
38
34
|
|
39
35
|
def self.all_accounts
|
40
|
-
self.
|
36
|
+
self.application.accounts
|
41
37
|
end
|
42
38
|
|
43
39
|
def self.find_account(href)
|
44
|
-
self.
|
40
|
+
self.client.accounts.get href
|
45
41
|
end
|
46
42
|
|
47
43
|
def self.update_account!(href, attributes)
|
48
|
-
account = self.
|
49
|
-
attributes.each { |field, value| account.send("
|
44
|
+
account = self.find_account href
|
45
|
+
attributes.each { |field, value| account.send("#{field}=", value) }
|
50
46
|
account.save
|
51
47
|
end
|
52
48
|
|
53
49
|
def self.delete_account!(href)
|
54
|
-
self.
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.root_directory
|
58
|
-
self.ds.get_resource Config[:root], ::Directory
|
50
|
+
self.client.accounts.get(href).delete
|
59
51
|
end
|
60
52
|
|
61
53
|
def self.ds
|
62
54
|
self.client.data_store
|
63
55
|
end
|
64
56
|
|
57
|
+
def self.application
|
58
|
+
self.root_application ||= self.client.applications.get ENV["STORMPATH_APPLICATION_URL"]
|
59
|
+
end
|
60
|
+
|
65
61
|
def self.client
|
66
|
-
self.connection
|
67
|
-
|
62
|
+
unless self.connection
|
63
|
+
if ENV['STORMPATH_URL'].nil? && ENV['STORMPATH_APPLICATION_URL'].nil?
|
64
|
+
raise ConfigurationError, 'Either STORMPATH_URL or STORMPATH_APPLICATION_URL must be set'
|
65
|
+
end
|
66
|
+
|
67
|
+
composite_url = ENV['STORMPATH_URL']
|
68
|
+
|
69
|
+
if composite_url
|
70
|
+
self.root_application = Stormpath::Resource::Application.load composite_url
|
71
|
+
self.connection = self.root_application.client
|
72
|
+
else
|
73
|
+
self.connection = Stormpath::Client.new client_options
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
self.connection
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.client_options
|
81
|
+
Hash.new.tap do |o|
|
82
|
+
set_if_not_empty(o, "api_key_file_location", ENV["STORMPATH_API_KEY_FILE_LOCATION"])
|
83
|
+
set_if_not_empty(o, "api_key_id_property_name", ENV["STORMPATH_API_KEY_ID_PROPERTY_NAME"])
|
84
|
+
set_if_not_empty(o, "api_key_secret_property_name", ENV["STORMPATH_API_KEY_SECRET_PROPERTY_NAME"])
|
85
|
+
|
86
|
+
o[:api_key] = {
|
87
|
+
id: ENV["STORMPATH_API_KEY_ID"],
|
88
|
+
secret: ENV["STORMPATH_API_KEY_SECRET"]
|
89
|
+
} unless ENV["STORMPATH_API_KEY_ID"].blank? or ENV["STORMPATH_API_KEY_SECRET"].blank?
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def self.set_if_not_empty(object, property, value)
|
96
|
+
object[property.to_sym] = value unless value.blank?
|
68
97
|
end
|
69
98
|
end
|
70
99
|
end
|