janus 0.6.0 → 0.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 (41) hide show
  1. data/README.rdoc +77 -154
  2. data/lib/generators/janus/install_generator.rb +19 -0
  3. data/lib/generators/janus/resource_generator.rb +64 -0
  4. data/lib/generators/templates/confirmations/new.html.erb +16 -0
  5. data/lib/generators/templates/confirmations_controller.erb +3 -0
  6. data/lib/generators/templates/janus.en.yml +62 -0
  7. data/lib/generators/templates/janus.rb +25 -0
  8. data/lib/generators/templates/model.erb +8 -0
  9. data/lib/generators/templates/passwords/edit.html.erb +21 -0
  10. data/lib/generators/templates/passwords/new.html.erb +16 -0
  11. data/lib/generators/templates/passwords_controller.erb +3 -0
  12. data/lib/generators/templates/registrations/edit.html.erb +31 -0
  13. data/lib/generators/templates/registrations/new.html.erb +26 -0
  14. data/lib/generators/templates/registrations_controller.erb +17 -0
  15. data/lib/generators/templates/sessions/new.html.erb +30 -0
  16. data/lib/generators/templates/sessions_controller.erb +11 -0
  17. data/lib/janus.rb +1 -0
  18. data/lib/janus/config.rb +10 -4
  19. data/lib/janus/controllers/confirmations_controller.rb +6 -6
  20. data/lib/janus/controllers/helpers.rb +4 -4
  21. data/lib/janus/controllers/passwords_controller.rb +3 -3
  22. data/lib/janus/controllers/registrations_controller.rb +12 -9
  23. data/lib/janus/controllers/sessions_controller.rb +15 -7
  24. data/lib/janus/helper.rb +1 -1
  25. data/lib/janus/hooks.rb +6 -6
  26. data/lib/janus/hooks/rememberable.rb +2 -2
  27. data/lib/janus/hooks/remote_authenticatable.rb +1 -1
  28. data/lib/janus/manager.rb +5 -5
  29. data/lib/janus/models/base.rb +2 -2
  30. data/lib/janus/models/confirmable.rb +7 -4
  31. data/lib/janus/models/database_authenticatable.rb +26 -16
  32. data/lib/janus/models/rememberable.rb +12 -9
  33. data/lib/janus/models/remote_authenticatable.rb +21 -18
  34. data/lib/janus/models/trackable.rb +11 -8
  35. data/lib/janus/routes.rb +22 -22
  36. data/lib/janus/strategies.rb +3 -3
  37. data/lib/janus/strategies/database_authenticatable.rb +1 -1
  38. data/lib/janus/strategies/rememberable.rb +1 -1
  39. data/lib/janus/strategies/remote_authenticatable.rb +1 -1
  40. data/lib/janus/test_helper.rb +6 -2
  41. metadata +19 -36
@@ -1,7 +1,7 @@
1
1
  Janus::Manager.after_login do |user, manager, options|
2
2
  if options[:rememberable] && user.respond_to?(:remember_me!)
3
3
  user.remember_me!
4
-
4
+
5
5
  remember_cookie_name = Janus::Strategies::Rememberable.remember_cookie_name(options[:scope])
6
6
  manager.cookies[remember_cookie_name] = {
7
7
  :value => user.remember_token,
@@ -13,7 +13,7 @@ end
13
13
  Janus::Manager.after_logout do |user, manager, options|
14
14
  if user.respond_to?(:forget_me!)
15
15
  user.forget_me!
16
-
16
+
17
17
  remember_cookie_name = Janus::Strategies::Rememberable.remember_cookie_name(options[:scope])
18
18
  manager.cookies.delete(remember_cookie_name)
19
19
  end
@@ -1,7 +1,7 @@
1
1
  Janus::Manager.after_login do |user, manager, options|
2
2
  if user.respond_to?(:generate_session_token!)
3
3
  user.generate_session_token! if user.session_token.nil?
4
-
4
+
5
5
  session = manager.session(options[:scope])
6
6
  session[:session_token] = user.session_token
7
7
  end
@@ -33,7 +33,7 @@ module Janus
33
33
  end
34
34
 
35
35
  # Logs a user in.
36
- #
36
+ #
37
37
  # FIXME: what should happen when a user signs in but a user is already signed in for the same scope?!
38
38
  def login(user, options = {})
39
39
  options[:scope] ||= Janus.scope_for(user)
@@ -46,13 +46,13 @@ module Janus
46
46
  # whole session will be resetted.
47
47
  def logout(*scopes)
48
48
  scopes = janus_sessions.keys if scopes.empty?
49
-
49
+
50
50
  scopes.each do |scope|
51
51
  _user = user(scope)
52
52
  unset_user(scope)
53
53
  Janus::Manager.run_callbacks(:logout, _user, self, :scope => scope)
54
54
  end
55
-
55
+
56
56
  request.reset_session if janus_sessions.empty?
57
57
  end
58
58
 
@@ -73,7 +73,7 @@ module Janus
73
73
  def user(scope)
74
74
  scope = scope.to_sym
75
75
  @users ||= {}
76
-
76
+
77
77
  if authenticated?(scope)
78
78
  if @users[scope].nil?
79
79
  begin
@@ -84,7 +84,7 @@ module Janus
84
84
  Janus::Manager.run_callbacks(:fetch, @users[scope], self, :scope => scope)
85
85
  end
86
86
  end
87
-
87
+
88
88
  @users[scope]
89
89
  end
90
90
  end
@@ -17,14 +17,14 @@ module Janus
17
17
  def self.#{key}
18
18
  @#{key} || Janus::Config.#{key}
19
19
  end
20
-
20
+
21
21
  def self.#{key}=(value)
22
22
  @#{key} = value
23
23
  end
24
24
  EOV
25
25
  end
26
26
  end
27
-
27
+
28
28
  end
29
29
  end
30
30
  end
@@ -1,18 +1,21 @@
1
1
  module Janus
2
2
  module Models
3
3
  # = Confirmable
4
- #
4
+ #
5
5
  # Confirms an account's email by sending an email with an unique token.
6
6
  # This is necessary to be sure the user can be contacted on that email.
7
- #
7
+ #
8
8
  # IMPROVE: reconfirm whenever email changes.
9
9
  module Confirmable
10
10
  extend ActiveSupport::Concern
11
11
 
12
12
  included do
13
- attr_protected :confirmation_token, :confirmation_sent_at, :confirmed_at
13
+ begin
14
+ attr_protected :confirmation_token, :confirmation_sent_at, :confirmed_at
15
+ rescue
16
+ end
14
17
  janus_config(:confirmation_key)
15
-
18
+
16
19
  before_create :generate_confirmation_token
17
20
  # before_update :generate_confirmation_token, :if => :email_changed?
18
21
  end
@@ -1,36 +1,46 @@
1
- require 'bcrypt'
2
- require 'scrypt'
1
+ begin
2
+ require 'bcrypt'
3
+ rescue
4
+ end
5
+
6
+ begin
7
+ require 'scrypt'
8
+ rescue
9
+ end
3
10
 
4
11
  module Janus
5
12
  module Models
6
13
  # = DatabaseAuthenticatable
7
- #
14
+ #
8
15
  # This is the initial part and is required for email + password registration
9
16
  # and logins. Passwords are automatically encrypted following Devise's
10
17
  # default encryption logic, which relies on bcrypt.
11
- #
18
+ #
12
19
  # == Required columns:
13
- #
20
+ #
14
21
  # - email
15
22
  # - encrypted_password
16
- #
23
+ #
17
24
  # == Configuration
18
- #
25
+ #
19
26
  # - +stretches+
20
27
  # - +pepper+
21
28
  # - +authentication_keys+ - required keys for authenticating a user, defaults to <tt>[:email]</tt>
22
- #
29
+ #
23
30
  module DatabaseAuthenticatable
24
31
  extend ActiveSupport::Concern
25
32
 
26
33
  included do
27
- attr_protected :encrypted_password, :reset_password_token, :reset_password_sent_at
34
+ begin
35
+ attr_protected :encrypted_password, :reset_password_token, :reset_password_sent_at
36
+ rescue
37
+ end
28
38
  attr_reader :password
29
39
  attr_accessor :current_password
30
-
40
+
31
41
  validates :password, :presence => true, :confirmation => true, :if => :password_required?
32
42
  validate :validate_current_password, :on => :update, :if => :current_password
33
-
43
+
34
44
  janus_config(:authentication_keys, :encryptor, :stretches, :pepper, :scrypt_options)
35
45
  end
36
46
 
@@ -74,10 +84,10 @@ module Janus
74
84
  end
75
85
 
76
86
  def reset_password!(params)
77
- params.each do |key, value|
78
- send("#{key}=", value) if [:password, :password_confirmation].include?(key.to_sym)
87
+ %w{password password_confirmation}.each do |attr|
88
+ send("#{attr}=", params[attr]) if params.has_key?(attr)
79
89
  end
80
-
90
+
81
91
  self.reset_password_sent_at = self.reset_password_token = nil
82
92
  save
83
93
  end
@@ -99,13 +109,13 @@ module Janus
99
109
 
100
110
  def find_for_password_reset(token)
101
111
  user = find_by_reset_password_token(token) unless token.blank?
102
-
112
+
103
113
  if user && user.reset_password_sent_at < 2.days.ago
104
114
  user.reset_password_token = user.reset_password_sent_at = nil
105
115
  user.save
106
116
  user = nil
107
117
  end
108
-
118
+
109
119
  user
110
120
  end
111
121
  end
@@ -1,26 +1,29 @@
1
1
  module Janus
2
2
  module Models
3
3
  # = Rememberable
4
- #
4
+ #
5
5
  # Allows a user to check a remember me check box when she logs in through
6
6
  # DatabaseAuthenticatable. It will set a cookie with a configurable
7
7
  # expiration date.
8
- #
8
+ #
9
9
  # == Required columns
10
- #
10
+ #
11
11
  # - remember_token
12
12
  # - remember_created_at
13
- #
13
+ #
14
14
  # == Configuration
15
- #
15
+ #
16
16
  # - remember_for - how long to remember the user, for instance <tt>1.week</tt>.
17
17
  # - :extend_remember_period - set to true to extend the remember cookie every time the user logs in.
18
- #
18
+ #
19
19
  module Rememberable
20
20
  extend ActiveSupport::Concern
21
21
 
22
22
  included do
23
- attr_protected :remember_token, :remember_created_at
23
+ begin
24
+ attr_protected :remember_token, :remember_created_at
25
+ rescue
26
+ end
24
27
  janus_config :remember_for, :extend_remember_period
25
28
  end
26
29
 
@@ -40,12 +43,12 @@ module Janus
40
43
  module ClassMethods
41
44
  def find_for_remember_authentication(token)
42
45
  user = where(:remember_token => token).first unless token.blank?
43
-
46
+
44
47
  if user && user.remember_created_at < remember_for.ago
45
48
  user.forget_me!
46
49
  user = nil
47
50
  end
48
-
51
+
49
52
  user
50
53
  end
51
54
  end
@@ -3,61 +3,64 @@ require 'janus/hooks/remote_authenticatable'
3
3
  module Janus
4
4
  module Models
5
5
  # = RemoteAuthenticatable
6
- #
6
+ #
7
7
  # Keeping a user connected on subdomains is an easy task, all you need to do
8
8
  # is define the session cookie to <tt>.example.com</tt> for instance. But
9
9
  # keeping a user connected on multiple top level domains is a harder task.
10
- #
10
+ #
11
11
  # Hopefully RemoteAuthenticatable takes care of all the hassle.
12
- #
12
+ #
13
13
  # == Single Sign In
14
- #
14
+ #
15
15
  # The authentication must happen on a single domain, for instance
16
16
  # <tt>login.example.com</tt>, then other domains must redirect to that
17
17
  # domain's new session url. For instance:
18
- #
18
+ #
19
19
  # redirect_to new_user_session_url(:host => "login.example.com") unless user_signed_in?
20
- #
20
+ #
21
21
  # And that's it! The user shall be redirected with an unique +remote_token+,
22
22
  # which shall log her in. Actually the user won't be logged in through
23
23
  # Janus::Manager#login but through Janus::Manager#set_user which won't
24
24
  # run the login hooks. This is useful for not tracking the user everytime
25
25
  # it gets authenticated on each remote site.
26
- #
26
+ #
27
27
  # == Single Sign Out
28
- #
28
+ #
29
29
  # Session state is maintained across domains through the session_token
30
30
  # column of your User model. If a session token is invalid the session
31
31
  # is simply resetted, thus logging out the user on remote domains. Actually
32
32
  # the user is logged out using Janus::Manager#unset_user before
33
33
  # resetting the session.
34
- #
34
+ #
35
35
  # == Required columns and models:
36
- #
36
+ #
37
37
  # A +session_token+ column (string) is required, as well as a RemoteToken
38
38
  # model like so:
39
- #
39
+ #
40
40
  # class RemoteToken < ActiveRecord::Base
41
41
  # include Janus::Models::RemoteToken
42
- #
42
+ #
43
43
  # belongs_to :user
44
44
  # validates_presence_of :user
45
45
  # end
46
- #
46
+ #
47
47
  # With the associated table:
48
- #
48
+ #
49
49
  # create_table :remote_tokens do |t|
50
50
  # t.references :user
51
51
  # t.string :token
52
52
  # t.datetime :created_at
53
53
  # end
54
- #
54
+ #
55
55
  # add_index :remote_tokens, :token, :unique => true
56
56
  module RemoteAuthenticatable
57
57
  extend ActiveSupport::Concern
58
58
 
59
59
  included do |klass|
60
- attr_protected :session_token
60
+ begin
61
+ attr_protected :session_token
62
+ rescue
63
+ end
61
64
  klass.class_eval { has_many :remote_tokens }
62
65
  janus_config :remote_authentication_key
63
66
  end
@@ -65,7 +68,7 @@ module Janus
65
68
  # Generates an unique session token. This token will be used to validate
66
69
  # the current session, and must be generated whenever a user signs in on
67
70
  # the main site.
68
- #
71
+ #
69
72
  # The token won't be regenerated if it already exists.
70
73
  def generate_session_token!
71
74
  update_attribute(:session_token, self.class.generate_token(:session_token)) unless session_token
@@ -87,7 +90,7 @@ module Janus
87
90
  module ClassMethods
88
91
  def find_for_remote_authentication(token)
89
92
  remote_token = ::RemoteToken.where(:token => token).first
90
-
93
+
91
94
  if remote_token
92
95
  remote_token.destroy
93
96
  remote_token.user unless remote_token.created_at < 30.seconds.ago
@@ -3,33 +3,36 @@ require 'janus/hooks/trackable'
3
3
  module Janus
4
4
  module Models
5
5
  # = Trackable
6
- #
6
+ #
7
7
  # Simple hook to update some columns of your model whenever a user logs in.
8
- #
8
+ #
9
9
  # == Required columns
10
- #
10
+ #
11
11
  # - +sign_in_count+
12
12
  # - +current_sign_in_ip+
13
13
  # - +current_sign_in_at+
14
14
  # - +last_sign_in_ip+
15
15
  # - +last_sign_in_at+
16
- #
16
+ #
17
17
  module Trackable
18
18
  extend ActiveSupport::Concern
19
19
 
20
20
  included do
21
- attr_protected :sign_in_count, :current_sign_in_at, :last_sign_in_at, :current_sign_in_ip, :last_sign_in_ip
21
+ begin
22
+ attr_protected :sign_in_count, :current_sign_in_at, :last_sign_in_at, :current_sign_in_ip, :last_sign_in_ip
23
+ rescue
24
+ end
22
25
  end
23
26
 
24
27
  def track!(ip)
25
28
  self.sign_in_count += 1
26
-
29
+
27
30
  self.last_sign_in_at = self.current_sign_in_at
28
31
  self.last_sign_in_ip = self.current_sign_in_ip
29
-
32
+
30
33
  self.current_sign_in_at = Time.now
31
34
  self.current_sign_in_ip = ip
32
-
35
+
33
36
  save(:validate => false)
34
37
  end
35
38
  end
@@ -2,73 +2,73 @@ module ActionDispatch # :nodoc:
2
2
  module Routing # :nodoc:
3
3
  class Mapper
4
4
  # Creates the routes for a Janus capable resource.
5
- #
5
+ #
6
6
  # Example:
7
- #
7
+ #
8
8
  # MyApp::Application.routes.draw do
9
9
  # janus :users, :session => true, :registration => false
10
10
  # end
11
- #
11
+ #
12
12
  # Options:
13
- #
13
+ #
14
14
  # - +session+ - true to generate session routes
15
15
  # - +registration+ - true to generate registration routes
16
16
  # - +confirmation+ - true to generate confirmation routes
17
17
  # - +password+ - true to generate password reset routes
18
- #
18
+ #
19
19
  # Generated session routes:
20
- #
20
+ #
21
21
  # new_user_session GET /users/sign_in(.:format) {:controller=>"users/sessions", :action=>"new"}
22
22
  # user_session POST /users/sign_in(.:format) {:controller=>"users/sessions", :action=>"create"}
23
- # destroy_user_session /users/sign_out(.:format) {:controller=>"users/sessions", :action=>"destroy"}
24
- #
23
+ # destroy_user_session DELETE /users/sign_out(.:format) {:controller=>"users/sessions", :action=>"destroy"}
24
+ #
25
25
  # Generated registration routes:
26
- #
26
+ #
27
27
  # new_user_registration GET /users/sign_up(.:format) {:controller=>"users/registrations", :action=>"new"}
28
28
  # user_registration POST /users(.:format) {:controller=>"users/registrations", :action=>"create"}
29
29
  # edit_user_registration GET /users/edit(.:format) {:controller=>"users/registrations", :action=>"edit"}
30
30
  # PUT /users(.:format) {:controller=>"users/registrations", :action=>"update"}
31
31
  # DELETE /users(.:format) {:controller=>"users/registrations", :action=>"destroy"}
32
- #
32
+ #
33
33
  # Generated confirmation routes:
34
- #
34
+ #
35
35
  # user_confirmation POST /users/confirmation(.:format) {:controller=>"users/confirmations", :action=>"create"}
36
36
  # new_user_confirmation GET /users/confirmation/new(.:format) {:controller=>"users/confirmations", :action=>"new"}
37
37
  # GET /users/confirmation(.:format) {:controller=>"users/confirmations", :action=>"show"}
38
- #
38
+ #
39
39
  # Generated password reset routes:
40
- #
40
+ #
41
41
  # user_password POST /users/password(.:format) {:controller=>"users/passwords", :action=>"create"}
42
42
  # new_user_password GET /users/password/new(.:format) {:controller=>"users/passwords", :action=>"new"}
43
43
  # edit_user_password GET /users/password/edit(.:format) {:controller=>"users/passwords", :action=>"edit"}
44
44
  # PUT /users/password(.:format) {:controller=>"users/passwords", :action=>"update"}
45
- #
45
+ #
46
46
  def janus(*resources)
47
47
  ActionController::Base.send(:include, Janus::Helpers) unless ActionController::Base.include?(Janus::Helpers)
48
48
  ActionController::Base.send(:include, Janus::UrlHelpers) unless ActionController::Base.include?(Janus::UrlHelpers)
49
49
  options = resources.extract_options!
50
-
50
+
51
51
  resources.each do |plural|
52
52
  singular = plural.to_s.singularize
53
-
53
+
54
54
  if options[:session]
55
55
  scope :path => plural, :controller => "#{plural}/sessions" do
56
- match "/sign_in(.:format)", :action => "new", :via => :get, :as => "new_#{singular}_session"
57
- match "/sign_in(.:format)", :action => "create", :via => :post, :as => "#{singular}_session"
58
- match "/sign_out(.:format)", :action => "destroy", :as => "destroy_#{singular}_session"
56
+ get "/sign_in(.:format)", :action => "new", :as => "new_#{singular}_session"
57
+ post "/sign_in(.:format)", :action => "create", :as => "#{singular}_session"
58
+ delete "/sign_out(.:format)", :action => "destroy", :as => "destroy_#{singular}_session"
59
59
  end
60
60
  end
61
-
61
+
62
62
  namespace plural, :as => singular do
63
63
  if options[:registration]
64
64
  resource :registration, :except => [:index, :show], :path => "",
65
65
  :path_names => { :new => 'sign_up' }
66
66
  end
67
-
67
+
68
68
  resource :confirmation, :only => [:show, :new, :create] if options[:confirmation]
69
69
  resource :password, :except => [:index, :show, :destroy] if options[:password]
70
70
  end
71
-
71
+
72
72
  ActionController::Base.janus(singular)
73
73
  end
74
74
  end