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 CHANGED
@@ -17,3 +17,4 @@ spec/reports
17
17
  test/tmp
18
18
  test/version_tmp
19
19
  tmp/
20
+ spec/fixtures/vcr_cassettes
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
- - 1.9.3
4
+ - 1.9.3
4
5
  gemfile:
5
- - Gemfile
6
+ - Gemfile
6
7
  script: bundle exec rake spec
7
8
  services:
8
- - mongodb
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
  [![Build Status](https://secure.travis-ci.org/stormpath/stormpath-rails.png)](http://travis-ci.org/stormpath/stormpath-rails)
2
2
  [![Code Climate](https://codeclimate.com/github/stormpath/stormpath-rails.png)](https://codeclimate.com/github/stormpath/stormpath-rails)
3
+ # Stormpath Rails Gem
3
4
 
4
- # Ruby on Rails support for Stormpath
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
- ## Gem Setup
8
+ ## Setup
7
9
 
8
- Reference gem from Gemfile.
10
+ 1. Install the <code>stormpath-rails</code> gem, either via the command line:
9
11
 
10
- ```ruby
11
- add gem 'stormpath-rails' to Gemfile
12
- ```
12
+ ```
13
+ $ gem install stormpath-rails
14
+ ```
13
15
 
14
- Generate configuration file, then create directory per environment at stormpath and update stormpath.yml with corresponding directory hrefs.
16
+ or adding the gem to your [Bundler][bundler] Gemspec:
15
17
 
16
- ```sh
17
- rails g stormpath:rails:install
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
- Generate and run migration, if you're on ActiveRecord. Skip this step for Mongoid.
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
- rails g stormpath:rails:migration user
25
- rake db:migrate
60
+ $ rake spec
26
61
  ```
27
62
 
28
- Update your model file.
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
- ```ruby
31
- class User < ActiveRecord:Base
32
- include Stormpath::Rails::Account
33
- end
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
- ## Contributing
95
+ ## Copyright & Licensing
96
+
97
+ Copyright &copy; 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
- 1. Fork it
46
- 2. Create your feature branch (`git checkout -b my-new-feature`)
47
- 3. Commit your changes (`git commit -am 'Add some feature'`)
48
- 4. Push to the branch (`git push origin my-new-feature`)
49
- 5. Create new Pull Request
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 *STORMPATH_FIELDS
22
- attr_accessible *STORMPATH_FIELDS
41
+ attr_accessor(*STORMPATH_FIELDS)
42
+ attr_accessible(*STORMPATH_FIELDS)
23
43
 
24
- after_initialize do |user|
25
- return true unless user.stormpath_url
26
- begin
27
- account = Client.find_account(user.stormpath_url)
28
- (STORMPATH_FIELDS - [:password]).each { |field| self.send("#{field}=", account.send("get_#{field}")) }
29
- rescue ResourceError => error
30
- Logger.new(STDERR).warn "Error loading Stormpath account (#{error})"
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
- before_create do
35
- begin
36
- account = Stormpath::Rails::Client.create_account!(Hash[*STORMPATH_FIELDS.map { |f| { f => self.send(f) } }.map(&:to_a).flatten])
37
- rescue ResourceError => error
38
- self.errors[:base] << error.to_s
39
- return false
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
- before_update do
45
- return true unless self.stormpath_url
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.update_account!(self.stormpath_url, Hash[*STORMPATH_FIELDS.map { |f| { f => self.send(f) } }.map(&:to_a).flatten])
48
- rescue ResourceError => error
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
- return false
89
+ false
51
90
  end
52
91
  end
53
92
 
54
- after_destroy do
55
- return true unless self.stormpath_url
56
- begin
57
- account = Client.delete_account!(self.stormpath_url)
58
- rescue ResourceError => error
59
- Logger.new(STDERR).warn "Error destroying Stormpath account (#{error})"
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(login, password)
14
- application = self.ds.get_resource Config[:stormpath_url], ::Application
15
- auth_result = application.authenticate_account ::UsernamePasswordRequest.new(login, password)
16
- auth_result.get_account
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(login_or_email)
20
- application = self.ds.get_resource Config[:stormpath_url], ::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.current_tenant.verify_account_email token
28
+ self.client.accounts.verify_email_token token
31
29
  end
32
30
 
33
31
  def self.create_account!(attributes)
34
- account = self.ds.instantiate ::Account
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.root_directory.get_accounts
36
+ self.application.accounts
41
37
  end
42
38
 
43
39
  def self.find_account(href)
44
- self.ds.get_resource href, ::Account
40
+ self.client.accounts.get href
45
41
  end
46
42
 
47
43
  def self.update_account!(href, attributes)
48
- account = self.ds.get_resource href, ::Account
49
- attributes.each { |field, value| account.send("set_#{field}", value) }
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.ds.delete self.ds.get_resource href, ::Account
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 ||= ::ClientApplicationBuilder.new.set_application_href(Config[:stormpath_url] || Config[:href]).build
67
- self.connection.client
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