authpwn_rails 0.3.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/.document +5 -0
- data/.gitignore +24 -0
- data/.project +17 -0
- data/LICENSE +20 -0
- data/README.rdoc +21 -0
- data/Rakefile +57 -0
- data/VERSION +1 -0
- data/app/controllers/session_controller.rb +10 -0
- data/app/helpers/session_helper.rb +4 -0
- data/app/models/facebook_token.rb +47 -0
- data/app/models/user.rb +70 -0
- data/authpwn_rails.gemspec +99 -0
- data/config/routes.rb +3 -0
- data/lib/authpwn_rails/engine.rb +25 -0
- data/lib/authpwn_rails/facebook_token.rb +44 -0
- data/lib/authpwn_rails/generators/facebook_migration_generator.rb +17 -0
- data/lib/authpwn_rails/generators/templates/001_create_users.rb +17 -0
- data/lib/authpwn_rails/generators/templates/002_create_facebook_tokens.rb +15 -0
- data/lib/authpwn_rails/generators/templates/facebook_token.rb +5 -0
- data/lib/authpwn_rails/generators/templates/facebook_tokens.yml +10 -0
- data/lib/authpwn_rails/generators/templates/user.rb +5 -0
- data/lib/authpwn_rails/generators/templates/users.yml +9 -0
- data/lib/authpwn_rails/generators/user_migration_generator.rb +17 -0
- data/lib/authpwn_rails/session.rb +63 -0
- data/lib/authpwn_rails.rb +15 -0
- data/test/cookie_controller_test.rb +41 -0
- data/test/facebook_controller_test.rb +43 -0
- data/test/facebook_token_test.rb +28 -0
- data/test/helpers/application_controller.rb +3 -0
- data/test/helpers/db_setup.rb +25 -0
- data/test/helpers/fbgraph.rb +6 -0
- data/test/helpers/routes.rb +15 -0
- data/test/session_controller_test.rb +17 -0
- data/test/test_helper.rb +17 -0
- data/test/user_test.rb +88 -0
- metadata +193 -0
data/.document
ADDED
data/.gitignore
ADDED
data/.project
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<projectDescription>
|
3
|
+
<name>pwnauth_rails</name>
|
4
|
+
<comment></comment>
|
5
|
+
<projects>
|
6
|
+
</projects>
|
7
|
+
<buildSpec>
|
8
|
+
<buildCommand>
|
9
|
+
<name>org.rubypeople.rdt.core.rubybuilder</name>
|
10
|
+
<arguments>
|
11
|
+
</arguments>
|
12
|
+
</buildCommand>
|
13
|
+
</buildSpec>
|
14
|
+
<natures>
|
15
|
+
<nature>org.rubypeople.rdt.core.rubynature</nature>
|
16
|
+
</natures>
|
17
|
+
</projectDescription>
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Victor Costan
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
= mini_auth_rails
|
2
|
+
|
3
|
+
User authentication for a Ruby on Rails 3 application. Works with Facebook.
|
4
|
+
|
5
|
+
== Integration
|
6
|
+
|
7
|
+
TBD
|
8
|
+
|
9
|
+
== Note on Patches/Pull Requests
|
10
|
+
|
11
|
+
* Fork the project.
|
12
|
+
* Make your feature addition or bug fix.
|
13
|
+
* Add tests for it. This is important so I don't break it in a
|
14
|
+
future version unintentionally.
|
15
|
+
* Commit, do not mess with rakefile, version, or history.
|
16
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
17
|
+
* Send me a pull request. Bonus points for topic branches.
|
18
|
+
|
19
|
+
== Copyright
|
20
|
+
|
21
|
+
Copyright (c) 2010 Victor Costan, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "authpwn_rails"
|
8
|
+
gem.summary = %Q{User authentication for Rails 3 applications.}
|
9
|
+
gem.description = %Q{Works with Facebook.}
|
10
|
+
gem.email = "victor@costan.us"
|
11
|
+
gem.homepage = "http://github.com/costan/mini_auth_rails"
|
12
|
+
gem.authors = ["Victor Costan"]
|
13
|
+
gem.add_runtime_dependency "fbgraph_rails", ">= 0.1.3"
|
14
|
+
gem.add_development_dependency "activerecord", ">= 3.0.0.rc"
|
15
|
+
gem.add_development_dependency "actionpack", ">= 3.0.0.rc"
|
16
|
+
gem.add_development_dependency "activesupport", ">= 3.0.0.rc"
|
17
|
+
gem.add_development_dependency "sqlite3-ruby", ">= 1.3.0"
|
18
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
19
|
+
end
|
20
|
+
Jeweler::GemcutterTasks.new
|
21
|
+
rescue LoadError
|
22
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'rake/testtask'
|
26
|
+
Rake::TestTask.new(:test) do |test|
|
27
|
+
test.libs << 'lib' << 'test'
|
28
|
+
test.pattern = 'test/**/*_test.rb'
|
29
|
+
test.verbose = true
|
30
|
+
end
|
31
|
+
|
32
|
+
begin
|
33
|
+
require 'rcov/rcovtask'
|
34
|
+
Rcov::RcovTask.new do |test|
|
35
|
+
test.libs << 'test'
|
36
|
+
test.pattern = 'test/**/*_test.rb'
|
37
|
+
test.verbose = true
|
38
|
+
end
|
39
|
+
rescue LoadError
|
40
|
+
task :rcov do
|
41
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
task :test => :check_dependencies
|
46
|
+
|
47
|
+
task :default => :test
|
48
|
+
|
49
|
+
require 'rake/rdoctask'
|
50
|
+
Rake::RDocTask.new do |rdoc|
|
51
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
52
|
+
|
53
|
+
rdoc.rdoc_dir = 'rdoc'
|
54
|
+
rdoc.title = "authpwn_rails #{version}"
|
55
|
+
rdoc.rdoc_files.include('README*')
|
56
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
57
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.0
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
|
4
|
+
# Wraps an OAuth2 access token for Facebook.
|
5
|
+
class FacebookToken < ActiveRecord::Base
|
6
|
+
# The user whose token this is.
|
7
|
+
belongs_to :user
|
8
|
+
validates :user, :presence => true
|
9
|
+
|
10
|
+
# A unique ID on the Facebook site for the user owning this token.
|
11
|
+
validates :external_uid, :length => 1..32, :presence => true
|
12
|
+
|
13
|
+
# The OAuth2 access token.
|
14
|
+
validates :access_token, :length => 1..128, :presence => true
|
15
|
+
|
16
|
+
# FBGraph client loaded with this access token.
|
17
|
+
def facebook_client
|
18
|
+
@client ||= FBGraphRails.fbclient(access_token)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Finds or creates the model containing a token.
|
22
|
+
#
|
23
|
+
# If a model for the same user exists, the model is updated with the given
|
24
|
+
# token. Otherwise, a new model will be created, together with a user.
|
25
|
+
def self.for(access_token)
|
26
|
+
uid = uid_from_token access_token
|
27
|
+
token = self.where(:external_uid => uid).first
|
28
|
+
if token
|
29
|
+
token.access_token = access_token
|
30
|
+
else
|
31
|
+
token = FacebookToken.new :external_uid => uid,
|
32
|
+
:access_token => access_token
|
33
|
+
token.user = User.create_with_facebook_token token
|
34
|
+
end
|
35
|
+
token.save!
|
36
|
+
token
|
37
|
+
end
|
38
|
+
|
39
|
+
# Extracts the Facebook user ID from a OAuth2 token.
|
40
|
+
#
|
41
|
+
# This is a hack. It works based on the current format, but might break at any
|
42
|
+
# time. Hopefully, we'll eventually have an official way of pulling the UID
|
43
|
+
# out of an OAuth2 token.
|
44
|
+
def self.uid_from_token(access_token)
|
45
|
+
access_token.split('|')[1].split('-').last
|
46
|
+
end
|
47
|
+
end
|
data/app/models/user.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
|
4
|
+
# An user account.
|
5
|
+
class User < ActiveRecord::Base
|
6
|
+
# E-mail address identifying the user account.
|
7
|
+
validates :email, :format => /^[A-Za-z0-9.+_]+@[^@]*\.(\w+)$/,
|
8
|
+
:presence => true, :length => 1..64, :uniqueness => true
|
9
|
+
|
10
|
+
# Random string preventing dictionary attacks on the password database.
|
11
|
+
validates :password_salt, :length => 1..16, :allow_nil => true
|
12
|
+
|
13
|
+
# SHA-256 of (salt + password).
|
14
|
+
validates :password_hash, :length => 1..64, :allow_nil => true
|
15
|
+
|
16
|
+
# Virtual attribute: the user's password.
|
17
|
+
attr_reader :password
|
18
|
+
validates :password, :confirmation => true
|
19
|
+
def password=(new_password)
|
20
|
+
@password = new_password
|
21
|
+
self.password_salt = self.class.random_salt
|
22
|
+
self.password_hash = self.class.hash_password new_password, password_salt
|
23
|
+
end
|
24
|
+
|
25
|
+
# Virtual attribute: confirmation for the user's password.
|
26
|
+
attr_accessor :password_confirmation
|
27
|
+
validates_confirmation_of :password
|
28
|
+
|
29
|
+
# The authenticated user or nil.
|
30
|
+
def self.find_by_email_and_password(email, password)
|
31
|
+
@user = User.where(:email => email).first
|
32
|
+
(@user && @user.password_matches?(password)) ? @user : nil
|
33
|
+
end
|
34
|
+
|
35
|
+
# Compares the given password against the user's stored password.
|
36
|
+
#
|
37
|
+
# Returns +true+ for a match, +false+ otherwise.
|
38
|
+
def password_matches?(passwd)
|
39
|
+
password_hash == User.hash_password(passwd, password_salt)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Computes a password hash from a raw password and a salt.
|
43
|
+
def self.hash_password(password, salt)
|
44
|
+
Digest::SHA2.hexdigest(password + salt)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Generates a random salt value.
|
48
|
+
def self.random_salt
|
49
|
+
(0...16).map { |i| 1 + rand(255) }.pack('C*')
|
50
|
+
end
|
51
|
+
|
52
|
+
# Resets the virtual password attributes.
|
53
|
+
def reset_password
|
54
|
+
@password = @password_confirmation = nil
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
# Fills out a new user's information based on a Facebook access token.
|
59
|
+
def self.create_with_facebook_token(token)
|
60
|
+
self.create :email => "#{token.external_uid}@graph.facebook.com"
|
61
|
+
end
|
62
|
+
|
63
|
+
# The user that owns a given Facebook OAuth2 token.
|
64
|
+
#
|
65
|
+
# A new user will be created if the token doesn't belong to any user. This is
|
66
|
+
# the case for a new visitor.
|
67
|
+
def self.for_facebook_token(access_token)
|
68
|
+
FacebookToken.for(access_token).user
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{authpwn_rails}
|
8
|
+
s.version = "0.3.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Victor Costan"]
|
12
|
+
s.date = %q{2010-08-02}
|
13
|
+
s.description = %q{Works with Facebook.}
|
14
|
+
s.email = %q{victor@costan.us}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
".project",
|
23
|
+
"LICENSE",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"app/controllers/session_controller.rb",
|
28
|
+
"app/helpers/session_helper.rb",
|
29
|
+
"app/models/facebook_token.rb",
|
30
|
+
"app/models/user.rb",
|
31
|
+
"authpwn_rails.gemspec",
|
32
|
+
"config/routes.rb",
|
33
|
+
"lib/authpwn_rails.rb",
|
34
|
+
"lib/authpwn_rails/engine.rb",
|
35
|
+
"lib/authpwn_rails/facebook_token.rb",
|
36
|
+
"lib/authpwn_rails/generators/facebook_migration_generator.rb",
|
37
|
+
"lib/authpwn_rails/generators/templates/001_create_users.rb",
|
38
|
+
"lib/authpwn_rails/generators/templates/002_create_facebook_tokens.rb",
|
39
|
+
"lib/authpwn_rails/generators/templates/facebook_token.rb",
|
40
|
+
"lib/authpwn_rails/generators/templates/facebook_tokens.yml",
|
41
|
+
"lib/authpwn_rails/generators/templates/user.rb",
|
42
|
+
"lib/authpwn_rails/generators/templates/users.yml",
|
43
|
+
"lib/authpwn_rails/generators/user_migration_generator.rb",
|
44
|
+
"lib/authpwn_rails/session.rb",
|
45
|
+
"test/cookie_controller_test.rb",
|
46
|
+
"test/facebook_controller_test.rb",
|
47
|
+
"test/facebook_token_test.rb",
|
48
|
+
"test/helpers/application_controller.rb",
|
49
|
+
"test/helpers/db_setup.rb",
|
50
|
+
"test/helpers/fbgraph.rb",
|
51
|
+
"test/helpers/routes.rb",
|
52
|
+
"test/session_controller_test.rb",
|
53
|
+
"test/test_helper.rb",
|
54
|
+
"test/user_test.rb"
|
55
|
+
]
|
56
|
+
s.homepage = %q{http://github.com/costan/mini_auth_rails}
|
57
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
58
|
+
s.require_paths = ["lib"]
|
59
|
+
s.rubygems_version = %q{1.3.7}
|
60
|
+
s.summary = %q{User authentication for Rails 3 applications.}
|
61
|
+
s.test_files = [
|
62
|
+
"test/facebook_token_test.rb",
|
63
|
+
"test/user_test.rb",
|
64
|
+
"test/cookie_controller_test.rb",
|
65
|
+
"test/test_helper.rb",
|
66
|
+
"test/facebook_controller_test.rb",
|
67
|
+
"test/session_controller_test.rb",
|
68
|
+
"test/helpers/application_controller.rb",
|
69
|
+
"test/helpers/routes.rb",
|
70
|
+
"test/helpers/fbgraph.rb",
|
71
|
+
"test/helpers/db_setup.rb"
|
72
|
+
]
|
73
|
+
|
74
|
+
if s.respond_to? :specification_version then
|
75
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
76
|
+
s.specification_version = 3
|
77
|
+
|
78
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
79
|
+
s.add_runtime_dependency(%q<fbgraph_rails>, [">= 0.1.3"])
|
80
|
+
s.add_development_dependency(%q<activerecord>, [">= 3.0.0.rc"])
|
81
|
+
s.add_development_dependency(%q<actionpack>, [">= 3.0.0.rc"])
|
82
|
+
s.add_development_dependency(%q<activesupport>, [">= 3.0.0.rc"])
|
83
|
+
s.add_development_dependency(%q<sqlite3-ruby>, [">= 1.3.0"])
|
84
|
+
else
|
85
|
+
s.add_dependency(%q<fbgraph_rails>, [">= 0.1.3"])
|
86
|
+
s.add_dependency(%q<activerecord>, [">= 3.0.0.rc"])
|
87
|
+
s.add_dependency(%q<actionpack>, [">= 3.0.0.rc"])
|
88
|
+
s.add_dependency(%q<activesupport>, [">= 3.0.0.rc"])
|
89
|
+
s.add_dependency(%q<sqlite3-ruby>, [">= 1.3.0"])
|
90
|
+
end
|
91
|
+
else
|
92
|
+
s.add_dependency(%q<fbgraph_rails>, [">= 0.1.3"])
|
93
|
+
s.add_dependency(%q<activerecord>, [">= 3.0.0.rc"])
|
94
|
+
s.add_dependency(%q<actionpack>, [">= 3.0.0.rc"])
|
95
|
+
s.add_dependency(%q<activesupport>, [">= 3.0.0.rc"])
|
96
|
+
s.add_dependency(%q<sqlite3-ruby>, [">= 1.3.0"])
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
data/config/routes.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'mini_auth_rails'
|
2
|
+
require 'rails'
|
3
|
+
|
4
|
+
# :nodoc: namespace
|
5
|
+
module AuthpwnRails
|
6
|
+
|
7
|
+
class Engine < Rails::Engine
|
8
|
+
paths.app = "app"
|
9
|
+
paths.app.controllers = "app/controllers"
|
10
|
+
paths.app.helpers = "app/helpers"
|
11
|
+
paths.app.models = "app/models"
|
12
|
+
paths.app.views = "app/views"
|
13
|
+
# paths.lib = "lib"
|
14
|
+
# paths.lib.tasks = "lib/tasks"
|
15
|
+
# paths.config = "config"
|
16
|
+
# paths.config.initializers = "config/initializers"
|
17
|
+
# paths.config.locales = "config/locales"
|
18
|
+
paths.config.routes = "config/routes.rb"
|
19
|
+
|
20
|
+
def generators
|
21
|
+
require 'mini_auth_rails/generators/user_model_generator.rb'
|
22
|
+
end
|
23
|
+
end # class AuthpwnRails::Engine
|
24
|
+
|
25
|
+
end # namespace AuthpwnRails
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'action_controller'
|
2
|
+
|
3
|
+
# :nodoc: namespace
|
4
|
+
module AuthpwnRails
|
5
|
+
|
6
|
+
# :nodoc: namespace
|
7
|
+
module FacebookToken
|
8
|
+
|
9
|
+
# Mixed into ActiveController::Base
|
10
|
+
module ControllerMixin
|
11
|
+
def self.included(base)
|
12
|
+
base.send :extend, ControllerClassMethods
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Methods here become ActiveController::Base class methods.
|
17
|
+
module ControllerClassMethods
|
18
|
+
# Authenticates users via Facebook OAuth2, using fbgraph_rails.
|
19
|
+
#
|
20
|
+
# The User model class must implement for_facebook_token. The controller
|
21
|
+
# should obtain the Facebook token, using probes_facebook_access_token or
|
22
|
+
# requires_facebook_access_token.
|
23
|
+
def authenticates_using_facebook(options = {})
|
24
|
+
include ControllerInstanceMethods
|
25
|
+
before_filter :authenticate_using_facebook_access_token, options
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Included in controllers that call authenticates_using_facebook.
|
30
|
+
module ControllerInstanceMethods
|
31
|
+
def authenticate_using_facebook_access_token
|
32
|
+
return true if current_user
|
33
|
+
if access_token = current_facebook_access_token
|
34
|
+
self.current_user = User.for_facebook_token access_token
|
35
|
+
end
|
36
|
+
end
|
37
|
+
private :authenticate_using_facebook_access_token
|
38
|
+
end
|
39
|
+
|
40
|
+
ActionController::Base.send :include, ControllerMixin
|
41
|
+
|
42
|
+
end # namespace AuthpwnRails::FacebookToken
|
43
|
+
|
44
|
+
end # namespace AuthpwnRails
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# :nodoc: namespace
|
2
|
+
module AuthpwnRails
|
3
|
+
|
4
|
+
|
5
|
+
class FacebookMigrationGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path("../templates", __FILE__)
|
7
|
+
|
8
|
+
def create_session_model
|
9
|
+
template 'facebook_token.rb',
|
10
|
+
File.join('app/models', class_path, 'facebook_token.rb')
|
11
|
+
template '002_create_facebook_tokens.rb',
|
12
|
+
File.join('db/migrations', '20100725000002_create_facebook_tokens.rb')
|
13
|
+
template 'facebook_tokens.yml', File.join('test/fixtures', 'facebook_tokens.yml')
|
14
|
+
end
|
15
|
+
end # class AuthpwnRails::UserMigrationGenerator
|
16
|
+
|
17
|
+
end # namespace AuthpwnRails
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateUsers < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :users do |t|
|
4
|
+
t.string :email, :limit => 64, :null => false
|
5
|
+
t.string :password_salt, :limit => 16, :null => true
|
6
|
+
t.string :password_hash, :limit => 64, :null => true
|
7
|
+
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
add_index :users, :email, :unique => true, :null => false
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.down
|
15
|
+
drop_table :users
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateFacebookTokens < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :facebook_tokens do |t|
|
4
|
+
t.integer :user_id, :null => false
|
5
|
+
t.string :external_uid, :limit => 32, :null => false
|
6
|
+
t.string :access_token, :limit => 128, :null => false
|
7
|
+
end
|
8
|
+
|
9
|
+
add_index :facebook_tokens, :external_uid, :unique => true, :null => false
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.down
|
13
|
+
drop_table :facebook_tokens
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Test account vic.tor@costan.us
|
2
|
+
jane:
|
3
|
+
user: jane
|
4
|
+
external_uid: 100001181310542
|
5
|
+
access_token: 125502267478972|d2ecea6d763d2fb17cfa70fa-100001181310542|h849k0nQBq4FkAVEGVgeyoSd_RA.
|
6
|
+
|
7
|
+
john:
|
8
|
+
user: john
|
9
|
+
external_uid: 702659
|
10
|
+
access_token: 702659|ffffffffffffffffffffffff-702659|ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# :nodoc: namespace
|
2
|
+
module AuthpwnRails
|
3
|
+
|
4
|
+
|
5
|
+
class UserMigrationGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path("../templates", __FILE__)
|
7
|
+
|
8
|
+
def create_session_model
|
9
|
+
template 'user_token.rb',
|
10
|
+
File.join('app/models', class_path, 'user.rb')
|
11
|
+
template '001_create_users.rb',
|
12
|
+
File.join('db/migrations', '20100725000001_create_users.rb')
|
13
|
+
template 'users.yml', File.join('test/fixtures', 'users.yml')
|
14
|
+
end
|
15
|
+
end # class AuthpwnRails::UserMigrationGenerator
|
16
|
+
|
17
|
+
end # namespace AuthpwnRails
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'action_controller'
|
2
|
+
|
3
|
+
# :nodoc: namespace
|
4
|
+
module AuthpwnRails
|
5
|
+
|
6
|
+
# :nodoc: namespace
|
7
|
+
module Session
|
8
|
+
|
9
|
+
# Mixed into ActiveController::Base
|
10
|
+
module ControllerMixin
|
11
|
+
def self.included(base)
|
12
|
+
base.send :extend, ControllerClassMethods
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Methods here become ActiveController::Base class methods.
|
17
|
+
module ControllerClassMethods
|
18
|
+
# Keeps track of the currently authenticated user via the session.
|
19
|
+
#
|
20
|
+
# Assumes the existence of a User model. A bare ActiveModel model will do the
|
21
|
+
# trick. Model instances must implement id, and the model class must implement
|
22
|
+
# find_by_id.
|
23
|
+
def authenticates_using_session(options = {})
|
24
|
+
include ControllerInstanceMethods
|
25
|
+
before_filter :authenticate_using_session, options
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Included in controllers that call authenticates_using_session.
|
30
|
+
module ControllerInstanceMethods
|
31
|
+
attr_reader :current_user
|
32
|
+
|
33
|
+
def current_user=(user)
|
34
|
+
@current_user = user
|
35
|
+
if user
|
36
|
+
session[:current_user_id] = user.id
|
37
|
+
else
|
38
|
+
session.delete :current_user_id
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def authenticate_using_session
|
43
|
+
return true if current_user
|
44
|
+
user_id = session[:current_user_id]
|
45
|
+
user = user_id && User.find_by_id(user_id)
|
46
|
+
self.current_user = user if user
|
47
|
+
end
|
48
|
+
private :authenticate_using_session
|
49
|
+
end
|
50
|
+
|
51
|
+
ActionController::Base.send :include, ControllerMixin
|
52
|
+
|
53
|
+
# :nodoc: add session modification
|
54
|
+
class ActionController::TestCase
|
55
|
+
# Sets the authenticated user in the test session.
|
56
|
+
def set_session_current_user(user)
|
57
|
+
request.session[:current_user_id] = user ? user.id : nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end # namespace AuthpwnRails::Session
|
62
|
+
|
63
|
+
end # namespace AuthpwnRails
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# :nodoc: namespace
|
2
|
+
module AuthpwnRails
|
3
|
+
end
|
4
|
+
|
5
|
+
require 'authpwn_rails/facebook_token.rb'
|
6
|
+
require 'authpwn_rails/session.rb'
|
7
|
+
|
8
|
+
if defined?(Rails)
|
9
|
+
require 'authpwn_rails/engine.rb'
|
10
|
+
|
11
|
+
# HACK(costan): this works around a known Rails bug
|
12
|
+
# https://rails.lighthouseapp.com/projects/8994/tickets/1905-apphelpers-within-plugin-not-being-mixed-in
|
13
|
+
require File.expand_path('../../app/helpers/session_helper.rb', __FILE__)
|
14
|
+
ActionController::Base.helper SessionHelper
|
15
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
# Mock controller used for testing session handling.
|
4
|
+
class CookieController < ApplicationController
|
5
|
+
authenticates_using_session
|
6
|
+
|
7
|
+
def show
|
8
|
+
if current_user
|
9
|
+
render :text => "User: #{current_user.id}"
|
10
|
+
else
|
11
|
+
render :text => "No user"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class CookieControllerTest < ActionController::TestCase
|
17
|
+
setup do
|
18
|
+
@user = users(:john)
|
19
|
+
end
|
20
|
+
|
21
|
+
test "no user_id in session" do
|
22
|
+
get :show
|
23
|
+
assert_response :success
|
24
|
+
assert_nil assigns(:current_user)
|
25
|
+
assert_equal 'No user', response.body
|
26
|
+
end
|
27
|
+
|
28
|
+
test "valid user_id in session" do
|
29
|
+
set_session_current_user @user
|
30
|
+
get :show
|
31
|
+
assert_response :success
|
32
|
+
assert_equal @user, assigns(:current_user)
|
33
|
+
assert_equal "User: #{Fixtures.identify(:john)}", response.body
|
34
|
+
end
|
35
|
+
|
36
|
+
test "invalid user_id in session" do
|
37
|
+
get :show, {}, :current_user_id => 999
|
38
|
+
assert_response :success
|
39
|
+
assert_nil assigns(:current_user)
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
# Mock controller used for testing session handling.
|
4
|
+
class FacebookController < ApplicationController
|
5
|
+
authenticates_using_session
|
6
|
+
probes_facebook_access_token
|
7
|
+
authenticates_using_facebook
|
8
|
+
|
9
|
+
def show
|
10
|
+
if current_user
|
11
|
+
render :text => "User: #{current_user.id}"
|
12
|
+
else
|
13
|
+
render :text => "No user"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class FacebookControllerTest < ActionController::TestCase
|
19
|
+
setup do
|
20
|
+
@user = users(:john)
|
21
|
+
@new_token = 'facebook:new_token|boom'
|
22
|
+
end
|
23
|
+
|
24
|
+
test "no facebook token" do
|
25
|
+
get :show
|
26
|
+
assert_response :success
|
27
|
+
assert_nil assigns(:current_user)
|
28
|
+
end
|
29
|
+
|
30
|
+
test "facebook token for existing user" do
|
31
|
+
set_session_current_facebook_token facebook_tokens(:john).access_token
|
32
|
+
get :show, {}
|
33
|
+
assert_response :success
|
34
|
+
assert_equal @user, assigns(:current_user)
|
35
|
+
end
|
36
|
+
|
37
|
+
test "new facebook token" do
|
38
|
+
set_session_current_facebook_token @new_token
|
39
|
+
get :show, {}
|
40
|
+
assert_response :success
|
41
|
+
assert !(@user == assigns(:current_user))
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
class FacebookTokenTest < ActiveSupport::TestCase
|
4
|
+
setup do
|
5
|
+
@code = '125502267478972|057806abb79e632e0f7dde62-100001181310542|y5SoPVcXoEl214vfs--F3y-Z0Xk.'
|
6
|
+
end
|
7
|
+
|
8
|
+
test "uid_from_token" do
|
9
|
+
assert_equal '100001181310542', FacebookToken.uid_from_token(@code)
|
10
|
+
end
|
11
|
+
|
12
|
+
test "for with existing access token" do
|
13
|
+
assert_equal facebook_tokens(:jane), FacebookToken.for(@code),
|
14
|
+
'Wrong token'
|
15
|
+
assert_equal @code, facebook_tokens(:jane).reload.access_token,
|
16
|
+
'Token not refreshed'
|
17
|
+
end
|
18
|
+
|
19
|
+
test "for with new access token" do
|
20
|
+
token = nil
|
21
|
+
assert_difference 'FacebookToken.count', 1 do
|
22
|
+
token = FacebookToken.for @code.gsub('100001181310542', '3141592')
|
23
|
+
end
|
24
|
+
assert_equal '3141592@graph.facebook.com', token.user.email
|
25
|
+
assert !token.new_record?, 'New token not saved'
|
26
|
+
assert !token.user.new_record?, "New token's user not saved"
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
ActiveRecord::Base.establish_connection :adapter => 'sqlite3',
|
2
|
+
:database => ':memory:'
|
3
|
+
ActiveRecord::Base.configurations = true
|
4
|
+
|
5
|
+
ActiveRecord::Migration.verbose = false
|
6
|
+
require 'authpwn_rails/generators/templates/001_create_users.rb'
|
7
|
+
CreateUsers.up
|
8
|
+
require 'authpwn_rails/generators/templates/002_create_facebook_tokens.rb'
|
9
|
+
CreateFacebookTokens.up
|
10
|
+
|
11
|
+
require File.expand_path('../../../app/models/facebook_token.rb', __FILE__)
|
12
|
+
require File.expand_path('../../../app/models/user.rb', __FILE__)
|
13
|
+
|
14
|
+
# :nodoc: open TestCase to setup fixtures
|
15
|
+
class ActiveSupport::TestCase
|
16
|
+
include ActiveRecord::TestFixtures
|
17
|
+
|
18
|
+
self.fixture_path =
|
19
|
+
File.expand_path '../../../lib/authpwn_rails/generators/templates',
|
20
|
+
__FILE__
|
21
|
+
self.use_transactional_fixtures = false
|
22
|
+
self.use_instantiated_fixtures = false
|
23
|
+
self.pre_loaded_fixtures = false
|
24
|
+
fixtures :all
|
25
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# :nodoc: the routes used in all tests
|
2
|
+
class ActionController::TestCase
|
3
|
+
def setup_routes
|
4
|
+
@routes = ActionController::Routing::RouteSet.new
|
5
|
+
@routes.draw do
|
6
|
+
resource :cookie, :controller => 'cookie'
|
7
|
+
resource :facebook, :controller => 'facebook'
|
8
|
+
resource :session, :controller => 'session'
|
9
|
+
root :to => 'session#index'
|
10
|
+
end
|
11
|
+
ApplicationController.send :include, @routes.url_helpers
|
12
|
+
end
|
13
|
+
|
14
|
+
setup :setup_routes
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
require File.expand_path('../../app/controllers/session_controller', __FILE__)
|
4
|
+
|
5
|
+
class SessionControllerTest < ActionController::TestCase
|
6
|
+
setup do
|
7
|
+
@user = users(:john)
|
8
|
+
end
|
9
|
+
|
10
|
+
test "logout" do
|
11
|
+
set_session_current_user @user
|
12
|
+
delete :destroy
|
13
|
+
|
14
|
+
assert_redirected_to root_url
|
15
|
+
assert_nil assigns(:current_user)
|
16
|
+
end
|
17
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
require 'action_pack'
|
5
|
+
require 'active_record'
|
6
|
+
require 'active_support'
|
7
|
+
|
8
|
+
require 'fbgraph_rails'
|
9
|
+
require 'fbgraph_rails/controller'
|
10
|
+
require 'sqlite3'
|
11
|
+
|
12
|
+
require 'authpwn_rails'
|
13
|
+
|
14
|
+
require 'helpers/application_controller.rb'
|
15
|
+
require 'helpers/db_setup.rb'
|
16
|
+
require 'helpers/fbgraph.rb'
|
17
|
+
require 'helpers/routes.rb'
|
data/test/user_test.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
class UserTest < ActiveSupport::TestCase
|
4
|
+
def setup
|
5
|
+
@user = User.new :password => 'awesome',
|
6
|
+
:password_confirmation => 'awesome',
|
7
|
+
:email => 'dvdjohn@mit.edu'
|
8
|
+
end
|
9
|
+
|
10
|
+
test 'password_salt not required' do
|
11
|
+
@user.password_salt = nil
|
12
|
+
assert @user.valid?
|
13
|
+
end
|
14
|
+
|
15
|
+
test 'password_salt length' do
|
16
|
+
@user.password_salt = '12345' * 4
|
17
|
+
assert !@user.valid?, 'Long salt'
|
18
|
+
@user.password_salt = ''
|
19
|
+
assert !@user.valid?, 'Empty salt'
|
20
|
+
end
|
21
|
+
|
22
|
+
test 'password_hash not required' do
|
23
|
+
@user.password_hash = nil
|
24
|
+
assert @user.valid?
|
25
|
+
end
|
26
|
+
|
27
|
+
test 'password_hash length' do
|
28
|
+
@user.password_hash = '12345' * 13
|
29
|
+
assert !@user.valid?, 'Long hash'
|
30
|
+
@user.password_hash = ''
|
31
|
+
assert !@user.valid?, 'Empty hash'
|
32
|
+
end
|
33
|
+
|
34
|
+
test 'email presence' do
|
35
|
+
@user.email = nil
|
36
|
+
assert !@user.valid?
|
37
|
+
end
|
38
|
+
|
39
|
+
test 'email length' do
|
40
|
+
@user.email = 'abcde' * 12 + '@mit.edu'
|
41
|
+
assert !@user.valid?, 'Overly long user name'
|
42
|
+
end
|
43
|
+
|
44
|
+
test 'email format' do
|
45
|
+
['cos tan@gmail.com', 'costan@x@mit.edu'].each do |email|
|
46
|
+
@user.email = email
|
47
|
+
assert !@user.valid?, "Bad email format - #{name}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
test 'email uniqueness' do
|
52
|
+
@user.email = users(:john).email
|
53
|
+
assert !@user.valid?
|
54
|
+
end
|
55
|
+
|
56
|
+
test 'password not required' do
|
57
|
+
@user.reset_password
|
58
|
+
assert @user.valid?
|
59
|
+
end
|
60
|
+
|
61
|
+
test 'password confirmation' do
|
62
|
+
@user.password_confirmation = 'not awesome'
|
63
|
+
assert !@user.valid?
|
64
|
+
end
|
65
|
+
|
66
|
+
test 'password_matches?' do
|
67
|
+
assert_equal true, @user.password_matches?('awesome')
|
68
|
+
assert_equal false, @user.password_matches?('not awesome'), 'Bogus password'
|
69
|
+
assert_equal false, @user.password_matches?('password'),
|
70
|
+
"Another user's password"
|
71
|
+
end
|
72
|
+
|
73
|
+
test 'find_by_email_and_password' do
|
74
|
+
assert_equal users(:john),
|
75
|
+
User.find_by_email_and_password('john@gmail.com', 'password')
|
76
|
+
assert_equal nil,
|
77
|
+
User.find_by_email_and_password('john@gmail.com', 'pa55w0rd'),
|
78
|
+
"Jane's password on John's account"
|
79
|
+
assert_equal users(:jane),
|
80
|
+
User.find_by_email_and_password('jane@gmail.com', 'pa55w0rd')
|
81
|
+
assert_equal nil,
|
82
|
+
User.find_by_email_and_password('jane@gmail.com', 'password'),
|
83
|
+
"John's password on Jane's account"
|
84
|
+
assert_equal nil,
|
85
|
+
User.find_by_email_and_password('john@gmail.com', 'awesome'),
|
86
|
+
'Bogus password'
|
87
|
+
end
|
88
|
+
end
|
metadata
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: authpwn_rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Victor Costan
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-08-02 00:00:00 -04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: fbgraph_rails
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 29
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 1
|
33
|
+
- 3
|
34
|
+
version: 0.1.3
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: activerecord
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 7712042
|
46
|
+
segments:
|
47
|
+
- 3
|
48
|
+
- 0
|
49
|
+
- 0
|
50
|
+
- rc
|
51
|
+
version: 3.0.0.rc
|
52
|
+
type: :development
|
53
|
+
version_requirements: *id002
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: actionpack
|
56
|
+
prerelease: false
|
57
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
hash: 7712042
|
63
|
+
segments:
|
64
|
+
- 3
|
65
|
+
- 0
|
66
|
+
- 0
|
67
|
+
- rc
|
68
|
+
version: 3.0.0.rc
|
69
|
+
type: :development
|
70
|
+
version_requirements: *id003
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: activesupport
|
73
|
+
prerelease: false
|
74
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
hash: 7712042
|
80
|
+
segments:
|
81
|
+
- 3
|
82
|
+
- 0
|
83
|
+
- 0
|
84
|
+
- rc
|
85
|
+
version: 3.0.0.rc
|
86
|
+
type: :development
|
87
|
+
version_requirements: *id004
|
88
|
+
- !ruby/object:Gem::Dependency
|
89
|
+
name: sqlite3-ruby
|
90
|
+
prerelease: false
|
91
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
hash: 27
|
97
|
+
segments:
|
98
|
+
- 1
|
99
|
+
- 3
|
100
|
+
- 0
|
101
|
+
version: 1.3.0
|
102
|
+
type: :development
|
103
|
+
version_requirements: *id005
|
104
|
+
description: Works with Facebook.
|
105
|
+
email: victor@costan.us
|
106
|
+
executables: []
|
107
|
+
|
108
|
+
extensions: []
|
109
|
+
|
110
|
+
extra_rdoc_files:
|
111
|
+
- LICENSE
|
112
|
+
- README.rdoc
|
113
|
+
files:
|
114
|
+
- .document
|
115
|
+
- .gitignore
|
116
|
+
- .project
|
117
|
+
- LICENSE
|
118
|
+
- README.rdoc
|
119
|
+
- Rakefile
|
120
|
+
- VERSION
|
121
|
+
- app/controllers/session_controller.rb
|
122
|
+
- app/helpers/session_helper.rb
|
123
|
+
- app/models/facebook_token.rb
|
124
|
+
- app/models/user.rb
|
125
|
+
- authpwn_rails.gemspec
|
126
|
+
- config/routes.rb
|
127
|
+
- lib/authpwn_rails.rb
|
128
|
+
- lib/authpwn_rails/engine.rb
|
129
|
+
- lib/authpwn_rails/facebook_token.rb
|
130
|
+
- lib/authpwn_rails/generators/facebook_migration_generator.rb
|
131
|
+
- lib/authpwn_rails/generators/templates/001_create_users.rb
|
132
|
+
- lib/authpwn_rails/generators/templates/002_create_facebook_tokens.rb
|
133
|
+
- lib/authpwn_rails/generators/templates/facebook_token.rb
|
134
|
+
- lib/authpwn_rails/generators/templates/facebook_tokens.yml
|
135
|
+
- lib/authpwn_rails/generators/templates/user.rb
|
136
|
+
- lib/authpwn_rails/generators/templates/users.yml
|
137
|
+
- lib/authpwn_rails/generators/user_migration_generator.rb
|
138
|
+
- lib/authpwn_rails/session.rb
|
139
|
+
- test/cookie_controller_test.rb
|
140
|
+
- test/facebook_controller_test.rb
|
141
|
+
- test/facebook_token_test.rb
|
142
|
+
- test/helpers/application_controller.rb
|
143
|
+
- test/helpers/db_setup.rb
|
144
|
+
- test/helpers/fbgraph.rb
|
145
|
+
- test/helpers/routes.rb
|
146
|
+
- test/session_controller_test.rb
|
147
|
+
- test/test_helper.rb
|
148
|
+
- test/user_test.rb
|
149
|
+
has_rdoc: true
|
150
|
+
homepage: http://github.com/costan/mini_auth_rails
|
151
|
+
licenses: []
|
152
|
+
|
153
|
+
post_install_message:
|
154
|
+
rdoc_options:
|
155
|
+
- --charset=UTF-8
|
156
|
+
require_paths:
|
157
|
+
- lib
|
158
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
159
|
+
none: false
|
160
|
+
requirements:
|
161
|
+
- - ">="
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
hash: 3
|
164
|
+
segments:
|
165
|
+
- 0
|
166
|
+
version: "0"
|
167
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
168
|
+
none: false
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
hash: 3
|
173
|
+
segments:
|
174
|
+
- 0
|
175
|
+
version: "0"
|
176
|
+
requirements: []
|
177
|
+
|
178
|
+
rubyforge_project:
|
179
|
+
rubygems_version: 1.3.7
|
180
|
+
signing_key:
|
181
|
+
specification_version: 3
|
182
|
+
summary: User authentication for Rails 3 applications.
|
183
|
+
test_files:
|
184
|
+
- test/facebook_token_test.rb
|
185
|
+
- test/user_test.rb
|
186
|
+
- test/cookie_controller_test.rb
|
187
|
+
- test/test_helper.rb
|
188
|
+
- test/facebook_controller_test.rb
|
189
|
+
- test/session_controller_test.rb
|
190
|
+
- test/helpers/application_controller.rb
|
191
|
+
- test/helpers/routes.rb
|
192
|
+
- test/helpers/fbgraph.rb
|
193
|
+
- test/helpers/db_setup.rb
|