sinatra-authentication 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest +2 -0
- data/Rakefile +10 -1
- data/lib/models/abstract_user.rb +7 -2
- data/lib/models/mm_adapter.rb +53 -0
- data/lib/models/mongomapper_user.rb +41 -0
- data/lib/models/rufus_tokyo_user.rb +2 -2
- data/lib/sinatra-authentication.rb +19 -25
- data/lib/views/edit.haml +1 -1
- data/lib/views/login.haml +12 -7
- data/lib/views/signup.haml +14 -10
- data/sinatra-authentication.gemspec +11 -2
- data/test/lib/mm_app.rb +24 -0
- data/test/mongomapper_test.rb +39 -0
- metadata +10 -4
data/Manifest
CHANGED
data/Rakefile
CHANGED
@@ -6,7 +6,7 @@ begin
|
|
6
6
|
|
7
7
|
Jeweler::Tasks.new do |gemspec|
|
8
8
|
gemspec.name = 'sinatra-authentication'
|
9
|
-
gemspec.version = '0.
|
9
|
+
gemspec.version = '0.2.0'
|
10
10
|
gemspec.description = "Simple authentication plugin for sinatra."
|
11
11
|
gemspec.summary = "Simple authentication plugin for sinatra."
|
12
12
|
gemspec.homepage = "http://github.com/maxjustus/sinatra-authentication"
|
@@ -25,3 +25,12 @@ rescue LoadError
|
|
25
25
|
end
|
26
26
|
|
27
27
|
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
|
28
|
+
|
29
|
+
require 'rake/testtask'
|
30
|
+
|
31
|
+
Rake::TestTask.new do |t|
|
32
|
+
t.libs << "test"
|
33
|
+
t.test_files = FileList['test/mongomapper_test.rb']
|
34
|
+
t.verbose = true
|
35
|
+
end
|
36
|
+
|
data/lib/models/abstract_user.rb
CHANGED
@@ -4,9 +4,12 @@ if Object.const_defined?("DataMapper")
|
|
4
4
|
require 'dm-validations'
|
5
5
|
require Pathname(__FILE__).dirname.expand_path + "datamapper_user.rb"
|
6
6
|
require Pathname(__FILE__).dirname.expand_path + "dm_adapter.rb"
|
7
|
-
elsif Object.const_defined?("Rufus")
|
7
|
+
elsif Object.const_defined?("Rufus")
|
8
8
|
require Pathname(__FILE__).dirname.expand_path + "rufus_tokyo_user.rb"
|
9
9
|
require Pathname(__FILE__).dirname.expand_path + "tc_adapter.rb"
|
10
|
+
elsif Object.const_defined?("MongoMapper")
|
11
|
+
require Pathname(__FILE__).dirname.expand_path + "mongomapper_user.rb"
|
12
|
+
require Pathname(__FILE__).dirname.expand_path + "mm_adapter.rb"
|
10
13
|
end
|
11
14
|
|
12
15
|
class User
|
@@ -14,8 +17,10 @@ class User
|
|
14
17
|
include DmAdapter
|
15
18
|
elsif Object.const_defined?("Rufus")
|
16
19
|
include TcAdapter
|
20
|
+
elsif Object.const_defined?("MongoMapper")
|
21
|
+
include MmAdapter
|
17
22
|
else
|
18
|
-
throw "you need to require either 'dm-core' or 'rufus-tokyo' for sinatra-authentication to work"
|
23
|
+
throw "you need to require either 'dm-core', 'mongo_mapper', or 'rufus-tokyo' for sinatra-authentication to work"
|
19
24
|
end
|
20
25
|
|
21
26
|
def initialize(interfacing_class_instance)
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module MmAdapter
|
2
|
+
def self.included(base)
|
3
|
+
base.extend ClassMethods
|
4
|
+
base.class_eval { include MmAdapter::InstanceMethods }
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def all
|
9
|
+
result = MmUser.all
|
10
|
+
result.collect {|instance| self.new instance}
|
11
|
+
end
|
12
|
+
|
13
|
+
def get(hash)
|
14
|
+
if user = MmUser.first(hash)
|
15
|
+
self.new user
|
16
|
+
else
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def set(attributes)
|
22
|
+
puts attributes.inspect
|
23
|
+
user = MmUser.new attributes
|
24
|
+
puts user.inspect
|
25
|
+
puts user.to_json
|
26
|
+
user.save
|
27
|
+
user
|
28
|
+
end
|
29
|
+
|
30
|
+
def set!(attributes)
|
31
|
+
user = MmUser.new attributes
|
32
|
+
user.save!
|
33
|
+
user
|
34
|
+
end
|
35
|
+
|
36
|
+
def delete(pk)
|
37
|
+
user = User.first(:id => pk)
|
38
|
+
user.destroy
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
module InstanceMethods
|
43
|
+
def update(attributes)
|
44
|
+
@instance.update_attributes attributes
|
45
|
+
@instance.save
|
46
|
+
end
|
47
|
+
|
48
|
+
def method_missing(meth, *args, &block)
|
49
|
+
#cool I just found out * on an array turns the array into a list of args for a function
|
50
|
+
@instance.send(meth, *args, &block)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class MmUser
|
2
|
+
include MongoMapper::Document
|
3
|
+
|
4
|
+
key :email, String, :length => (5..40), :unique => true
|
5
|
+
key :hashed_password, String
|
6
|
+
key :salt, String
|
7
|
+
key :created_at, DateTime
|
8
|
+
key :permission_level, Integer, :default => 1
|
9
|
+
if Sinatra.const_defined?('FacebookObject')
|
10
|
+
key :fb_uid, String
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_accessor :password, :password_confirmation
|
14
|
+
#protected equievelant? :protected => true doesn't exist in dm 0.10.0
|
15
|
+
#protected :id, :salt
|
16
|
+
#doesn't behave correctly, I'm not even sure why I did this.
|
17
|
+
|
18
|
+
#validates_presence_of :password_confirmation, :unless => Proc.new { |t| t.hashed_password }
|
19
|
+
#validates_presence_of :password, :unless => Proc.new { |t| t.hashed_password }
|
20
|
+
#validates_is_confirmed :password
|
21
|
+
|
22
|
+
def password=(pass)
|
23
|
+
@password = pass
|
24
|
+
self.salt = User.random_string(10) if !self.salt
|
25
|
+
self.hashed_password = User.encrypt(@password, self.salt)
|
26
|
+
end
|
27
|
+
|
28
|
+
def admin?
|
29
|
+
self.permission_level == -1 || self.id == 1
|
30
|
+
end
|
31
|
+
|
32
|
+
def site_admin?
|
33
|
+
self.id == 1
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
def method_missing(m, *args)
|
39
|
+
return false
|
40
|
+
end
|
41
|
+
end
|
@@ -36,9 +36,9 @@ class TcUser
|
|
36
36
|
def self.query(&block)
|
37
37
|
connection = TcUserTable.new
|
38
38
|
result_set = connection.query(&block)
|
39
|
-
|
39
|
+
result_set.collect! { |result_hash| TcUser.new(result_hash) }
|
40
40
|
connection.close
|
41
|
-
|
41
|
+
result_set
|
42
42
|
end
|
43
43
|
|
44
44
|
def self.get(key)
|
@@ -2,10 +2,6 @@ require 'sinatra/base'
|
|
2
2
|
require 'pathname'
|
3
3
|
require Pathname(__FILE__).dirname.expand_path + "models/abstract_user"
|
4
4
|
|
5
|
-
module SinatraAuthentication
|
6
|
-
VERSION = "0.0.3"
|
7
|
-
end
|
8
|
-
|
9
5
|
module Sinatra
|
10
6
|
module LilAuthentication
|
11
7
|
def self.registered(app)
|
@@ -17,12 +13,10 @@ module Sinatra
|
|
17
13
|
#loading the view from this path into a string and rendering it
|
18
14
|
set :lil_authentication_view_path, Pathname(__FILE__).dirname.expand_path + "views/"
|
19
15
|
|
20
|
-
#TODO write captain sinatra developer man and inform him that the documentation
|
21
|
-
#concerning the writing of extensions is somewhat outdaded/incorrect.
|
22
|
-
#you do not need to to do self.get/self.post when writing an extension
|
23
|
-
#In fact, it doesn't work. You have to use the plain old sinatra DSL
|
24
|
-
|
25
16
|
get '/users' do
|
17
|
+
login_required
|
18
|
+
redirect "/" unless current_user.admin?
|
19
|
+
|
26
20
|
@users = User.all
|
27
21
|
if @users != []
|
28
22
|
haml get_view_as_string("index.haml"), :layout => use_layout?
|
@@ -52,18 +46,18 @@ module Sinatra
|
|
52
46
|
end
|
53
47
|
|
54
48
|
post '/login' do
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
else
|
62
|
-
redirect '/'
|
63
|
-
end
|
49
|
+
if user = User.authenticate(params[:email], params[:password])
|
50
|
+
session[:user] = user.id
|
51
|
+
if session[:return_to]
|
52
|
+
redirect_url = session[:return_to]
|
53
|
+
session[:return_to] = false
|
54
|
+
redirect redirect_url
|
64
55
|
else
|
65
|
-
redirect '/
|
56
|
+
redirect '/'
|
66
57
|
end
|
58
|
+
else
|
59
|
+
redirect '/login'
|
60
|
+
end
|
67
61
|
end
|
68
62
|
|
69
63
|
get '/logout' do
|
@@ -212,19 +206,19 @@ module Sinatra
|
|
212
206
|
logout_parameters = html_attributes
|
213
207
|
# a tad janky?
|
214
208
|
logout_parameters.delete(:rel)
|
215
|
-
result += "<a href='/users/#{current_user.id}/edit' class='#{css_classes} sinatra-authentication-edit' #{parameters}>
|
209
|
+
result += "<a href='/users/#{current_user.id}/edit' class='#{css_classes} sinatra-authentication-edit' #{parameters}>Edit account</a> "
|
216
210
|
if Sinatra.const_defined?('FacebookObject')
|
217
211
|
if fb[:user]
|
218
|
-
result += "<a href='javascript:FB.Connect.logoutAndRedirect(\"/logout\");' class='#{css_classes} sinatra-authentication-logout' #{logout_parameters}>
|
212
|
+
result += "<a href='javascript:FB.Connect.logoutAndRedirect(\"/logout\");' class='#{css_classes} sinatra-authentication-logout' #{logout_parameters}>Logout</a>"
|
219
213
|
else
|
220
|
-
result += "<a href='/logout' class='#{css_classes} sinatra-authentication-logout' #{logout_parameters}>
|
214
|
+
result += "<a href='/logout' class='#{css_classes} sinatra-authentication-logout' #{logout_parameters}>Logout</a>"
|
221
215
|
end
|
222
216
|
else
|
223
|
-
result += "<a href='/logout' class='#{css_classes} sinatra-authentication-logout' #{logout_parameters}>
|
217
|
+
result += "<a href='/logout' class='#{css_classes} sinatra-authentication-logout' #{logout_parameters}>Logout</a>"
|
224
218
|
end
|
225
219
|
else
|
226
|
-
result += "<a href='/signup' class='#{css_classes} sinatra-authentication-signup' #{parameters}>
|
227
|
-
result += "<a href='/login' class='#{css_classes} sinatra-authentication-login' #{parameters}>
|
220
|
+
result += "<a href='/signup' class='#{css_classes} sinatra-authentication-signup' #{parameters}>Signup</a> "
|
221
|
+
result += "<a href='/login' class='#{css_classes} sinatra-authentication-login' #{parameters}>Login</a>"
|
228
222
|
end
|
229
223
|
|
230
224
|
result += "</div>"
|
data/lib/views/edit.haml
CHANGED
data/lib/views/login.haml
CHANGED
@@ -1,13 +1,18 @@
|
|
1
1
|
#sinatra_authentication
|
2
2
|
%h1 Login
|
3
3
|
%form{:action => "/login", :method => "post"}
|
4
|
-
%
|
5
|
-
|
4
|
+
%p
|
5
|
+
%label{:for => "user_email'"} Email
|
6
|
+
%br
|
7
|
+
%input{:id => "user_email", :name => "email", :size => 30, :type => "text"}
|
8
|
+
%p
|
9
|
+
%label{:for => "user_password"} Password
|
10
|
+
%br
|
11
|
+
%input{:id => "user_password", :name => "password", :size => 30, :type => "password"}
|
12
|
+
%p
|
13
|
+
%input{:value => "login", :type => "submit"}
|
14
|
+
%a{:href => "/signup"}
|
15
|
+
Signup
|
6
16
|
%br
|
7
|
-
%input{:id => "user_password", :name => "password", :size => 30, :type => "password"}
|
8
|
-
password
|
9
|
-
%br
|
10
|
-
%input{:value => "login", :type => "submit"}
|
11
17
|
- if Sinatra.const_defined?('FacebookObject')
|
12
|
-
|
|
13
18
|
= render_facebook_connect_link
|
data/lib/views/signup.haml
CHANGED
@@ -1,13 +1,17 @@
|
|
1
1
|
#sinatra_authentication
|
2
2
|
%h1 Signup
|
3
3
|
%form{:action => "/signup", :method => "post"}
|
4
|
-
%
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
%
|
13
|
-
|
4
|
+
%p
|
5
|
+
%label{:for => "user_email"} Email
|
6
|
+
%br
|
7
|
+
%input{ :id => "user_email", :name => "user[email]", :size => 30, :type => "text" }
|
8
|
+
%p
|
9
|
+
%label{:for => "user_password"} Password
|
10
|
+
%br
|
11
|
+
%input{ :id => "user_password", :name => "user[password]", :size => 30, :type => "password" }
|
12
|
+
%p
|
13
|
+
%label{:for => "user_password_confirmation"} Confirm Password
|
14
|
+
%br
|
15
|
+
%input{ :id => "user_password_confirmation", :name => "user[password_confirmation]", :size => 30, :type => "password" }
|
16
|
+
%p
|
17
|
+
%input{ :value => "Create account", :type => "submit" }
|
@@ -5,13 +5,16 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{sinatra-authentication}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Max Justus Spransy"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2010-01-13}
|
13
13
|
s.description = %q{Simple authentication plugin for sinatra.}
|
14
14
|
s.email = %q{maxjustus@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"TODO"
|
17
|
+
]
|
15
18
|
s.files = [
|
16
19
|
".gitignore",
|
17
20
|
"History.txt",
|
@@ -21,6 +24,8 @@ Gem::Specification.new do |s|
|
|
21
24
|
"lib/models/abstract_user.rb",
|
22
25
|
"lib/models/datamapper_user.rb",
|
23
26
|
"lib/models/dm_adapter.rb",
|
27
|
+
"lib/models/mm_adapter.rb",
|
28
|
+
"lib/models/mongomapper_user.rb",
|
24
29
|
"lib/models/rufus_tokyo_user.rb",
|
25
30
|
"lib/models/tc_adapter.rb",
|
26
31
|
"lib/sinatra-authentication.rb",
|
@@ -35,8 +40,10 @@ Gem::Specification.new do |s|
|
|
35
40
|
"test/lib/dm_app.rb",
|
36
41
|
"test/lib/dm_sinbook.rb",
|
37
42
|
"test/lib/helper.rb",
|
43
|
+
"test/lib/mm_app.rb",
|
38
44
|
"test/lib/tc_app.rb",
|
39
45
|
"test/lib/tc_sinbook.rb",
|
46
|
+
"test/mongomapper_test.rb",
|
40
47
|
"test/route_tests.rb",
|
41
48
|
"test/rufus_tokyo_test.rb"
|
42
49
|
]
|
@@ -48,10 +55,12 @@ Gem::Specification.new do |s|
|
|
48
55
|
s.test_files = [
|
49
56
|
"test/lib/dm_sinbook.rb",
|
50
57
|
"test/lib/tc_app.rb",
|
58
|
+
"test/lib/mm_app.rb",
|
51
59
|
"test/lib/tc_sinbook.rb",
|
52
60
|
"test/lib/helper.rb",
|
53
61
|
"test/lib/dm_app.rb",
|
54
62
|
"test/datamapper_test.rb",
|
63
|
+
"test/mongomapper_test.rb",
|
55
64
|
"test/rufus_tokyo_test.rb",
|
56
65
|
"test/route_tests.rb"
|
57
66
|
]
|
data/test/lib/mm_app.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'sinatra/base'
|
3
|
+
require 'haml'
|
4
|
+
require 'mongo_mapper'
|
5
|
+
require File.join(File.dirname(__FILE__), '../../lib/sinatra-authentication')
|
6
|
+
|
7
|
+
logger = Logger.new($stdout)
|
8
|
+
MongoMapper.connection = Mongo::Connection.new('db.mongohq.com', 27017, :logger => logger)
|
9
|
+
MongoMapper.database = "fdbk"
|
10
|
+
MongoMapper.database.authenticate(ENV['mongohq_user'], ENV['mongohq_pass'])
|
11
|
+
|
12
|
+
class TestApp < Sinatra::Base
|
13
|
+
use Rack::Session::Cookie, :secret => "heyhihello"
|
14
|
+
|
15
|
+
register Sinatra::LilAuthentication
|
16
|
+
|
17
|
+
set :environment, 'development'
|
18
|
+
set :public, 'public'
|
19
|
+
set :views, 'views'
|
20
|
+
|
21
|
+
get '/' do
|
22
|
+
haml "= render_login_logout", :layout => :layout
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'lib/mm_app'
|
2
|
+
require 'lib/helper'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rack/test'
|
5
|
+
|
6
|
+
Test::Unit::TestCase.send :include, Rack::Test::Methods
|
7
|
+
|
8
|
+
class SinatraAuthMongoMapperTest < Test::Unit::TestCase
|
9
|
+
include Rack::Test::Methods
|
10
|
+
|
11
|
+
def app
|
12
|
+
TestApp
|
13
|
+
end
|
14
|
+
|
15
|
+
def setup
|
16
|
+
post '/signup', TestHelper.gen_user
|
17
|
+
follow_redirect!
|
18
|
+
get '/logout'
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_should_login
|
22
|
+
post '/login', {'email' => TestHelper.gen_user['user[email]'], 'password' => TestHelper.gen_user['user[password]']}
|
23
|
+
follow_redirect!
|
24
|
+
|
25
|
+
assert_equal 'http://example.org/', last_request.url
|
26
|
+
#assert cookie_jar['user']
|
27
|
+
assert last_request.env['rack.session'][:user]
|
28
|
+
assert last_response.ok?
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_should_logout
|
32
|
+
post '/login', {'email' => TestHelper.gen_user['user[email]'], 'password' => TestHelper.gen_user['user[password]']}
|
33
|
+
get '/logout'
|
34
|
+
follow_redirect!
|
35
|
+
|
36
|
+
assert !last_request.env['rack.session'][:user]
|
37
|
+
assert_equal 'http://example.org/', last_request.url
|
38
|
+
end
|
39
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sinatra-authentication
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Max Justus Spransy
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-01-13 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -78,8 +78,8 @@ executables: []
|
|
78
78
|
|
79
79
|
extensions: []
|
80
80
|
|
81
|
-
extra_rdoc_files:
|
82
|
-
|
81
|
+
extra_rdoc_files:
|
82
|
+
- TODO
|
83
83
|
files:
|
84
84
|
- .gitignore
|
85
85
|
- History.txt
|
@@ -89,6 +89,8 @@ files:
|
|
89
89
|
- lib/models/abstract_user.rb
|
90
90
|
- lib/models/datamapper_user.rb
|
91
91
|
- lib/models/dm_adapter.rb
|
92
|
+
- lib/models/mm_adapter.rb
|
93
|
+
- lib/models/mongomapper_user.rb
|
92
94
|
- lib/models/rufus_tokyo_user.rb
|
93
95
|
- lib/models/tc_adapter.rb
|
94
96
|
- lib/sinatra-authentication.rb
|
@@ -103,8 +105,10 @@ files:
|
|
103
105
|
- test/lib/dm_app.rb
|
104
106
|
- test/lib/dm_sinbook.rb
|
105
107
|
- test/lib/helper.rb
|
108
|
+
- test/lib/mm_app.rb
|
106
109
|
- test/lib/tc_app.rb
|
107
110
|
- test/lib/tc_sinbook.rb
|
111
|
+
- test/mongomapper_test.rb
|
108
112
|
- test/route_tests.rb
|
109
113
|
- test/rufus_tokyo_test.rb
|
110
114
|
has_rdoc: true
|
@@ -138,9 +142,11 @@ summary: Simple authentication plugin for sinatra.
|
|
138
142
|
test_files:
|
139
143
|
- test/lib/dm_sinbook.rb
|
140
144
|
- test/lib/tc_app.rb
|
145
|
+
- test/lib/mm_app.rb
|
141
146
|
- test/lib/tc_sinbook.rb
|
142
147
|
- test/lib/helper.rb
|
143
148
|
- test/lib/dm_app.rb
|
144
149
|
- test/datamapper_test.rb
|
150
|
+
- test/mongomapper_test.rb
|
145
151
|
- test/rufus_tokyo_test.rb
|
146
152
|
- test/route_tests.rb
|