mbleigh-twitter-auth 0.1.1 → 0.1.3
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.markdown +2 -0
- data/Rakefile +31 -0
- data/VERSION.yml +1 -1
- data/app/controllers/sessions_controller.rb +62 -0
- data/app/models/twitter_auth/basic_user.rb +63 -0
- data/app/models/twitter_auth/generic_user.rb +70 -0
- data/app/models/twitter_auth/oauth_user.rb +38 -0
- data/app/views/sessions/_login_form.html.erb +17 -0
- data/app/views/sessions/new.html.erb +5 -0
- data/config/routes.rb +6 -0
- data/rails/init.rb +8 -0
- metadata +25 -1
data/README.markdown
CHANGED
@@ -6,6 +6,8 @@ TwitterAuth aims to provide a complete authentication and API access solution fo
|
|
6
6
|
Installation
|
7
7
|
============
|
8
8
|
|
9
|
+
**NOTE:** The GemPlugin version of TwitterAuth is currently broken...Rails isn't picking up namespaced models in the Engines. I'm working on a fix, but please use the plugin version until then.
|
10
|
+
|
9
11
|
You can include TwitterAuth as a gem in your project like so:
|
10
12
|
|
11
13
|
config.gem 'mbleigh-twitter-auth', :source => 'http://gems.github.com'
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'spec/rake/spectask'
|
3
|
+
|
4
|
+
desc 'Default: run specs.'
|
5
|
+
task :default => :spec
|
6
|
+
|
7
|
+
desc 'Run the specs'
|
8
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
9
|
+
t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
|
10
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
11
|
+
end
|
12
|
+
|
13
|
+
begin
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |s|
|
16
|
+
s.name = "twitter-auth"
|
17
|
+
s.summary = "TwitterAuth is a Rails plugin gem that provides Single Sign-On capabilities for Rails applications via Twitter."
|
18
|
+
s.email = "michael@intridea.com"
|
19
|
+
s.homepage = "http://github.com/mbleigh/twitter-auth"
|
20
|
+
s.description = "TwitterAuth is a Rails plugin gem that provides Single Sign-On capabilities for Rails applications via Twitter. Both OAuth and HTTP Basic are supported."
|
21
|
+
s.files = FileList["[A-Z]*", "{bin,generators,lib,spec,config,app,rails}/**/*"]
|
22
|
+
s.add_dependency 'schacon-git'
|
23
|
+
|
24
|
+
s.authors = ["Michael Bleigh"]
|
25
|
+
s.add_dependency('oauth', '>= 0.3.1')
|
26
|
+
s.add_dependency('ezcrypto', '>= 0.7.2')
|
27
|
+
end
|
28
|
+
rescue LoadError
|
29
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
30
|
+
end
|
31
|
+
|
data/VERSION.yml
CHANGED
@@ -0,0 +1,62 @@
|
|
1
|
+
class SessionsController < ApplicationController
|
2
|
+
def new
|
3
|
+
if TwitterAuth.oauth?
|
4
|
+
@request_token = TwitterAuth.consumer.get_request_token
|
5
|
+
session[:request_token] = @request_token.token
|
6
|
+
session[:request_token_secret] = @request_token.secret
|
7
|
+
|
8
|
+
url = @request_token.authorize_url
|
9
|
+
url << "&oauth_callback=#{CGI.escape(TwitterAuth.oauth_callback)}" if TwitterAuth.oauth_callback?
|
10
|
+
redirect_to url
|
11
|
+
else
|
12
|
+
# we don't have to do anything, it's just a simple form for HTTP basic!
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def create
|
17
|
+
logout_keeping_session!
|
18
|
+
if user = User.authenticate(params[:login], params[:password])
|
19
|
+
self.current_user = user
|
20
|
+
authentication_succeeded and return
|
21
|
+
else
|
22
|
+
authentication_failed('Unable to verify your credentials through Twitter. Please try again.', '/login') and return
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def oauth_callback
|
27
|
+
unless session[:request_token] && session[:request_token_secret]
|
28
|
+
authentication_failed('No authentication information was found in the session. Please try again.') and return
|
29
|
+
end
|
30
|
+
|
31
|
+
unless params[:oauth_token].blank? || session[:request_token] == params[:oauth_token]
|
32
|
+
authentication_failed('Authentication information does not match session information. Please try again.') and return
|
33
|
+
end
|
34
|
+
|
35
|
+
@request_token = OAuth::RequestToken.new(TwitterAuth.consumer, session[:request_token], session[:request_token_secret])
|
36
|
+
|
37
|
+
@access_token = @request_token.get_access_token
|
38
|
+
|
39
|
+
# The request token has been invalidated
|
40
|
+
# so we nullify it in the session.
|
41
|
+
session[:request_token] = nil
|
42
|
+
session[:request_token_secret] = nil
|
43
|
+
|
44
|
+
@user = User.identify_or_create_from_access_token(@access_token)
|
45
|
+
|
46
|
+
session[:user_id] = @user.id
|
47
|
+
|
48
|
+
authentication_succeeded
|
49
|
+
rescue Net::HTTPServerException => e
|
50
|
+
case e.message
|
51
|
+
when '401 "Unauthorized"'
|
52
|
+
authentication_failed('This authentication request is no longer valid. Please try again.') and return
|
53
|
+
else
|
54
|
+
authentication_failed('There was a problem trying to authenticate you. Please try again.') and return
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def destroy
|
59
|
+
logout_keeping_session!
|
60
|
+
redirect_back_or_default('/')
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
module TwitterAuth
|
4
|
+
module BasicUser
|
5
|
+
def self.included(base)
|
6
|
+
base.class_eval do
|
7
|
+
attr_protected :crypted_password, :salt
|
8
|
+
end
|
9
|
+
|
10
|
+
base.extend TwitterAuth::BasicUser::ClassMethods
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
def verify_credentials(login, password)
|
15
|
+
response = TwitterAuth.net.start { |http|
|
16
|
+
request = Net::HTTP::Get.new('/account/verify_credentials.json')
|
17
|
+
request.basic_auth login, password
|
18
|
+
http.request(request)
|
19
|
+
}
|
20
|
+
|
21
|
+
if response.code == '200'
|
22
|
+
JSON.parse(response.body)
|
23
|
+
else
|
24
|
+
false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def authenticate(login, password)
|
29
|
+
if twitter_hash = verify_credentials(login, password)
|
30
|
+
user = identify_or_create_from_twitter_hash_and_password(twitter_hash, password)
|
31
|
+
user
|
32
|
+
else
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def identify_or_create_from_twitter_hash_and_password(twitter_hash, password)
|
38
|
+
if user = User.find_by_login(twitter_hash['screen_name'])
|
39
|
+
user.assign_twitter_attributes(twitter_hash)
|
40
|
+
user.password = password
|
41
|
+
user.save
|
42
|
+
user
|
43
|
+
else
|
44
|
+
user = User.new_from_twitter_hash(twitter_hash)
|
45
|
+
user.password = password
|
46
|
+
user.save
|
47
|
+
user
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def password=(new_password)
|
53
|
+
encrypted = TwitterAuth::Cryptify.encrypt(new_password)
|
54
|
+
self.crypted_password = encrypted[:encrypted_data]
|
55
|
+
self.salt = encrypted[:salt]
|
56
|
+
end
|
57
|
+
|
58
|
+
def password
|
59
|
+
TwitterAuth::Cryptify.decrypt(self.crypted_password, self.salt)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module TwitterAuth
|
2
|
+
class GenericUser < ActiveRecord::Base
|
3
|
+
attr_protected :login
|
4
|
+
|
5
|
+
TWITTER_ATTRIBUTES = [
|
6
|
+
:name,
|
7
|
+
:location,
|
8
|
+
:description,
|
9
|
+
:profile_image_url,
|
10
|
+
:url,
|
11
|
+
:protected,
|
12
|
+
:profile_background_color,
|
13
|
+
:profile_sidebar_fill_color,
|
14
|
+
:profile_link_color,
|
15
|
+
:profile_sidebar_border_color,
|
16
|
+
:profile_text_color,
|
17
|
+
:friends_count,
|
18
|
+
:statuses_count,
|
19
|
+
:followers_count,
|
20
|
+
:favourites_count,
|
21
|
+
:time_zone,
|
22
|
+
:utc_offset
|
23
|
+
]
|
24
|
+
|
25
|
+
validates_presence_of :login
|
26
|
+
validates_format_of :login, :with => /\A[a-z0-9_]+\z/
|
27
|
+
validates_length_of :login, :in => 1..15
|
28
|
+
validates_uniqueness_of :login
|
29
|
+
|
30
|
+
def self.table_name; 'users' end
|
31
|
+
|
32
|
+
def self.new_from_twitter_hash(hash)
|
33
|
+
raise ArgumentError, 'Invalid hash: must include screen_name.' unless hash.key?('screen_name')
|
34
|
+
|
35
|
+
user = User.new
|
36
|
+
user.login = hash['screen_name']
|
37
|
+
|
38
|
+
TWITTER_ATTRIBUTES.each do |att|
|
39
|
+
user.send("#{att}=", hash[att.to_s]) if user.respond_to?("#{att}=")
|
40
|
+
end
|
41
|
+
|
42
|
+
user
|
43
|
+
end
|
44
|
+
|
45
|
+
def assign_twitter_attributes(hash)
|
46
|
+
TWITTER_ATTRIBUTES.each do |att|
|
47
|
+
send("#{att}=", hash[att.to_s]) if respond_to?("#{att}=")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def update_twitter_attributes(hash)
|
52
|
+
assign_twitter_attributes(hash)
|
53
|
+
save
|
54
|
+
end
|
55
|
+
|
56
|
+
if TwitterAuth.oauth?
|
57
|
+
include TwitterAuth::OauthUser
|
58
|
+
else
|
59
|
+
include TwitterAuth::BasicUser
|
60
|
+
end
|
61
|
+
|
62
|
+
def twitter
|
63
|
+
if TwitterAuth.oauth?
|
64
|
+
TwitterAuth::Dispatcher::Oauth.new(self)
|
65
|
+
else
|
66
|
+
TwitterAuth::Dispatcher::Basic.new(self)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module TwitterAuth
|
2
|
+
module OauthUser
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
attr_protected :access_token, :access_secret
|
6
|
+
end
|
7
|
+
|
8
|
+
base.extend TwitterAuth::OauthUser::ClassMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
def identify_or_create_from_access_token(token, secret=nil)
|
13
|
+
raise ArgumentError, 'Must authenticate with an OAuth::AccessToken or the string access token and secret.' unless (token && secret) || token.is_a?(OAuth::AccessToken)
|
14
|
+
|
15
|
+
user_info = JSON.parse(token.get('/account/verify_credentials.json').body)
|
16
|
+
|
17
|
+
if user = User.find_by_login(user_info['screen_name'])
|
18
|
+
user.update_twitter_attributes(user_info)
|
19
|
+
user
|
20
|
+
else
|
21
|
+
User.create_from_twitter_hash_and_token(user_info, token)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_from_twitter_hash_and_token(user_info, access_token)
|
26
|
+
user = User.new_from_twitter_hash(user_info)
|
27
|
+
user.access_token = access_token.token
|
28
|
+
user.access_secret = access_token.secret
|
29
|
+
user.save
|
30
|
+
user
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def token
|
35
|
+
OAuth::AccessToken.new(TwitterAuth.consumer, access_token, access_secret)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<% form_tag session_path, :id => 'login_form' do %>
|
2
|
+
<div class='field'>
|
3
|
+
<label for='login'>Twitter Username:</label>
|
4
|
+
<%= text_field_tag 'login', nil, :class => 'text_field' %>
|
5
|
+
</div>
|
6
|
+
<div class='field'>
|
7
|
+
<label for='password'>Password:</label>
|
8
|
+
<%= password_field_tag 'password', nil, :class => 'password_field' %>
|
9
|
+
</div>
|
10
|
+
<!--<div class='checkbox-field'>
|
11
|
+
<%= check_box_tag 'remember_me' %> <label for='remember_me'>Keep Me Logged In</label>
|
12
|
+
</div>-->
|
13
|
+
<div class='field submit'>
|
14
|
+
<%= submit_tag 'Log In', :class => 'submit' %>
|
15
|
+
</div>
|
16
|
+
<% end %>
|
17
|
+
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<h1>Log In Via Twitter</h1>
|
2
|
+
|
3
|
+
<p>This application utilizes your Twitter username and password for authentication; you do not have to create a separate account here. To log in, just enter your Twitter credentials in the form below.</p>
|
4
|
+
|
5
|
+
<%= render :partial => 'login_form' %>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
ActionController::Routing::Routes.draw do |map|
|
2
|
+
map.login '/login', :controller => 'sessions', :action => 'new'
|
3
|
+
map.logout '/logout', :controller => 'sessions', :action => 'destroy'
|
4
|
+
map.resource :session
|
5
|
+
map.oauth_callback '/oauth_callback', :controller => 'sessions', :action => 'oauth_callback'
|
6
|
+
end
|
data/rails/init.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mbleigh-twitter-auth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Bleigh
|
@@ -12,6 +12,16 @@ cert_chain: []
|
|
12
12
|
date: 2009-03-20 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: schacon-git
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
15
25
|
- !ruby/object:Gem::Dependency
|
16
26
|
name: oauth
|
17
27
|
type: :runtime
|
@@ -41,6 +51,7 @@ extensions: []
|
|
41
51
|
extra_rdoc_files:
|
42
52
|
- README.markdown
|
43
53
|
files:
|
54
|
+
- Rakefile
|
44
55
|
- README.markdown
|
45
56
|
- VERSION.yml
|
46
57
|
- generators/twitter_auth
|
@@ -84,6 +95,19 @@ files:
|
|
84
95
|
- spec/twitter_auth/dispatcher/basic_spec.rb
|
85
96
|
- spec/twitter_auth/dispatcher/oauth_spec.rb
|
86
97
|
- spec/twitter_auth_spec.rb
|
98
|
+
- config/routes.rb
|
99
|
+
- app/controllers
|
100
|
+
- app/controllers/sessions_controller.rb
|
101
|
+
- app/models
|
102
|
+
- app/models/twitter_auth
|
103
|
+
- app/models/twitter_auth/basic_user.rb
|
104
|
+
- app/models/twitter_auth/generic_user.rb
|
105
|
+
- app/models/twitter_auth/oauth_user.rb
|
106
|
+
- app/views
|
107
|
+
- app/views/sessions
|
108
|
+
- app/views/sessions/_login_form.html.erb
|
109
|
+
- app/views/sessions/new.html.erb
|
110
|
+
- rails/init.rb
|
87
111
|
has_rdoc: true
|
88
112
|
homepage: http://github.com/mbleigh/twitter-auth
|
89
113
|
post_install_message:
|