mbleigh-twitter-auth 0.0.2 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +66 -35
- data/VERSION.yml +2 -2
- data/generators/twitter_auth/USAGE +12 -0
- data/generators/twitter_auth/templates/migration.rb +29 -20
- data/generators/twitter_auth/templates/twitter_auth.yml +38 -0
- data/generators/twitter_auth/templates/user.rb +4 -6
- data/generators/twitter_auth/twitter_auth_generator.rb +31 -7
- data/lib/twitter_auth.rb +65 -1
- data/lib/twitter_auth/controller_extensions.rb +32 -168
- data/lib/twitter_auth/cryptify.rb +18 -7
- data/lib/twitter_auth/dispatcher/basic.rb +45 -0
- data/lib/twitter_auth/dispatcher/oauth.rb +23 -0
- data/spec/controllers/controller_extensions_spec.rb +146 -0
- data/spec/controllers/sessions_controller_spec.rb +206 -0
- data/spec/fixtures/config/twitter_auth.yml +17 -0
- data/spec/fixtures/factories.rb +18 -0
- data/spec/fixtures/fakeweb.rb +18 -0
- data/spec/fixtures/twitter.rb +5 -0
- data/spec/models/twitter_auth/basic_user_spec.rb +122 -0
- data/spec/models/twitter_auth/generic_user_spec.rb +48 -0
- data/spec/models/twitter_auth/oauth_user_spec.rb +85 -0
- data/spec/schema.rb +37 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +41 -0
- data/spec/twitter_auth/cryptify_spec.rb +51 -0
- data/spec/twitter_auth/dispatcher/basic_spec.rb +63 -0
- data/spec/twitter_auth/dispatcher/oauth_spec.rb +52 -0
- data/spec/twitter_auth_spec.rb +129 -0
- metadata +57 -8
data/README.markdown
CHANGED
@@ -1,52 +1,83 @@
|
|
1
1
|
TwitterAuth
|
2
2
|
===========
|
3
3
|
|
4
|
-
TwitterAuth
|
5
|
-
as an SSO provider. This is obviously most useful and therefore targeted at
|
6
|
-
apps that intend to heavily use the Twitter API.
|
4
|
+
TwitterAuth aims to provide a complete authentication and API access solution for creating Twitter applications in Rails. It provides a generator and all of the necessary components to use Twitter as the sole authentication provider for an application using either Twitter's OAuth or HTTP Basic authentication strategies.
|
7
5
|
|
8
|
-
|
9
|
-
|
6
|
+
Installation
|
7
|
+
============
|
10
8
|
|
11
|
-
|
12
|
-
---------------
|
9
|
+
You can include TwitterAuth as a gem in your project like so:
|
13
10
|
|
14
|
-
|
11
|
+
config.gem 'mbleigh-twitter-auth', :source => 'http://gems.github.com'
|
12
|
+
|
13
|
+
Or you can install it as a traditional Rails plugin:
|
15
14
|
|
16
|
-
config.gem 'mbleigh-twitter-auth', :source => 'http://gems.github.com/'
|
17
|
-
|
18
|
-
OR
|
19
|
-
|
20
15
|
script/plugin install git://github.com/mbleigh/twitter-auth.git
|
21
16
|
|
22
|
-
|
23
|
-
|
17
|
+
Note that because TwitterAuth utilizes Rails Engines functionality introduced in Rails 2.3, it will not work with earlier versions of Rails.
|
18
|
+
|
19
|
+
**NOTE:** TwitterAuth requires Rails version 2.3 or later because it makes extensive use of the new support for Rails Engines. Previous versions of Rails are not supported.
|
20
|
+
|
21
|
+
Usage
|
22
|
+
=====
|
23
|
+
|
24
|
+
To utilize TwitterAuth in your application you will need to run the generator:
|
25
|
+
|
26
|
+
script/generate twitter_auth [--oauth (default) | --basic]
|
27
|
+
|
28
|
+
This will generate a migration as well as set up the stubs needed to use the Rails Engines controllers and models set up by TwitterAuth. It will also create a User class that inherits from TwitterUser, abstracting away all of the Twitter authentication functionality and leaving you a blank slate to work with for your application.
|
29
|
+
|
30
|
+
Finally, it will create a configuration file in `config/twitter_auth.yml` in which you should input your OAuth consumer key and secret (if using the OAuth strategy) as well as a custom callback for development (the `oauth_callback` option is where Twitter will send the browser after authentication is complete. If you leave it blank Twitter will send it to the URL set up when you registered your application).
|
31
|
+
|
32
|
+
Usage Basics
|
33
|
+
------------
|
34
|
+
|
35
|
+
If you need more information about how to use OAuth with Twitter, please visit Twitter's [OAuth FAQ](http://apiwiki.twitter.com/OAuth-FAQ).
|
36
|
+
|
37
|
+
TwitterAuth borrows heavily from [Restful Authentication](http://github.com/technoweenie/restful-authentication) for its API because it's simple and well-known. Here are some of the familiar methods that are available:
|
38
|
+
|
39
|
+
* `login_required`: a before filter that can be added to a controller to require that a user logs in before he/she can view the page.
|
40
|
+
* `current_user`: returns the logged in user if one exists, otherwise returns `nil`.
|
41
|
+
* `logged_in?`: true if logged in, false otherwise.
|
42
|
+
* `redirect_back_or_default(url)`: redirects to the location where `store_location` was last called or the specified default URL.
|
43
|
+
* `store_location`: store the current URL for returning to when a `redirect_back_or_default` is called.
|
44
|
+
* `authorized?`: override this to add fine-grained access control for when `login_required` is already called.
|
45
|
+
|
46
|
+
Accessing the Twitter API
|
47
|
+
-------------------------
|
48
|
+
|
49
|
+
Obviously if you're using Twitter as an authentication strategy you probably have interest in accessing Twitter API information as well. Because I wasn't really satisfied with either of the popular Twitter API Ruby libraries ([Twitter4R](http://twitter4r.rubyforge.org) and [Twitter](http://twitter.rubyforge.org)) and also because neither support OAuth (yet), I decided to go with a simple, dependency-free API implementation.
|
50
|
+
|
51
|
+
The `User` class will have a `twitter` method that provides a generic dispatcher with HTTP verb commands available (`get`, `put`, `post`, and `delete`). These are automatically initialized to the `base_url` you specified in the `twitter_auth.yml` file, so you need only specify a path. Additionally, it will automatically append a .json extension and parse the JSON if you don't provide (it returns strings for XML because, well, I don't like XML and don't feel like parsing it).
|
52
|
+
|
53
|
+
# This code will work with the OAuth and Basic strategies alike.
|
54
|
+
user = User.find_by_login('mbleigh')
|
55
|
+
|
56
|
+
user.twitter.get('/account/verify_credentials')
|
57
|
+
# => {'screen_name' => 'mbleigh', 'name' => 'Michael Bleigh' ... }
|
58
|
+
|
59
|
+
user.twitter.post('/statuses/update.json', 'status' => 'This is my status.')
|
60
|
+
# => {"user"=>{"login" => "mbleigh" ... }, "text"=>"This is my status.", "id"=>1234567890 ... }
|
61
|
+
|
62
|
+
This area of the code is still a little raw, but hopefully will evolve to be a little more user-friendly as TwitterAuth matures. In the meantime, it's a perfectly workable foundation library, and the fact that it works the same with OAuth and HTTP Basic makes it all the better!
|
63
|
+
|
64
|
+
Customizing TwitterAuth
|
65
|
+
-----------------------
|
24
66
|
|
25
|
-
|
26
|
-
|
27
|
-
If you look in the migration you will see that there are some information
|
28
|
-
fields pre-populated (name, location, etc). These will automatically be
|
29
|
-
retrieved from Twitter at each login and therefor kept both accessible
|
30
|
-
and fresh for your usage.
|
67
|
+
There are a number of hooks to extend the functionality of TwitterAuth. Here is a brief description of each of them.
|
31
68
|
|
32
|
-
|
33
|
-
of restful-auth controller helpers such as:
|
69
|
+
### Controller Methods
|
34
70
|
|
35
|
-
|
36
|
-
* current_user
|
37
|
-
* logged_in?
|
71
|
+
TwitterAuth provides some default controller methods that may be overridden in your `ApplicationController` to behave differently.
|
38
72
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
in user has never logged in before.
|
73
|
+
* `authentication_failed(message)`: called when Twitter authorization has failed during the process. By default, simply redirects to the site root and sets the `flash[:error]`.
|
74
|
+
* `authentication_succeeded(message=default)`: called when Twitter authorization has completed successfully. By default, simply redirects to the site root and sets the `flash[:notice]`.
|
75
|
+
* `access_denied`: what happens when the `login_required` before filter fails. By default it stores the current location to return to and redirects to the login process.
|
43
76
|
|
44
|
-
Caveats
|
45
|
-
-------
|
46
77
|
|
47
|
-
|
48
|
-
|
49
|
-
drastically even in the near future.
|
78
|
+
Copyright
|
79
|
+
---------
|
50
80
|
|
81
|
+
**TwitterAuth** is Copyright (c) 2009 [Michael Bleigh](http://www.mbleigh.com) and [Intridea, Inc.](http://www.intridea.com/), released under the MIT License.
|
51
82
|
|
52
|
-
|
83
|
+
TwitterAuth is not affiliated with Twitter, Inc.
|
data/VERSION.yml
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
TwitterAuth Generator
|
2
|
+
=====================
|
3
|
+
|
4
|
+
The TwitterAuth generator allows you to generate the components necessary to implement Twitter as a Single Sign-On provider for your site.
|
5
|
+
|
6
|
+
To run it, you simply need to call it:
|
7
|
+
|
8
|
+
script/generate twitter_auth
|
9
|
+
|
10
|
+
This will generate the migration necessary for the users table as well as generate a User model that extends the appropriate TwitterAuth model template and a config/twitter.yml that allows you to set your OAuth consumer key and secret.
|
11
|
+
|
12
|
+
By default, TwitterAuth uses OAuth as its authentication strategy. If you wish to use HTTP Basic you can pass in the --basic option.
|
@@ -1,33 +1,42 @@
|
|
1
1
|
class TwitterAuthMigration < ActiveRecord::Migration
|
2
2
|
def self.up
|
3
3
|
create_table :users do |t|
|
4
|
-
t.string
|
5
|
-
|
6
|
-
t.string
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
t.string
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
4
|
+
t.string :login
|
5
|
+
<% if options[:oauth] -%>
|
6
|
+
t.string :access_token
|
7
|
+
t.string :access_secret
|
8
|
+
<% elsif options[:basic] -%>
|
9
|
+
t.binary :crypted_password
|
10
|
+
t.string :salt
|
11
|
+
<% end -%>
|
12
|
+
|
13
|
+
# This information is automatically kept
|
14
|
+
# in-sync at each login of the user. You
|
15
|
+
# may remove any/all of these columns.
|
16
|
+
t.string :name
|
17
|
+
t.string :location
|
18
|
+
t.string :description
|
19
|
+
t.string :profile_image_url
|
20
|
+
t.string :url
|
15
21
|
t.boolean :protected
|
16
|
-
t.string
|
17
|
-
t.string
|
18
|
-
t.string
|
19
|
-
t.string
|
20
|
-
t.string
|
22
|
+
t.string :profile_background_color
|
23
|
+
t.string :profile_sidebar_fill_color
|
24
|
+
t.string :profile_link_color
|
25
|
+
t.string :profile_sidebar_border_color
|
26
|
+
t.string :profile_text_color
|
21
27
|
t.integer :friends_count
|
22
28
|
t.integer :statuses_count
|
23
|
-
t.integer :followers_count
|
24
|
-
t.integer :favourites_count
|
29
|
+
t.integer :followers_count
|
30
|
+
t.integer :favourites_count
|
31
|
+
|
32
|
+
# Probably don't need both, but they're here.
|
25
33
|
t.integer :utc_offset
|
26
|
-
|
34
|
+
t.string :time_zone
|
35
|
+
|
27
36
|
t.timestamps
|
28
37
|
end
|
29
38
|
end
|
30
|
-
|
39
|
+
|
31
40
|
def self.down
|
32
41
|
drop_table :users
|
33
42
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<% if options[:oauth] -%>
|
2
|
+
development:
|
3
|
+
strategy: oauth
|
4
|
+
base_url: "https://twitter.com"
|
5
|
+
api_timeout: 10
|
6
|
+
oauth_consumer_key: devkey
|
7
|
+
oauth_consumer_secret: devsecret
|
8
|
+
oauth_callback: "http://localhost:3000/oauth_callback"
|
9
|
+
test:
|
10
|
+
strategy: oauth
|
11
|
+
base_url: "https://twitter.com"
|
12
|
+
api_timeout: 10
|
13
|
+
oauth_consumer_key: testkey
|
14
|
+
oauth_consumer_secret: testsecret
|
15
|
+
oauth_callback: "http://localhost:3000/oauth_callback"
|
16
|
+
production:
|
17
|
+
strategy: oauth
|
18
|
+
api_timeout: 10
|
19
|
+
base_url: "https://twitter.com"
|
20
|
+
oauth_consumer_key: prodkey
|
21
|
+
oauth_consumer_secret: prodsecret
|
22
|
+
<% else -%>
|
23
|
+
development:
|
24
|
+
strategy: basic
|
25
|
+
api_timeout: 10
|
26
|
+
base_url: "https://twitter.com"
|
27
|
+
# randomly generated key for encrypting Twitter passwords
|
28
|
+
encryption_key: "<%= key = ActiveSupport::SecureRandom.hex(12) %>"
|
29
|
+
test:
|
30
|
+
strategy: basic
|
31
|
+
api_timeout: 10
|
32
|
+
base_url: "https://twitter.com"
|
33
|
+
encryption_key: "<%= key %>"
|
34
|
+
production:
|
35
|
+
strategy: basic
|
36
|
+
api_timeout: 10
|
37
|
+
encryption_key: "<%= key %>"
|
38
|
+
<% end %>
|
@@ -1,7 +1,5 @@
|
|
1
1
|
class User < TwitterAuth::GenericUser
|
2
|
-
#
|
3
|
-
#
|
4
|
-
#
|
5
|
-
|
6
|
-
# already utilizes the 'users' table.
|
7
|
-
end
|
2
|
+
# Extend and define your user model as you see fit.
|
3
|
+
# All of the authentication logic is handled by the
|
4
|
+
# parent TwitterAuth::GenericUser class.
|
5
|
+
end
|
@@ -1,10 +1,34 @@
|
|
1
|
-
class TwitterAuthGenerator < Rails::Generator::Base
|
2
|
-
|
3
|
-
|
1
|
+
class TwitterAuthGenerator < Rails::Generator::Base
|
2
|
+
default_options :oauth => true, :basic => false
|
3
|
+
|
4
|
+
def manifest
|
5
|
+
record do |m|
|
4
6
|
m.class_collisions 'User'
|
5
|
-
|
6
|
-
m.migration_template 'migration.rb', 'db/migrate', :migration_file_name =>
|
7
|
-
m.template 'user.rb', File.join('app
|
7
|
+
|
8
|
+
m.migration_template 'migration.rb', 'db/migrate', :migration_file_name => 'twitter_auth_migration'
|
9
|
+
m.template 'user.rb', File.join('app','models','user.rb')
|
10
|
+
m.template 'twitter_auth.yml', File.join('config','twitter_auth.yml')
|
8
11
|
end
|
9
12
|
end
|
10
|
-
|
13
|
+
|
14
|
+
protected
|
15
|
+
|
16
|
+
def banner
|
17
|
+
"Usage: #{$0} twitter_auth"
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_options!(opt)
|
21
|
+
opt.separator ''
|
22
|
+
opt.separator 'Options:'
|
23
|
+
|
24
|
+
opt.on('-O', '--oauth', 'Use the OAuth authentication strategy to connect to Twitter. (default)') { |v|
|
25
|
+
options[:oauth] = v
|
26
|
+
options[:basic] = !v
|
27
|
+
}
|
28
|
+
|
29
|
+
opt.on('-B', '--basic', 'Use the HTTP Basic authentication strategy to connect to Twitter.') { |v|
|
30
|
+
options[:basic] = v
|
31
|
+
options[:oauth] = !v
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
data/lib/twitter_auth.rb
CHANGED
@@ -1,5 +1,69 @@
|
|
1
1
|
module TwitterAuth
|
2
2
|
class Error < StandardError; end
|
3
|
+
|
4
|
+
def self.config(environment=RAILS_ENV)
|
5
|
+
@config ||= {}
|
6
|
+
@config[environment] ||= YAML.load(File.open(RAILS_ROOT + '/config/twitter_auth.yml').read)[environment]
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.base_url
|
10
|
+
config['base_url'] || 'https://twitter.com'
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.api_timeout
|
14
|
+
config['api_timeout'] || 10
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.encryption_key
|
18
|
+
raise TwitterAuth::Cryptify::Error, 'You must specify an encryption_key in config/twitter_auth.yml' if config['encryption_key'].blank?
|
19
|
+
config['encryption_key']
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.oauth_callback?
|
23
|
+
config.key?('oauth_callback')
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.oauth_callback
|
27
|
+
config['oauth_callback']
|
28
|
+
end
|
29
|
+
|
30
|
+
# The authentication strategy employed by this
|
31
|
+
# application. Set in +config/twitter.yml+ as
|
32
|
+
# strategy; valid options are oauth or basic.
|
33
|
+
def self.strategy
|
34
|
+
strat = config['strategy']
|
35
|
+
raise ArgumentError, 'Invalid TwitterAuth Strategy: Valid strategies are oauth and basic.' unless %w(oauth basic).include?(strat)
|
36
|
+
strat.to_sym
|
37
|
+
rescue Errno::ENOENT
|
38
|
+
:oauth
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.oauth?
|
42
|
+
strategy == :oauth
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.basic?
|
46
|
+
strategy == :basic
|
47
|
+
end
|
48
|
+
|
49
|
+
# The OAuth consumer used by TwitterAuth for authentication. The consumer key and secret are set in your application's +config/twitter.yml+
|
50
|
+
def self.consumer
|
51
|
+
OAuth::Consumer.new(
|
52
|
+
config['oauth_consumer_key'],
|
53
|
+
config['oauth_consumer_secret'],
|
54
|
+
:site => TwitterAuth.base_url
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.net
|
59
|
+
uri = URI.parse(TwitterAuth.base_url)
|
60
|
+
net = Net::HTTP.new(uri.host, uri.port)
|
61
|
+
net.use_ssl = uri.scheme == 'https'
|
62
|
+
net.read_timeout = TwitterAuth.api_timeout
|
63
|
+
net
|
64
|
+
end
|
3
65
|
end
|
4
66
|
|
5
|
-
require 'twitter_auth/controller_extensions'
|
67
|
+
require 'twitter_auth/controller_extensions'
|
68
|
+
require 'twitter_auth/cryptify'
|
69
|
+
require 'twitter_auth/dispatcher/oauth'
|
@@ -1,200 +1,64 @@
|
|
1
1
|
module TwitterAuth
|
2
|
-
#
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# no credit is due here.
|
2
|
+
# These methods borrow HEAVILY from Rick Olsen's
|
3
|
+
# Restful Authentication. All cleverness props
|
4
|
+
# go to him, not me.
|
6
5
|
module ControllerExtensions
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
def self.included(base)
|
7
|
+
base.send :helper_method, :current_user, :logged_in?, :authorized?
|
8
|
+
end
|
9
|
+
|
10
|
+
protected
|
11
|
+
|
12
|
+
def authentication_failed(message, destination='/')
|
13
|
+
flash[:error] = message
|
14
|
+
redirect_to destination
|
15
|
+
end
|
16
|
+
|
17
|
+
def authentication_succeeded(message = 'You have logged in successfully.', destination = '/')
|
18
|
+
flash[:notice] = message
|
19
|
+
redirect_to destination
|
11
20
|
end
|
12
21
|
|
13
|
-
# Accesses the current user from the session.
|
14
|
-
# Future calls avoid the database because nil is not equal to false.
|
15
22
|
def current_user
|
16
|
-
@current_user ||= (
|
23
|
+
@current_user ||= User.find_by_id(session[:user_id])
|
17
24
|
end
|
18
25
|
|
19
|
-
# Store the given user id in the session.
|
20
26
|
def current_user=(new_user)
|
21
|
-
session[:user_id] = new_user
|
22
|
-
@current_user = new_user
|
27
|
+
session[:user_id] = new_user.id
|
28
|
+
@current_user = new_user
|
23
29
|
end
|
24
30
|
|
25
|
-
|
26
|
-
|
27
|
-
# Override this method in your controllers if you want to restrict access
|
28
|
-
# to only a few actions or if you want to check if the user
|
29
|
-
# has the correct rights.
|
30
|
-
#
|
31
|
-
# Example:
|
32
|
-
#
|
33
|
-
# # only allow nonbobs
|
34
|
-
# def authorized?
|
35
|
-
# current_user.login != "bob"
|
36
|
-
# end
|
37
|
-
#
|
38
|
-
def authorized?(action=nil, resource=nil, *args)
|
39
|
-
logged_in?
|
31
|
+
def authorized?
|
32
|
+
!!current_user
|
40
33
|
end
|
41
34
|
|
42
|
-
# Filter method to enforce a login requirement.
|
43
|
-
#
|
44
|
-
# To require logins for all actions, use this in your controllers:
|
45
|
-
#
|
46
|
-
# before_filter :login_required
|
47
|
-
#
|
48
|
-
# To require logins for specific actions, use this in your controllers:
|
49
|
-
#
|
50
|
-
# before_filter :login_required, :only => [ :edit, :update ]
|
51
|
-
#
|
52
|
-
# To skip this in a subclassed controller:
|
53
|
-
#
|
54
|
-
# skip_before_filter :login_required
|
55
|
-
#
|
56
35
|
def login_required
|
57
|
-
authorized? || access_denied
|
36
|
+
authorized? || access_denied
|
58
37
|
end
|
59
38
|
|
60
|
-
# Redirect as appropriate when an access request fails.
|
61
|
-
#
|
62
|
-
# The default action is to redirect to the login screen.
|
63
|
-
#
|
64
|
-
# Override this method in your controllers if you want to have special
|
65
|
-
# behavior in case the user is not authorized
|
66
|
-
# to access the requested action. For example, a popup window might
|
67
|
-
# simply close itself.
|
68
39
|
def access_denied
|
69
|
-
|
70
|
-
|
71
|
-
store_location
|
72
|
-
redirect_to new_session_path
|
73
|
-
end
|
74
|
-
# format.any doesn't work in rails version < http://dev.rubyonrails.org/changeset/8987
|
75
|
-
# you may want to change format.any to e.g. format.any(:js, :xml)
|
76
|
-
format.any(:xml, :json) do
|
77
|
-
request_http_basic_authentication 'Web Password'
|
78
|
-
end
|
79
|
-
end
|
40
|
+
store_location
|
41
|
+
redirect_to login_path
|
80
42
|
end
|
81
43
|
|
82
|
-
# Store the URI of the current request in the session.
|
83
|
-
#
|
84
|
-
# We can return to this location by calling #redirect_back_or_default.
|
85
44
|
def store_location
|
86
45
|
session[:return_to] = request.request_uri
|
87
46
|
end
|
88
47
|
|
89
|
-
|
90
|
-
|
91
|
-
# after_filter :store_location, :only => [:index, :new, :show, :edit]
|
92
|
-
# for any controller you want to be bounce-backable.
|
93
|
-
def redirect_back_or_default(default=nil)
|
94
|
-
redirect_to(session[:return_to] || default || self.default_location)
|
48
|
+
def redirect_back_or_default(default)
|
49
|
+
redirect_to(session[:return_to] || default)
|
95
50
|
session[:return_to] = nil
|
96
51
|
end
|
97
|
-
|
98
|
-
# Override this method with what you want your 'default default'
|
99
|
-
# to be (where it will redirect if there's no back and no explicit
|
100
|
-
# default).
|
101
|
-
def default_location
|
102
|
-
'/'
|
103
|
-
end
|
104
52
|
|
105
|
-
|
106
|
-
|
107
|
-
def self.included(base)
|
108
|
-
base.send :helper_method, :current_user, :logged_in?, :authorized? if base.respond_to? :helper_method
|
109
|
-
end
|
110
|
-
|
111
|
-
#
|
112
|
-
# Login
|
113
|
-
#
|
114
|
-
|
115
|
-
# Called from #current_user. First attempt to login by the user id stored in the session.
|
116
|
-
def login_from_session
|
117
|
-
self.current_user = User.find_by_id(session[:user_id]) if session[:user_id]
|
118
|
-
end
|
119
|
-
|
120
|
-
# Called from #current_user. Now, attempt to login by basic authentication information.
|
121
|
-
def login_from_basic_auth
|
122
|
-
authenticate_with_http_basic do |login, password|
|
123
|
-
self.current_user = User.authenticate(login, password)
|
124
|
-
end
|
53
|
+
def logged_in?
|
54
|
+
!!current_user
|
125
55
|
end
|
126
|
-
|
127
|
-
#
|
128
|
-
# Logout
|
129
|
-
#
|
130
56
|
|
131
|
-
# Called from #current_user. Finaly, attempt to login by an expiring token in the cookie.
|
132
|
-
# for the paranoid: we _should_ be storing user_token = hash(cookie_token, request IP)
|
133
|
-
# def login_from_cookie
|
134
|
-
# user = cookies[:auth_token] && User.find_by_remember_token(cookies[:auth_token])
|
135
|
-
# if user && user.remember_token?
|
136
|
-
# self.current_user = user
|
137
|
-
# handle_remember_cookie! false # freshen cookie token (keeping date)
|
138
|
-
# self.current_user
|
139
|
-
# end
|
140
|
-
# end
|
141
|
-
|
142
|
-
# This is ususally what you want; resetting the session willy-nilly wreaks
|
143
|
-
# havoc with forgery protection, and is only strictly necessary on login.
|
144
|
-
# However, **all session state variables should be unset here**.
|
145
57
|
def logout_keeping_session!
|
146
|
-
|
147
|
-
|
148
|
-
@current_user = false # not logged in, and don't do it for me
|
149
|
-
# kill_remember_cookie! # Kill client-side auth cookie
|
150
|
-
session[:user_id] = nil # keeps the session but kill our variable
|
151
|
-
# explicitly kill any other session variables you set
|
152
|
-
end
|
153
|
-
|
154
|
-
# The session should only be reset at the tail end of a form POST --
|
155
|
-
# otherwise the request forgery protection fails. It's only really necessary
|
156
|
-
# when you cross quarantine (logged-out to logged-in).
|
157
|
-
def logout_killing_session!
|
158
|
-
logout_keeping_session!
|
159
|
-
reset_session
|
58
|
+
@current_user = nil
|
59
|
+
session[:user_id] = nil
|
160
60
|
end
|
161
|
-
|
162
|
-
#
|
163
|
-
# Remember_me Tokens
|
164
|
-
#
|
165
|
-
# Cookies shouldn't be allowed to persist past their freshness date,
|
166
|
-
# and they should be changed at each login
|
167
|
-
|
168
|
-
# Cookies shouldn't be allowed to persist past their freshness date,
|
169
|
-
# and they should be changed at each login
|
170
|
-
|
171
|
-
# def valid_remember_cookie?
|
172
|
-
# return nil unless @current_user
|
173
|
-
# (@current_user.remember_token?) &&
|
174
|
-
# (cookies[:auth_token] == @current_user.remember_token)
|
175
|
-
# end
|
176
|
-
|
177
|
-
# Refresh the cookie auth token if it exists, create it otherwise
|
178
|
-
# def handle_remember_cookie! new_cookie_flag
|
179
|
-
# return unless @current_user
|
180
|
-
# case
|
181
|
-
# when valid_remember_cookie? then @current_user.refresh_token # keeping same expiry date
|
182
|
-
# when new_cookie_flag then @current_user.remember_me
|
183
|
-
# else @current_user.forget_me
|
184
|
-
# end
|
185
|
-
# send_remember_cookie!
|
186
|
-
# end
|
187
|
-
#
|
188
|
-
# def kill_remember_cookie!
|
189
|
-
# cookies.delete :auth_token
|
190
|
-
# end
|
191
|
-
#
|
192
|
-
# def send_remember_cookie!
|
193
|
-
# cookies[:auth_token] = {
|
194
|
-
# :value => @current_user.remember_token,
|
195
|
-
# :expires => @current_user.remember_token_expires_at }
|
196
|
-
# end
|
197
61
|
end
|
198
62
|
end
|
199
63
|
|
200
|
-
ActionController::Base.send
|
64
|
+
ActionController::Base.send(:include, TwitterAuth::ControllerExtensions)
|