mbleigh-twitter-auth 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :minor: 1
3
- :patch: 1
3
+ :patch: 3
4
4
  :major: 0
@@ -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
@@ -0,0 +1,8 @@
1
+ # Gem Dependencies
2
+ config.gem 'oauth'
3
+ config.gem 'ezcrypto'
4
+
5
+ require 'json'
6
+ require 'twitter_auth'
7
+
8
+ RAILS_DEFAULT_LOGGER.info("** TwitterAuth initialized properly.")
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.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: