janus 0.5.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.
- data/README.rdoc +144 -0
- data/lib/janus/config.rb +26 -0
- data/lib/janus/controllers/confirmations_controller.rb +56 -0
- data/lib/janus/controllers/helpers.rb +54 -0
- data/lib/janus/controllers/internal_helpers.rb +33 -0
- data/lib/janus/controllers/passwords_controller.rb +60 -0
- data/lib/janus/controllers/registrations_controller.rb +55 -0
- data/lib/janus/controllers/sessions_controller.rb +94 -0
- data/lib/janus/controllers/url_helpers.rb +61 -0
- data/lib/janus/helper.rb +11 -0
- data/lib/janus/hooks/rememberable.rb +20 -0
- data/lib/janus/hooks/remote_authenticatable.rb +27 -0
- data/lib/janus/hooks/trackable.rb +3 -0
- data/lib/janus/hooks.rb +58 -0
- data/lib/janus/mailer.rb +13 -0
- data/lib/janus/manager.rb +97 -0
- data/lib/janus/models/base.rb +31 -0
- data/lib/janus/models/confirmable.rb +45 -0
- data/lib/janus/models/database_authenticatable.rb +98 -0
- data/lib/janus/models/rememberable.rb +54 -0
- data/lib/janus/models/remote_authenticatable.rb +99 -0
- data/lib/janus/models/remote_token.rb +17 -0
- data/lib/janus/models/trackable.rb +37 -0
- data/lib/janus/routes.rb +78 -0
- data/lib/janus/strategies/base.rb +40 -0
- data/lib/janus/strategies/database_authenticatable.rb +20 -0
- data/lib/janus/strategies/rememberable.rb +52 -0
- data/lib/janus/strategies/remote_authenticatable.rb +28 -0
- data/lib/janus/strategies.rb +33 -0
- data/lib/janus/test_helper.rb +25 -0
- data/lib/janus.rb +60 -0
- data/test/functional/home_controller_test.rb +8 -0
- data/test/functional/janus/mailer_test.rb +14 -0
- data/test/functional/janus/manager_test.rb +94 -0
- data/test/functional/users/confirmations_controller_test.rb +59 -0
- data/test/functional/users/passwords_controller_test.rb +101 -0
- data/test/functional/users/registrations_controller_test.rb +112 -0
- data/test/functional/users/sessions_controller_test.rb +100 -0
- data/test/functional/users_controller_test.rb +22 -0
- data/test/integration/users/rememberable_test.rb +32 -0
- data/test/integration/users/remote_test.rb +72 -0
- data/test/integration/users/sessions_test.rb +18 -0
- data/test/integration/users/trackable_test.rb +22 -0
- data/test/rails_app/app/controllers/application_controller.rb +9 -0
- data/test/rails_app/app/controllers/blogs_controller.rb +6 -0
- data/test/rails_app/app/controllers/home_controller.rb +4 -0
- data/test/rails_app/app/controllers/users/confirmations_controller.rb +3 -0
- data/test/rails_app/app/controllers/users/passwords_controller.rb +3 -0
- data/test/rails_app/app/controllers/users/registrations_controller.rb +7 -0
- data/test/rails_app/app/controllers/users/sessions_controller.rb +11 -0
- data/test/rails_app/app/controllers/users_controller.rb +9 -0
- data/test/rails_app/app/helpers/application_helper.rb +2 -0
- data/test/rails_app/app/mailers/janus_mailer.rb +2 -0
- data/test/rails_app/app/models/remote_token.rb +6 -0
- data/test/rails_app/app/models/user.rb +8 -0
- data/test/rails_app/config/application.rb +42 -0
- data/test/rails_app/config/boot.rb +6 -0
- data/test/rails_app/config/environment.rb +5 -0
- data/test/rails_app/config/environments/development.rb +26 -0
- data/test/rails_app/config/environments/production.rb +49 -0
- data/test/rails_app/config/environments/test.rb +36 -0
- data/test/rails_app/config/initializers/janus.rb +11 -0
- data/test/rails_app/config/initializers/secret_token.rb +7 -0
- data/test/rails_app/config/initializers/session_store.rb +8 -0
- data/test/rails_app/config/routes.rb +12 -0
- data/test/rails_app/db/migrate/20110323153820_create_users.rb +34 -0
- data/test/rails_app/db/migrate/20110331153546_create_remote_tokens.rb +15 -0
- data/test/rails_app/db/schema.rb +45 -0
- data/test/rails_app/db/seeds.rb +7 -0
- data/test/test_helper.rb +103 -0
- data/test/unit/confirmable_test.rb +36 -0
- data/test/unit/janus_test.rb +27 -0
- data/test/unit/rememberable_test.rb +50 -0
- data/test/unit/remote_authenticatable_test.rb +37 -0
- data/test/unit/remote_token_test.rb +9 -0
- data/test/unit/reset_password_test.rb +45 -0
- data/test/unit/trackable_test.rb +21 -0
- data/test/unit/user_test.rb +60 -0
- metadata +232 -0
data/README.rdoc
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
= Janus
|
2
|
+
|
3
|
+
Janus is an authentication engine for Ruby on Rails 3 and is an alternative
|
4
|
+
to the Warden + Devise combo, without the Rack middleware. The whole project
|
5
|
+
is inspired by the Warden and Devise API but shall eventually be quite
|
6
|
+
different since everything happens within ActionDispatch and not at the Rack
|
7
|
+
level.
|
8
|
+
|
9
|
+
The main difference for now is the cross domain authentication --which allows
|
10
|
+
a user to single sign in and out across top level domains-- which required
|
11
|
+
a finer grained control over setting and unsetting a user than Warden provides.
|
12
|
+
Janus uses +login+ and +logout+ to actually sign the user in and out, while
|
13
|
+
+set_user+ and +unset_user+ will manually set the session, without dispatching
|
14
|
+
the +after_login+ and +after_logout+ hooks.
|
15
|
+
|
16
|
+
== Features
|
17
|
+
|
18
|
+
- DatabaseAuthenticatable
|
19
|
+
- RemoteAuthenticatable
|
20
|
+
- Confirmable
|
21
|
+
- Rememberable
|
22
|
+
- Trackable
|
23
|
+
|
24
|
+
Note: login through Janus::Manager#set_user won't track the user.
|
25
|
+
|
26
|
+
- authentication system with strategies and hooks
|
27
|
+
- scoped authentications with parallel authentication
|
28
|
+
- database authentication with password encryption, validation and remember me strategy
|
29
|
+
- remote authentication for cross domain sign in / sign out
|
30
|
+
- controllers: sessions, registrations, confirmations, passwords and their routes
|
31
|
+
- route generation for above controllers
|
32
|
+
- trackable hook
|
33
|
+
|
34
|
+
== TODO
|
35
|
+
|
36
|
+
- generators (janus:install, janus)
|
37
|
+
- rename RemoteAuthenticatable to something like CrossDomainAuthenticatable(?)
|
38
|
+
|
39
|
+
== Install
|
40
|
+
|
41
|
+
There is no automated way to install Janus yet, since generators are missing.
|
42
|
+
Please remember that Janus is only compatible with Rails 3.
|
43
|
+
|
44
|
+
First add the gem to your Gemfile:
|
45
|
+
|
46
|
+
$ gem 'janus', :git => git://github.com/ysbaddaden/janus.git
|
47
|
+
|
48
|
+
Configure your user models by including all or a selection of the Janus::Models
|
49
|
+
modules:
|
50
|
+
|
51
|
+
class User < ActiveRecord::Base
|
52
|
+
include Janus::Models::Base
|
53
|
+
include Janus::Models::DatabaseAuthenticatable
|
54
|
+
include Janus::Models::RemoteAuthenticatable
|
55
|
+
include Janus::Models::Confirmable
|
56
|
+
include Janus::Models::Rememberable
|
57
|
+
include Janus::Models::Trackable
|
58
|
+
end
|
59
|
+
|
60
|
+
class Admin < ActiveRecord::Base
|
61
|
+
include Janus::Models::Base
|
62
|
+
include Janus::Models::DatabaseAuthenticatable
|
63
|
+
include Janus::Models::RemoteAuthenticatable
|
64
|
+
end
|
65
|
+
|
66
|
+
Configure your routes:
|
67
|
+
|
68
|
+
Name::Application.routes.map do
|
69
|
+
janus :users, :session => true, :registration => true, :password => true, :confirmation => true
|
70
|
+
janus :admins, :session => true
|
71
|
+
|
72
|
+
root :to => "home#index"
|
73
|
+
end
|
74
|
+
|
75
|
+
Create the required controllers:
|
76
|
+
|
77
|
+
class Users::SessionsController < Janus::SessionsController
|
78
|
+
respond_to :html
|
79
|
+
end
|
80
|
+
|
81
|
+
class Users::RegistrationsController < Janus::RegistrationsController
|
82
|
+
respond_to :html
|
83
|
+
end
|
84
|
+
|
85
|
+
class Users::PasswordsController < Janus::PasswordsController
|
86
|
+
respond_to :html
|
87
|
+
end
|
88
|
+
|
89
|
+
class Users::ConfirmationssController < Janus::ConfirmationssController
|
90
|
+
respond_to :html
|
91
|
+
end
|
92
|
+
|
93
|
+
class Admins::SessionsController < Janus::SessionsController
|
94
|
+
respond_to :html
|
95
|
+
end
|
96
|
+
|
97
|
+
Copy the views from test/rails_app to your application:
|
98
|
+
|
99
|
+
mkdir name/app/views/users/
|
100
|
+
cp -r janus/test/rails_app/app/views/users/sessions name/app/views/users/
|
101
|
+
cp -r janus/test/rails_app/app/views/users/registrations name/app/views/users/
|
102
|
+
cp -r janus/test/rails_app/app/views/users/confirmations name/app/views/users/
|
103
|
+
cp -r janus/test/rails_app/app/views/users/registrations name/app/views/users/
|
104
|
+
|
105
|
+
mkdir name/app/views/admins/
|
106
|
+
cp -r janus/test/rails_app/app/views/users/sessions name/app/views/users/
|
107
|
+
|
108
|
+
Have a look to the test app in <tt>test/rails_app</tt> for additional help:
|
109
|
+
|
110
|
+
app/controllers/application_controller.rb
|
111
|
+
app/controller/users/confirmations_controller.rb
|
112
|
+
app/controller/users/passwords_controller.rb
|
113
|
+
app/controller/users/registrations_controller.rb
|
114
|
+
app/controller/users/sessions_controller.rb
|
115
|
+
app/mailers/janus_mailer.rb
|
116
|
+
app/models/remote_token.rb
|
117
|
+
app/models/user.rb
|
118
|
+
app/views/janus_mailer/confirmation_instructions.html.erb
|
119
|
+
app/views/janus_mailer/confirmation_instructions.text.erb
|
120
|
+
app/views/janus_mailer/reset_password_instructions.html.erb
|
121
|
+
app/views/janus_mailer/reset_password_instructions.text.erb
|
122
|
+
app/views/users/confirmations/new.html.erb
|
123
|
+
app/views/users/passwords/new.html.erb
|
124
|
+
app/views/users/passwords/edit.html.erb
|
125
|
+
app/views/users/registrations/new.html.erb
|
126
|
+
app/views/users/registrations/edit.html.erb
|
127
|
+
app/views/users/sessions/new.html.erb
|
128
|
+
config/initializers/janus.rb
|
129
|
+
config/locales/janus.en.yml
|
130
|
+
config/routes.rb
|
131
|
+
db/migrate/*.rb
|
132
|
+
|
133
|
+
== License
|
134
|
+
|
135
|
+
Janus is distributed under the MIT-License.
|
136
|
+
|
137
|
+
== Authors
|
138
|
+
|
139
|
+
Most of the API and some code like password encryption is copied from
|
140
|
+
Devise: http://github.com/plataformatec/devise.git and Warden:
|
141
|
+
http://github.com/hassox/warden
|
142
|
+
|
143
|
+
- Julien Portalier <ysbaddaden@gmail.com>
|
144
|
+
|
data/lib/janus/config.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'active_support/time'
|
2
|
+
|
3
|
+
module Janus
|
4
|
+
module Config
|
5
|
+
mattr_accessor :contact_email
|
6
|
+
|
7
|
+
# DatabaseAuthenticatable
|
8
|
+
mattr_accessor :authentication_keys, :stretches, :pepper
|
9
|
+
self.authentication_keys = [:email]
|
10
|
+
self.stretches = 10
|
11
|
+
|
12
|
+
# Confirmable
|
13
|
+
mattr_accessor :confirmation_key
|
14
|
+
self.confirmation_key = :confirm_token
|
15
|
+
|
16
|
+
# Rememberable
|
17
|
+
mattr_accessor :remember_for, :extend_remember_period, :remember_across_browsers
|
18
|
+
self.remember_for = 2.weeks
|
19
|
+
self.extend_remember_period = false
|
20
|
+
# self.remember_across_browsers = false
|
21
|
+
|
22
|
+
# RemoteAuthenticatable
|
23
|
+
mattr_accessor :remote_authentication_key
|
24
|
+
self.remote_authentication_key = :remote_token
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
class Janus::ConfirmationsController < ApplicationController
|
2
|
+
include Janus::InternalHelpers
|
3
|
+
|
4
|
+
helper JanusHelper
|
5
|
+
|
6
|
+
def show
|
7
|
+
self.resource = resource_class.find_for_confirmation(params[resource_class.confirmation_key])
|
8
|
+
|
9
|
+
if resource
|
10
|
+
resource.confirm!
|
11
|
+
|
12
|
+
respond_to do |format|
|
13
|
+
format.html { redirect_to root_url, :notice => t('flash.janus.confirmations.edit.confirmed') }
|
14
|
+
format.any { head :ok }
|
15
|
+
end
|
16
|
+
else
|
17
|
+
respond_to do |format|
|
18
|
+
format.html do
|
19
|
+
self.resource = resource_class.new
|
20
|
+
resource.errors.add(:base, :invalid_token)
|
21
|
+
render 'new'
|
22
|
+
end
|
23
|
+
|
24
|
+
format.any { head :bad_request }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def new
|
30
|
+
self.resource = resource_class.new
|
31
|
+
respond_with(resource)
|
32
|
+
end
|
33
|
+
|
34
|
+
def create
|
35
|
+
self.resource = resource_class.find_for_database_authentication(params[resource_name])
|
36
|
+
|
37
|
+
if resource
|
38
|
+
JanusMailer.confirmation_instructions(resource).deliver
|
39
|
+
|
40
|
+
respond_to do |format|
|
41
|
+
format.html { redirect_to root_url, :notice => t('flash.janus.confirmations.create.email_sent') }
|
42
|
+
format.any { head :ok }
|
43
|
+
end
|
44
|
+
else
|
45
|
+
respond_to do |format|
|
46
|
+
format.html do
|
47
|
+
self.resource = resource_class.new
|
48
|
+
resource.errors.add(:base, :not_found)
|
49
|
+
render 'new'
|
50
|
+
end
|
51
|
+
|
52
|
+
format.any { head :not_found }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Janus
|
2
|
+
module Helpers
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
helper_method :signed_in?
|
7
|
+
|
8
|
+
rescue_from Janus::NotAuthenticated do |exception|
|
9
|
+
respond_to do |format|
|
10
|
+
format.html { redirect_to send("new_#{exception.scope}_session_url") }
|
11
|
+
format.any { head :unauthorized }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def janus
|
17
|
+
@janus ||= Janus::Manager.new(request, cookies)
|
18
|
+
end
|
19
|
+
|
20
|
+
def handle_unverified_requests
|
21
|
+
janus.logout
|
22
|
+
end
|
23
|
+
|
24
|
+
def signed_in?(scope)
|
25
|
+
janus.authenticate?(scope)
|
26
|
+
end
|
27
|
+
|
28
|
+
module ClassMethods
|
29
|
+
def janus(*scopes)
|
30
|
+
scopes.each do |scope|
|
31
|
+
class_eval <<-EOV
|
32
|
+
helper_method :#{scope}_signed_in?, :current_#{scope}, :#{scope}_session
|
33
|
+
|
34
|
+
def authenticate_#{scope}!
|
35
|
+
janus.authenticate!(:#{scope})
|
36
|
+
end
|
37
|
+
|
38
|
+
def current_#{scope}
|
39
|
+
@current_#{scope} ||= janus.authenticate(:#{scope})
|
40
|
+
end
|
41
|
+
|
42
|
+
def #{scope}_signed_in?
|
43
|
+
janus.authenticate?(:#{scope})
|
44
|
+
end
|
45
|
+
|
46
|
+
def #{scope}_session
|
47
|
+
janus.session(:#{scope}) if #{scope}_signed_in?
|
48
|
+
end
|
49
|
+
EOV
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Janus
|
2
|
+
module InternalHelpers
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
helper_method :janus_scope, :resource, :resource_class, :resource_name
|
7
|
+
end
|
8
|
+
|
9
|
+
def authenticate!
|
10
|
+
send("authenticate_#{janus_scope}!")
|
11
|
+
end
|
12
|
+
|
13
|
+
def janus_scope
|
14
|
+
@janus_scope ||= self.class.name.split('::', 2).first.underscore.singularize
|
15
|
+
end
|
16
|
+
|
17
|
+
def resource
|
18
|
+
instance_variable_get(:"@#{janus_scope}")
|
19
|
+
end
|
20
|
+
|
21
|
+
def resource=(value)
|
22
|
+
instance_variable_set(:"@#{janus_scope}", value)
|
23
|
+
end
|
24
|
+
|
25
|
+
def resource_class
|
26
|
+
@resource_class ||= janus_scope.camelize.constantize
|
27
|
+
end
|
28
|
+
|
29
|
+
def resource_name
|
30
|
+
janus_scope
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
class Janus::PasswordsController < ApplicationController
|
2
|
+
include Janus::InternalHelpers
|
3
|
+
|
4
|
+
helper JanusHelper
|
5
|
+
|
6
|
+
def new
|
7
|
+
self.resource = resource_class.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def create
|
11
|
+
self.resource = resource_class.find_for_database_authentication(params[resource_name])
|
12
|
+
|
13
|
+
if resource
|
14
|
+
resource.generate_reset_password_token!
|
15
|
+
JanusMailer.reset_password_instructions(resource).deliver
|
16
|
+
|
17
|
+
respond_to do |format|
|
18
|
+
format.html { redirect_to root_url, :notice => t('flash.janus.passwords.create.email_sent') }
|
19
|
+
format.any { head :ok }
|
20
|
+
end
|
21
|
+
else
|
22
|
+
respond_to do |format|
|
23
|
+
format.html do
|
24
|
+
self.resource = resource_class.new
|
25
|
+
resource.errors.add(:base, :not_found)
|
26
|
+
render "new"
|
27
|
+
end
|
28
|
+
format.any { head :precondition_failed }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def edit
|
34
|
+
self.resource = resource_class.find_for_password_reset(params[:token])
|
35
|
+
redirect_to root_url, :alert => t('flash.janus.passwords.edit.alert') unless resource
|
36
|
+
end
|
37
|
+
|
38
|
+
def update
|
39
|
+
self.resource = resource_class.find_for_password_reset(params[resource_name][:reset_password_token])
|
40
|
+
|
41
|
+
if resource
|
42
|
+
if resource.reset_password!(params[resource_name])
|
43
|
+
respond_to do |format|
|
44
|
+
format.html { redirect_to root_url, :notice => t('flash.janus.passwords.update.password_updated') }
|
45
|
+
format.any { head :ok }
|
46
|
+
end
|
47
|
+
else
|
48
|
+
respond_to do |format|
|
49
|
+
format.html { render 'edit' }
|
50
|
+
format.any { head :precondition_failed }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
else
|
54
|
+
respond_to do |format|
|
55
|
+
format.html { redirect_to root_url, :alert => t('flash.janus.passwords.update.invalid_token') }
|
56
|
+
format.any { head :precondition_failed }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class Janus::RegistrationsController < ApplicationController
|
2
|
+
include Janus::InternalHelpers
|
3
|
+
|
4
|
+
helper JanusHelper
|
5
|
+
|
6
|
+
before_filter :authenticate!, :except => [:new, :create]
|
7
|
+
skip_before_filter :authenticate!, :only => [:new, :create]
|
8
|
+
|
9
|
+
def new
|
10
|
+
self.resource = resource_class.new
|
11
|
+
respond_with(resource)
|
12
|
+
end
|
13
|
+
|
14
|
+
def edit
|
15
|
+
self.resource = send("current_#{janus_scope}")
|
16
|
+
respond_with(resource)
|
17
|
+
end
|
18
|
+
|
19
|
+
def create
|
20
|
+
self.resource = resource_class.new(params[resource_name])
|
21
|
+
|
22
|
+
if resource.save
|
23
|
+
janus.login(resource, :scope => janus_scope, :rememberable => true)
|
24
|
+
JanusMailer.confirmation_instructions(resource).deliver if resource.respond_to?(:confirm!)
|
25
|
+
else
|
26
|
+
resource.clean_up_passwords
|
27
|
+
end
|
28
|
+
|
29
|
+
respond_with(resource, :location => after_sign_up_url(resource))
|
30
|
+
end
|
31
|
+
|
32
|
+
def update
|
33
|
+
params[resource_name].each do |key, value|
|
34
|
+
params[resource_name].delete(key) if value.blank? && [:password, :password_confirmation].include?(key.to_sym)
|
35
|
+
end
|
36
|
+
|
37
|
+
self.resource = send("current_#{janus_scope}")
|
38
|
+
resource.current_password = ""
|
39
|
+
resource.clean_up_passwords unless resource.update_attributes(params[resource_name])
|
40
|
+
respond_with(resource, :location => after_sign_up_url(resource))
|
41
|
+
end
|
42
|
+
|
43
|
+
def destroy
|
44
|
+
self.resource = send("current_#{janus_scope}")
|
45
|
+
janus.unset_user(janus_scope) if resource.destroy
|
46
|
+
|
47
|
+
respond_with(resource) do |format|
|
48
|
+
format.html { redirect_to root_url }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def after_sign_up_url(user)
|
53
|
+
user
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
|
3
|
+
class Janus::SessionsController < ApplicationController
|
4
|
+
include Janus::InternalHelpers
|
5
|
+
# include Janus::UrlHelpers
|
6
|
+
|
7
|
+
helper JanusHelper
|
8
|
+
# skip_before_filter :authenticate_user!
|
9
|
+
|
10
|
+
def new
|
11
|
+
params[:return_to] ||= request.env["HTTP_REFERER"]
|
12
|
+
|
13
|
+
if signed_in?(janus_scope)
|
14
|
+
redirect_after_sign_in(send("current_#{janus_scope}"))
|
15
|
+
else
|
16
|
+
self.resource = resource_class.new
|
17
|
+
respond_with(resource)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def create
|
22
|
+
self.resource = resource_class.find_for_database_authentication(params[resource_name])
|
23
|
+
|
24
|
+
if resource && resource.valid_password?(params[resource_name][:password])
|
25
|
+
janus.login(resource, :scope => janus_scope, :rememberable => params[:remember_me])
|
26
|
+
|
27
|
+
respond_to do |format|
|
28
|
+
format.html { redirect_after_sign_in(resource) }
|
29
|
+
format.any { head :ok }
|
30
|
+
end
|
31
|
+
else
|
32
|
+
respond_to do |format|
|
33
|
+
format.html do
|
34
|
+
self.resource ||= resource_class.new(params[resource_name])
|
35
|
+
resource.clean_up_passwords
|
36
|
+
resource.errors.add(:base, :not_found)
|
37
|
+
|
38
|
+
render "new", :status => :unauthorized
|
39
|
+
end
|
40
|
+
format.any { head :unauthorized }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def destroy
|
46
|
+
janus.logout(janus_scope)
|
47
|
+
|
48
|
+
respond_to do |format|
|
49
|
+
format.html { redirect_to after_sign_out_url(janus_scope) }
|
50
|
+
format.any { head :ok }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def after_sign_in_url(user)
|
55
|
+
user
|
56
|
+
end
|
57
|
+
|
58
|
+
def after_sign_out_url(scope)
|
59
|
+
root_url
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns true if remote host is known and redirect with an auth_token should
|
63
|
+
# be allowed or not. It must be overwritten by child class since it always
|
64
|
+
# returns true by default.
|
65
|
+
def valid_remote_host?(host)
|
66
|
+
true
|
67
|
+
end
|
68
|
+
|
69
|
+
# Either redirects the user to after_sign_in_url or to
|
70
|
+
# <tt>params[:return_to]</tt>. If return_to is an absolute URL, and not just
|
71
|
+
# a path, valid_remote_host? will be invoked to check if we should redirect
|
72
|
+
# to this URL or not --which is moslty of use for RemoteAuthenticatable to
|
73
|
+
# securize auth tokens from unknown domains.
|
74
|
+
def redirect_after_sign_in(user)
|
75
|
+
unless params[:return_to].blank?
|
76
|
+
return_to = Addressable::URI.parse(params[:return_to])
|
77
|
+
|
78
|
+
if return_to.host.nil? || return_to.host == request.host
|
79
|
+
redirect_to params[:return_to]
|
80
|
+
return
|
81
|
+
elsif valid_remote_host?(return_to.host)
|
82
|
+
if user.class.include?(Janus::Models::RemoteAuthenticatable)
|
83
|
+
query = return_to.query_values || {}
|
84
|
+
return_to.query_values = query.merge(user.class.remote_authentication_key => user.generate_remote_token!)
|
85
|
+
end
|
86
|
+
|
87
|
+
redirect_to return_to.to_s
|
88
|
+
return
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
redirect_to after_sign_in_url(user)
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Janus
|
2
|
+
module UrlHelpers
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
helper_method :session_url, :session_path, :new_session_url, :new_session_path, :destroy_session_url, :destroy_session_path,
|
7
|
+
:registration_url, :registration_path, :new_registration_url, :new_registration_path, :edit_registration_url, :edit_registration_path,
|
8
|
+
:confirmation_url, :confirmation_path, :new_confirmation_url, :new_confirmation_path,
|
9
|
+
:password_url, :password_path, :new_password_url, :new_password_path, :edit_password_url, :edit_password_path
|
10
|
+
end
|
11
|
+
|
12
|
+
[:url, :path].each do |suffix|
|
13
|
+
define_method("new_session_#{suffix}") do |scope, *args|
|
14
|
+
send("new_#{scope}_session_#{suffix}", *args)
|
15
|
+
end
|
16
|
+
|
17
|
+
define_method("session_#{suffix}") do |scope, *args|
|
18
|
+
send("#{scope}_session_#{suffix}", *args)
|
19
|
+
end
|
20
|
+
|
21
|
+
define_method("destroy_session_#{suffix}") do |scope, *args|
|
22
|
+
send("destroy_#{scope}_session_#{suffix}", *args)
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
define_method("registration_#{suffix}") do |scope, *args|
|
27
|
+
send("#{scope}_registration_#{suffix}", *args)
|
28
|
+
end
|
29
|
+
|
30
|
+
define_method("new_registration_#{suffix}") do |scope, *args|
|
31
|
+
send("new_#{scope}_registration_#{suffix}", *args)
|
32
|
+
end
|
33
|
+
|
34
|
+
define_method("edit_registration_#{suffix}") do |scope, *args|
|
35
|
+
send("edit_#{scope}_registration_#{suffix}", *args)
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
define_method("confirmation_#{suffix}") do |scope, *args|
|
40
|
+
send("#{scope}_confirmation_#{suffix}", *args)
|
41
|
+
end
|
42
|
+
|
43
|
+
define_method("new_confirmation_#{suffix}") do |scope, *args|
|
44
|
+
send("new_#{scope}_confirmation_#{suffix}", *args)
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
define_method("password_#{suffix}") do |scope, *args|
|
49
|
+
send("#{scope}_password_#{suffix}", *args)
|
50
|
+
end
|
51
|
+
|
52
|
+
define_method("new_password_#{suffix}") do |scope, *args|
|
53
|
+
send("new_#{scope}_password_#{suffix}", *args)
|
54
|
+
end
|
55
|
+
|
56
|
+
define_method("edit_password_#{suffix}") do |scope, *args|
|
57
|
+
send("edit_#{scope}_password_#{suffix}", *args)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/janus/helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
module JanusHelper
|
2
|
+
def janus_error_messages
|
3
|
+
return "" if resource.errors.empty?
|
4
|
+
|
5
|
+
content_tag :div, :id => 'error_explanation' do
|
6
|
+
content_tag :ul do
|
7
|
+
resource.errors.full_messages.map { |message| content_tag :li, message }.join.html_safe
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Janus::Manager.after_login do |user, manager, options|
|
2
|
+
if options[:rememberable] && user.respond_to?(:remember_me!)
|
3
|
+
user.remember_me!
|
4
|
+
|
5
|
+
remember_cookie_name = Janus::Strategies::Rememberable.remember_cookie_name(options[:scope])
|
6
|
+
manager.cookies[remember_cookie_name] = {
|
7
|
+
:value => user.remember_token,
|
8
|
+
:expires => user.class.remember_for.from_now
|
9
|
+
}
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
Janus::Manager.after_logout do |user, manager, options|
|
14
|
+
if user.respond_to?(:forget_me!)
|
15
|
+
user.forget_me!
|
16
|
+
|
17
|
+
remember_cookie_name = Janus::Strategies::Rememberable.remember_cookie_name(options[:scope])
|
18
|
+
manager.cookies.delete(remember_cookie_name)
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
Janus::Manager.after_login do |user, manager, options|
|
2
|
+
if user.respond_to?(:generate_session_token!)
|
3
|
+
user.generate_session_token! if user.session_token.nil?
|
4
|
+
|
5
|
+
session = manager.session(options[:scope])
|
6
|
+
session[:session_token] = user.session_token
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
Janus::Manager.after_authenticate do |user, manager, options|
|
11
|
+
if user.respond_to?(:session_token)
|
12
|
+
session = manager.session(options[:scope])
|
13
|
+
session[:session_token] = user.session_token
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
Janus::Manager.after_logout do |user, manager, options|
|
18
|
+
user.destroy_session_token! if user.respond_to?(:destroy_session_token!)
|
19
|
+
end
|
20
|
+
|
21
|
+
Janus::Manager.after_fetch do |user, manager, options|
|
22
|
+
if user.respond_to?(:session_token)
|
23
|
+
scope = options[:scope]
|
24
|
+
session = manager.session(scope)
|
25
|
+
manager.unset_user(scope) unless session[:session_token] == user.session_token
|
26
|
+
end
|
27
|
+
end
|