sinatra-authentication-oran 0.0.1
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/Gemfile +33 -0
- data/History.txt +4 -0
- data/Manifest +26 -0
- data/Rakefile +43 -0
- data/TODO +53 -0
- data/UNLICENSE +24 -0
- data/example/database.yml +3 -0
- data/example/dm_extend_app.rb +26 -0
- data/example/dm_sinbook.rb +56 -0
- data/example/extend_views/edit.haml +42 -0
- data/example/extend_views/index.haml +31 -0
- data/example/extend_views/login.haml +21 -0
- data/example/extend_views/show.haml +9 -0
- data/example/extend_views/signup.haml +30 -0
- data/example/mm_app.rb +22 -0
- data/example/tc_app.rb +16 -0
- data/example/tc_sinbook.rb +62 -0
- data/lib/models/abstract_user.rb +95 -0
- data/lib/models/activerecord_user.rb +56 -0
- data/lib/models/ar_adapter.rb +66 -0
- data/lib/models/datamapper_user.rb +43 -0
- data/lib/models/dm_adapter.rb +61 -0
- data/lib/models/mm_adapter.rb +65 -0
- data/lib/models/mongoid_adapter.rb +67 -0
- data/lib/models/mongoid_user.rb +42 -0
- data/lib/models/mongomapper_user.rb +38 -0
- data/lib/models/rufus_tokyo_user.rb +206 -0
- data/lib/models/sequel_adapter.rb +68 -0
- data/lib/models/sequel_user.rb +53 -0
- data/lib/models/tc_adapter.rb +101 -0
- data/lib/sinatra-authentication-o.rb +305 -0
- data/lib/sinatra-authentication.rb +305 -0
- data/lib/sinatra-authentication/models.rb +5 -0
- data/lib/views/edit.haml +45 -0
- data/lib/views/edit.slim +46 -0
- data/lib/views/index.haml +29 -0
- data/lib/views/index.slim +30 -0
- data/lib/views/login.haml +24 -0
- data/lib/views/login.slim +25 -0
- data/lib/views/show.haml +9 -0
- data/lib/views/show.slim +10 -0
- data/lib/views/signup.haml +28 -0
- data/lib/views/signup.slim +33 -0
- data/readme.markdown +295 -0
- data/sinatra-authentication-oran.gemspec +137 -0
- data/spec/run_all_specs.rb +8 -0
- data/spec/unit/ar_model_spec.rb +3 -0
- data/spec/unit/dm_model_spec.rb +3 -0
- data/spec/unit/mm_model_spec.rb +3 -0
- data/spec/unit/mongoid_model_spec.rb +3 -0
- data/spec/unit/sequel_model_spec.rb +10 -0
- data/spec/unit/tc_model_spec.rb +3 -0
- data/spec/unit/user_specs.rb +119 -0
- data/test/activerecord_test.rb +5 -0
- data/test/datamapper_test.rb +5 -0
- data/test/lib/ar_app.rb +27 -0
- data/test/lib/dm_app.rb +20 -0
- data/test/lib/dm_extend_app.rb +27 -0
- data/test/lib/dm_sinbook.rb +54 -0
- data/test/lib/extend_views/edit.haml +46 -0
- data/test/lib/extend_views/index.haml +31 -0
- data/test/lib/extend_views/login.haml +21 -0
- data/test/lib/extend_views/show.haml +9 -0
- data/test/lib/extend_views/signup.haml +29 -0
- data/test/lib/helper.rb +16 -0
- data/test/lib/mm_app.rb +24 -0
- data/test/lib/mongoid_app.rb +28 -0
- data/test/lib/sequel_app.rb +21 -0
- data/test/lib/tc_app.rb +17 -0
- data/test/lib/tc_sinbook.rb +61 -0
- data/test/mongoid_test.rb +5 -0
- data/test/mongomapper_test.rb +40 -0
- data/test/route_tests.rb +29 -0
- data/test/rufus_tokyo_test.rb +5 -0
- data/test/sequel_test.rb +5 -0
- metadata +220 -0
data/example/tc_app.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'sinatra'
|
3
|
+
require 'haml'
|
4
|
+
require 'rufus/tokyo'
|
5
|
+
require 'sinatra-authentication'
|
6
|
+
|
7
|
+
use Rack::Session::Cookie, :secret => "heyhihello"
|
8
|
+
TcUserTable.cabinet_path = File.dirname(__FILE__)
|
9
|
+
|
10
|
+
set :environment, 'development'
|
11
|
+
set :public, 'public'
|
12
|
+
set :views, 'views'
|
13
|
+
|
14
|
+
get '/' do
|
15
|
+
haml "= render_login_logout", :layout => :layout
|
16
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'haml'
|
3
|
+
require 'sinbook'
|
4
|
+
require 'rufus/tokyo'
|
5
|
+
require 'sinatra'
|
6
|
+
require 'sinatra-authentication'
|
7
|
+
|
8
|
+
use Rack::Session::Cookie, :secret => "heyhihello"
|
9
|
+
TcUserTable.cabinet_path = File.dirname(__FILE__)
|
10
|
+
|
11
|
+
facebook do
|
12
|
+
api_key 'aa2db1b96cb7b57f0c5b1d4d3d8f0a22'
|
13
|
+
secret '21d94ee63969ae3b3f833689838ca00f'
|
14
|
+
app_id 48652736613
|
15
|
+
url 'peoplewithjetpacks.com:4568/'
|
16
|
+
callback 'peoplewithjetpacks.com:4568/'
|
17
|
+
end
|
18
|
+
|
19
|
+
set :port, 4568
|
20
|
+
|
21
|
+
get '/' do
|
22
|
+
haml :main
|
23
|
+
end
|
24
|
+
|
25
|
+
get '/test' do
|
26
|
+
login_required
|
27
|
+
'hihihi'
|
28
|
+
end
|
29
|
+
|
30
|
+
__END__
|
31
|
+
|
32
|
+
@@ layout
|
33
|
+
%html{:xmlns=>"http://www.w3.org/1999/xhtml", :'xmlns:fb'=>"http://www.facebook.com/2008/fbml"}
|
34
|
+
%head
|
35
|
+
%title Welcome to my Facebook Connect website!
|
36
|
+
%script{:type => 'text/javascript', :src => 'http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/en_US'}
|
37
|
+
%script{:type => 'text/javascript', :src => 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js'}
|
38
|
+
:javascript
|
39
|
+
$(document).ready(function(){
|
40
|
+
/* test facebook crap works with ajax */
|
41
|
+
$('.sinatra-authentication-login').click(function(){
|
42
|
+
$.get($(this).attr('href'), {}, function(data){
|
43
|
+
$('#test_box').html(data);
|
44
|
+
});
|
45
|
+
return false;
|
46
|
+
});
|
47
|
+
});
|
48
|
+
%body
|
49
|
+
= render_login_logout
|
50
|
+
= yield
|
51
|
+
:javascript
|
52
|
+
FB.init("#{fb.api_key}", "/receiver")
|
53
|
+
#test_box
|
54
|
+
|
55
|
+
@@ main
|
56
|
+
- if fb[:user]
|
57
|
+
Hi,
|
58
|
+
%fb:profile-pic{:uid => fb[:user]}
|
59
|
+
%fb:name{:uid => fb[:user], :useyou => 'false', :firstnameonly => 'true'}
|
60
|
+
!
|
61
|
+
%br/
|
62
|
+
|
@@ -0,0 +1,95 @@
|
|
1
|
+
current_path = File.expand_path("..", __FILE__)
|
2
|
+
if Object.const_defined?("DataMapper")
|
3
|
+
#require 'dm-core'
|
4
|
+
require 'dm-timestamps'
|
5
|
+
require 'dm-validations'
|
6
|
+
require File.join(current_path, 'datamapper_user')
|
7
|
+
require File.join(current_path, 'dm_adapter')
|
8
|
+
elsif Object.const_defined?("Rufus") && Rufus.const_defined?("Tokyo")
|
9
|
+
require File.join(current_path, 'rufus_tokyo_user')
|
10
|
+
require File.join(current_path, 'tc_adapter')
|
11
|
+
elsif Object.const_defined?("MongoMapper")
|
12
|
+
require File.join(current_path, 'mongomapper_user')
|
13
|
+
require File.join(current_path, 'mm_adapter')
|
14
|
+
elsif Object.const_defined?("Sequel")
|
15
|
+
require File.join(current_path, 'sequel_user')
|
16
|
+
require File.join(current_path, 'sequel_adapter')
|
17
|
+
elsif Object.const_defined?("Mongoid")
|
18
|
+
require File.join(current_path, 'mongoid_user')
|
19
|
+
require File.join(current_path, 'mongoid_adapter')
|
20
|
+
end
|
21
|
+
|
22
|
+
class User
|
23
|
+
if Object.const_defined?("DataMapper")
|
24
|
+
include DmAdapter
|
25
|
+
elsif Object.const_defined?("Rufus")
|
26
|
+
include TcAdapter
|
27
|
+
elsif Object.const_defined?("MongoMapper")
|
28
|
+
include MmAdapter
|
29
|
+
elsif Object.const_defined?("Sequel")
|
30
|
+
include SequelAdapter
|
31
|
+
elsif Object.const_defined?("Mongoid")
|
32
|
+
include MongoidAdapter
|
33
|
+
elsif Object.const_defined?("ActiveRecord")
|
34
|
+
include ArAdapter
|
35
|
+
else
|
36
|
+
throw "you need to require either 'dm-core', 'mongo_mapper', 'sequel', 'mongoid', or 'rufus-tokyo' for sinatra-authentication to work"
|
37
|
+
end
|
38
|
+
|
39
|
+
def initialize(interfacing_class_instance)
|
40
|
+
@instance = interfacing_class_instance
|
41
|
+
end
|
42
|
+
|
43
|
+
def id
|
44
|
+
@instance.id
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.authenticate(email, pass)
|
48
|
+
current_user = get(:email => email)
|
49
|
+
return nil if current_user.nil?
|
50
|
+
return current_user if User.encrypt(pass, current_user.salt) == current_user.hashed_password
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
|
54
|
+
def db_instance
|
55
|
+
@instance
|
56
|
+
end
|
57
|
+
|
58
|
+
protected
|
59
|
+
|
60
|
+
def self.encrypt(pass, salt)
|
61
|
+
Digest::SHA1.hexdigest(pass+salt)
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.random_string(len)
|
65
|
+
#generate a random password consisting of strings and digits
|
66
|
+
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
|
67
|
+
newpass = ""
|
68
|
+
1.upto(len) { |i| newpass << chars[rand(chars.size-1)] }
|
69
|
+
return newpass
|
70
|
+
end
|
71
|
+
|
72
|
+
#def self.page_limit
|
73
|
+
# 20
|
74
|
+
#end
|
75
|
+
|
76
|
+
#def self.page_offset(page = 0)
|
77
|
+
# page.to_i * self.page_limit
|
78
|
+
#end
|
79
|
+
end
|
80
|
+
|
81
|
+
class Hash
|
82
|
+
def stringify
|
83
|
+
inject({}) do |options, (key, value)|
|
84
|
+
options[key.to_s] = value.to_s
|
85
|
+
options
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def stringify!
|
90
|
+
each do |key, value|
|
91
|
+
delete(key)
|
92
|
+
store(key.to_s, value.to_s)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
unless ActiveRecord::Base.connection.table_exists?("ar_users")
|
2
|
+
class CreateArUsers < ActiveRecord::Migration
|
3
|
+
def self.up
|
4
|
+
create_table :ar_users do |t|
|
5
|
+
t.string :email
|
6
|
+
t.string :hashed_password
|
7
|
+
t.string :salt
|
8
|
+
t.integer :permission_level
|
9
|
+
t.string :fb_uid
|
10
|
+
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
|
14
|
+
add_index :ar_users, :email, :unique => true
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.down
|
18
|
+
remove_index :ar_users, :email
|
19
|
+
drop_table :ar_users
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
CreateArUsers.up
|
24
|
+
end
|
25
|
+
|
26
|
+
#require 'logger'
|
27
|
+
#ActiveRecord::Base.logger = Logger.new(STDOUT)
|
28
|
+
|
29
|
+
class ArUser < ActiveRecord::Base
|
30
|
+
|
31
|
+
attr_accessor :password, :password_confirmation
|
32
|
+
|
33
|
+
validates_format_of :email, :with => /(\A(\s*)\Z)|(\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z)/i
|
34
|
+
validates_uniqueness_of :email
|
35
|
+
validates_presence_of :password_confirmation, :unless => Proc.new { |t| t.hashed_password }
|
36
|
+
validates_presence_of :password, :unless => Proc.new { |t| t.hashed_password }
|
37
|
+
validates_confirmation_of :password
|
38
|
+
|
39
|
+
def password=(pass)
|
40
|
+
@password = pass
|
41
|
+
self.salt = User.random_string(10) if !self.salt
|
42
|
+
self.hashed_password = User.encrypt(@password, self.salt)
|
43
|
+
end
|
44
|
+
|
45
|
+
def admin?
|
46
|
+
self.permission_level == -1 || self.id == 1
|
47
|
+
end
|
48
|
+
|
49
|
+
def site_admin?
|
50
|
+
self.id == 1
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_ary
|
54
|
+
self.attributes.values
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module ArAdapter
|
2
|
+
def self.included(base)
|
3
|
+
base.extend ClassMethods
|
4
|
+
base.class_eval { include ArAdapter::InstanceMethods }
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
#pass all args to this
|
9
|
+
def all
|
10
|
+
result = ArUser.all(:order => ["created_at DESC"])
|
11
|
+
result.collect {|instance| self.new instance}
|
12
|
+
end
|
13
|
+
|
14
|
+
def get(hash)
|
15
|
+
if user = ArUser.where(hash).first
|
16
|
+
self.new user
|
17
|
+
else
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def set(attributes)
|
23
|
+
user = ArUser.new attributes
|
24
|
+
user.save
|
25
|
+
self.new user
|
26
|
+
end
|
27
|
+
|
28
|
+
def set!(attributes)
|
29
|
+
user = ArUser.new attributes
|
30
|
+
user.save!
|
31
|
+
self.new user
|
32
|
+
end
|
33
|
+
|
34
|
+
def delete(pk)
|
35
|
+
user = ArUser.first(pk).first
|
36
|
+
user.destroy
|
37
|
+
user.destroyed?
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
module InstanceMethods
|
42
|
+
def valid
|
43
|
+
@instance.valid?
|
44
|
+
end
|
45
|
+
|
46
|
+
def errors
|
47
|
+
@instance.errors.collect do |k,v|
|
48
|
+
"#{k} #{v}"
|
49
|
+
end.join(', ')
|
50
|
+
end
|
51
|
+
|
52
|
+
def update(attributes)
|
53
|
+
@instance.update_attributes attributes
|
54
|
+
#self
|
55
|
+
end
|
56
|
+
|
57
|
+
def saved
|
58
|
+
@instance.valid?
|
59
|
+
end
|
60
|
+
|
61
|
+
def method_missing(meth, *args, &block)
|
62
|
+
#cool I just found out * on an array turns the array into a list of args for a function
|
63
|
+
@instance.send(meth, *args, &block)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class DmUser
|
2
|
+
include DataMapper::Resource
|
3
|
+
|
4
|
+
property :id, Serial
|
5
|
+
property :email, String, :length => (5..40), :unique => true, :format => :email_address
|
6
|
+
property :hashed_password, String
|
7
|
+
property :salt, String
|
8
|
+
#Was DateTime should be DateTime?
|
9
|
+
property :created_at, Time
|
10
|
+
property :permission_level, Integer, :default => 1
|
11
|
+
if Sinatra.const_defined?('FacebookObject')
|
12
|
+
property :fb_uid, String
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_accessor :password, :password_confirmation
|
16
|
+
#protected equievelant? :protected => true doesn't exist in dm 0.10.0
|
17
|
+
#protected :id, :salt
|
18
|
+
#doesn't behave correctly, I'm not even sure why I did this.
|
19
|
+
|
20
|
+
validates_presence_of :password_confirmation, :unless => Proc.new { |t| t.hashed_password }
|
21
|
+
validates_presence_of :password, :unless => Proc.new { |t| t.hashed_password }
|
22
|
+
validates_confirmation_of :password
|
23
|
+
|
24
|
+
def password=(pass)
|
25
|
+
@password = pass
|
26
|
+
self.salt = User.random_string(10) if !self.salt
|
27
|
+
self.hashed_password = User.encrypt(@password, self.salt)
|
28
|
+
end
|
29
|
+
|
30
|
+
def admin?
|
31
|
+
self.permission_level == -1 || self.id == 1
|
32
|
+
end
|
33
|
+
|
34
|
+
def site_admin?
|
35
|
+
self.id == 1
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
def method_missing(m, *args)
|
41
|
+
return false
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module DmAdapter
|
2
|
+
def self.included(base)
|
3
|
+
base.extend ClassMethods
|
4
|
+
base.class_eval { include DmAdapter::InstanceMethods }
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
#pass all args to this
|
9
|
+
def all
|
10
|
+
result = DmUser.all(:order => [:created_at.desc])
|
11
|
+
result.collect {|instance| self.new instance}
|
12
|
+
end
|
13
|
+
|
14
|
+
def get(hash)
|
15
|
+
if user = DmUser.first(hash)
|
16
|
+
self.new user
|
17
|
+
else
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def set(attributes)
|
23
|
+
user = DmUser.new attributes
|
24
|
+
user.save
|
25
|
+
self.new user
|
26
|
+
end
|
27
|
+
|
28
|
+
def set!(attributes)
|
29
|
+
user = DmUser.new attributes
|
30
|
+
user.save!
|
31
|
+
self.new user
|
32
|
+
end
|
33
|
+
|
34
|
+
def delete(pk)
|
35
|
+
user = DmUser.first(:id => pk)
|
36
|
+
user.destroy
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module InstanceMethods
|
41
|
+
def valid
|
42
|
+
@instance.valid?
|
43
|
+
end
|
44
|
+
|
45
|
+
def errors
|
46
|
+
@instance.errors.collect do |k,v|
|
47
|
+
"#{k} #{v}"
|
48
|
+
end.join(', ')
|
49
|
+
end
|
50
|
+
|
51
|
+
def update(attributes)
|
52
|
+
@instance.update attributes
|
53
|
+
#self
|
54
|
+
end
|
55
|
+
|
56
|
+
def method_missing(meth, *args, &block)
|
57
|
+
#cool I just found out * on an array turns the array into a list of args for a function
|
58
|
+
@instance.send(meth, *args, &block)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,65 @@
|
|
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(:order => 'created_at desc')
|
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
|
+
user.id = nil unless user.save
|
25
|
+
self.new user
|
26
|
+
end
|
27
|
+
|
28
|
+
def set!(attributes)
|
29
|
+
user = MmUser.new attributes
|
30
|
+
user.save(:validate => false)
|
31
|
+
self.new user
|
32
|
+
end
|
33
|
+
|
34
|
+
def delete(pk)
|
35
|
+
user = MmUser.first(:id => pk)
|
36
|
+
#returns nil on success. Is this correct? Will it return something else on failure?
|
37
|
+
user.destroy
|
38
|
+
user.destroyed?
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
module InstanceMethods
|
43
|
+
def valid
|
44
|
+
@instance.valid?
|
45
|
+
end
|
46
|
+
|
47
|
+
def update(attributes)
|
48
|
+
@instance.update_attributes attributes
|
49
|
+
@instance.save
|
50
|
+
end
|
51
|
+
|
52
|
+
def saved
|
53
|
+
@instance.valid?
|
54
|
+
end
|
55
|
+
|
56
|
+
def errors
|
57
|
+
@instance.errors.full_messages.join(', ')
|
58
|
+
end
|
59
|
+
|
60
|
+
def method_missing(meth, *args, &block)
|
61
|
+
#cool I just found out * on an array turns the array into a list of args for a function
|
62
|
+
@instance.send(meth, *args, &block)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|