sinatra-simple-authentication 1.0.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/lib/sinatra/simple-authentication.rb +27 -0
- data/lib/sinatra/simple_authentication/controllers/defaults.rb +67 -0
- data/lib/sinatra/simple_authentication/controllers/helpers.rb +42 -0
- data/lib/sinatra/simple_authentication/controllers/session.rb +136 -0
- data/lib/sinatra/simple_authentication/models/active_record/adapter.rb +55 -0
- data/lib/sinatra/simple_authentication/models/active_record/user.rb +39 -0
- data/lib/sinatra/simple_authentication/models/common/instance_methods.rb +33 -0
- data/lib/sinatra/simple_authentication/models/datamapper/adapter.rb +59 -0
- data/lib/sinatra/simple_authentication/models/datamapper/user.rb +22 -0
- data/lib/sinatra/simple_authentication/views/_form.haml +18 -0
- data/lib/sinatra/simple_authentication/views/login.haml +14 -0
- data/lib/sinatra/simple_authentication/views/signup.haml +3 -0
- data/test/tc_active_record.rb +102 -0
- data/test/tc_datamapper.rb +105 -0
- metadata +221 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module SimpleAuthentication
|
5
|
+
require File.join(File.expand_path("..", __FILE__), "simple_authentication/controllers/defaults")
|
6
|
+
require File.join(File.expand_path("..", __FILE__), "simple_authentication/controllers/helpers")
|
7
|
+
require File.join(File.expand_path("..", __FILE__), "simple_authentication/controllers/session")
|
8
|
+
|
9
|
+
def self.registered(app)
|
10
|
+
Sinatra::SimpleAuthentication::Controllers::Session.registered(app)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.require_adapter()
|
14
|
+
if Object.const_defined?("DataMapper")
|
15
|
+
require File.join(File.expand_path("..", __FILE__), "simple_authentication/models/datamapper/adapter")
|
16
|
+
elsif Object.const_defined?("ActiveRecord")
|
17
|
+
require File.join(File.expand_path("..", __FILE__), "simple_authentication/models/active_record/adapter")
|
18
|
+
else
|
19
|
+
throw "Not DataMapper nor ActiveRecord connection detected."
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.configure(&block)
|
24
|
+
Sinatra::SimpleAuthentication::Controllers::Defaults.configure(&block)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module SimpleAuthentication
|
5
|
+
module Controllers
|
6
|
+
module Defaults
|
7
|
+
class << self
|
8
|
+
attr_accessor :use_password_confirmation,
|
9
|
+
:max_password_length,
|
10
|
+
:min_password_length,
|
11
|
+
:taken_email_message,
|
12
|
+
:missing_email_message,
|
13
|
+
:invalid_email_message,
|
14
|
+
:missing_password_message,
|
15
|
+
:short_password_message,
|
16
|
+
:long_password_message,
|
17
|
+
:missing_password_confirmation_message,
|
18
|
+
:password_confirmation_dont_match_password_message,
|
19
|
+
:login_wrong_email_message,
|
20
|
+
:login_wrong_password_message,
|
21
|
+
:login_successful_message
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.configure(&block)
|
25
|
+
yield self
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.setDefaults(app)
|
29
|
+
app.set :sinatra_authentication_view_path, File.expand_path(File.join("../..", "views"), __FILE__)
|
30
|
+
app.enable :sessions
|
31
|
+
|
32
|
+
#Set costum variables
|
33
|
+
app.set :use_password_confirmation, use_password_confirmation.nil? ? false : use_password_confirmation
|
34
|
+
app.set :min_password_length, min_password_length.nil? ? 4 : min_password_length
|
35
|
+
app.set :max_password_length, max_password_length.nil? ? 16 : max_password_length
|
36
|
+
|
37
|
+
app.set :login_wrong_email_message, login_wrong_email_message.nil? ? "Wrong email address." : login_wrong_email_message
|
38
|
+
app.set :login_wrong_password_message, login_wrong_password_message.nil? ? "Wrong password." : login_wrong_password_message
|
39
|
+
app.set :login_successful_message, login_successful_message.nil? ? "Login successful." : login_successful_message
|
40
|
+
|
41
|
+
#Validations errors messages
|
42
|
+
taken_email = taken_email_message.nil? ? "Email has already been taken." : taken_email_message
|
43
|
+
missing_email = missing_email_message.nil? ? "Email can't be blank." : missing_email_message
|
44
|
+
invalid_email = invalid_email_message.nil? ? "Invalid email format." : invalid_email_message
|
45
|
+
missing_password = missing_password_message.nil? ? "Password can't be blank." : missing_password_message
|
46
|
+
short_password = short_password_message.nil? ? "Password is too short, must be between #{app.settings.min_password_length} and #{app.settings.max_password_length} characters long." : short_password_message
|
47
|
+
long_password = long_password_message.nil? ? "Password is too long, must be between #{app.settings.min_password_length} and #{app.settings.max_password_length} characters long." : long_password_message
|
48
|
+
missing_password_confirmation = missing_password_confirmation_message.nil? ? "Password confirmation can't be blank." : missing_password_confirmation_message
|
49
|
+
password_confirmation_dont_match_password = password_confirmation_dont_match_password_message.nil? ? "Password confirmation doesn't match password." : password_confirmation_dont_match_password_message
|
50
|
+
|
51
|
+
app.set :error_messages, { :missing_email => missing_email,
|
52
|
+
:taken_email => taken_email,
|
53
|
+
:invalid_email => invalid_email,
|
54
|
+
:missing_password => missing_password,
|
55
|
+
:short_password => short_password,
|
56
|
+
:long_password => long_password,
|
57
|
+
:missing_password_confirmation => missing_password_confirmation,
|
58
|
+
:password_confirmation_dont_match_password => password_confirmation_dont_match_password
|
59
|
+
}
|
60
|
+
|
61
|
+
app
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module SimpleAuthentication
|
5
|
+
module Controllers
|
6
|
+
module Helpers
|
7
|
+
def login_required
|
8
|
+
if !!current_user
|
9
|
+
return true
|
10
|
+
else
|
11
|
+
session[:return_to] = request.fullpath
|
12
|
+
redirect '/login'
|
13
|
+
return false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def current_user
|
18
|
+
if !!session[:user]
|
19
|
+
Session.model_class.find_user(:id => session[:user])
|
20
|
+
else
|
21
|
+
return false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def logged_in?
|
26
|
+
!!session[:user]
|
27
|
+
end
|
28
|
+
|
29
|
+
#BECAUSE sinatra 9.1.1 can't load views from different paths properly
|
30
|
+
def get_view_as_string(filename)
|
31
|
+
view = File.join(settings.sinatra_authentication_view_path, filename)
|
32
|
+
data = ""
|
33
|
+
f = File.open(view, "r")
|
34
|
+
f.each_line do |line|
|
35
|
+
data += line
|
36
|
+
end
|
37
|
+
return data
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require "rubygems"
|
4
|
+
require 'haml'
|
5
|
+
require 'sinatra/base'
|
6
|
+
|
7
|
+
module Sinatra
|
8
|
+
module SimpleAuthentication
|
9
|
+
module Controllers
|
10
|
+
module Session
|
11
|
+
class << self
|
12
|
+
attr_accessor :base_path,
|
13
|
+
:model_class
|
14
|
+
end
|
15
|
+
|
16
|
+
self.base_path = File.expand_path("../..", __FILE__)
|
17
|
+
|
18
|
+
def self.registered(app)
|
19
|
+
require File.join(self.base_path, "controllers/defaults")
|
20
|
+
#load_user_class will set the corresponding model class
|
21
|
+
Session.model_class = self.load_user_class
|
22
|
+
app.helpers Helpers
|
23
|
+
app = Defaults.setDefaults(app)
|
24
|
+
Session.model_class.settings = app.settings
|
25
|
+
Session.model_class.set_validation_rules
|
26
|
+
|
27
|
+
app.get "/signup" do
|
28
|
+
@password_confirmation = settings.use_password_confirmation
|
29
|
+
@user = Session.model_class.new
|
30
|
+
@actionUrl = ""
|
31
|
+
#Try to load an user view otherwise load the default
|
32
|
+
begin
|
33
|
+
haml :"/signup"
|
34
|
+
rescue
|
35
|
+
haml get_view_as_string("signup.haml")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
app.post "/signup" do
|
40
|
+
@user = Session.model_class.new
|
41
|
+
#Support custom user models with differents attributs (But always have to receive email and password)
|
42
|
+
params.each do |k, v|
|
43
|
+
@user.respond_to?(k)
|
44
|
+
@user.send(k + "=", v)
|
45
|
+
end
|
46
|
+
|
47
|
+
if @user.save
|
48
|
+
redirect '/'
|
49
|
+
else
|
50
|
+
@password_confirmation = settings.use_password_confirmation
|
51
|
+
if Rack.const_defined?('Flash')
|
52
|
+
if Object.const_defined?("DataMapper")
|
53
|
+
flash[:error] = @user.errors.full_messages
|
54
|
+
else
|
55
|
+
flash[:error] = @user.errors.map {|i, m| m}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
#Try to load a local user view otherwise load the default
|
59
|
+
begin
|
60
|
+
haml :"/signup"
|
61
|
+
rescue
|
62
|
+
haml get_view_as_string("signup.haml")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
app.get "/login" do
|
68
|
+
if !!session[:user]
|
69
|
+
redirect '/'
|
70
|
+
else
|
71
|
+
#Try to load a local user view otherwise load the default
|
72
|
+
begin
|
73
|
+
haml :"/login"
|
74
|
+
rescue
|
75
|
+
haml get_view_as_string("login.haml")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
app.post "/login" do
|
81
|
+
if user = Session.model_class.find_user(:email => params[:email])
|
82
|
+
if user.authenticate(params[:password])
|
83
|
+
session[:user] = user.id
|
84
|
+
if Rack.const_defined?('Flash')
|
85
|
+
flash[:notice] = [app.settings.login_successful_message]
|
86
|
+
end
|
87
|
+
|
88
|
+
if !!session[:return_to]
|
89
|
+
redirect_url = session[:return_to]
|
90
|
+
session[:return_to] = false
|
91
|
+
redirect redirect_url
|
92
|
+
else
|
93
|
+
redirect '/'
|
94
|
+
end
|
95
|
+
else
|
96
|
+
if Rack.const_defined?('Flash')
|
97
|
+
flash[:error] = [app.settings.login_wrong_password_message]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
else
|
101
|
+
if Rack.const_defined?('Flash')
|
102
|
+
flash[:error] = [app.settings.login_wrong_email_message]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
redirect '/login'
|
106
|
+
end
|
107
|
+
|
108
|
+
app.get '/logout' do
|
109
|
+
session[:user] = nil
|
110
|
+
redirect '/'
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.load_user_class
|
115
|
+
if Object.const_defined?("DataMapper")
|
116
|
+
orm_directory_name = "datamapper"
|
117
|
+
require File.join(self.base_path, "models/datamapper/adapter")
|
118
|
+
base_module = Sinatra::SimpleAuthentication::Models::DataMapper
|
119
|
+
elsif Object.const_defined?("ActiveRecord")
|
120
|
+
orm_directory_name = "active_record"
|
121
|
+
require File.join(self.base_path, "models/active_record/adapter")
|
122
|
+
base_module = Sinatra::SimpleAuthentication::Models::ActiveRecord
|
123
|
+
else
|
124
|
+
throw "Not DataMapper nor ActiveRecord connection detected."
|
125
|
+
end
|
126
|
+
|
127
|
+
if !base_module::Adapter.model_class
|
128
|
+
require File.join(self.base_path, "models/#{orm_directory_name}/user")
|
129
|
+
end
|
130
|
+
|
131
|
+
base_module::Adapter.model_class
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require File.join(File.expand_path("../../common", __FILE__), 'instance_methods')
|
4
|
+
|
5
|
+
module Sinatra
|
6
|
+
module SimpleAuthentication
|
7
|
+
module Models
|
8
|
+
module ActiveRecord
|
9
|
+
module Adapter
|
10
|
+
class << self; attr_accessor :model_class; end
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
self.model_class = base
|
14
|
+
base.extend ClassMethods
|
15
|
+
base.class_eval do
|
16
|
+
include InstanceMethods
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
attr_accessor :settings
|
22
|
+
|
23
|
+
def set_validation_rules
|
24
|
+
validates_presence_of :email, :message => self.settings.error_messages[:missing_email]
|
25
|
+
validates_format_of :email, :with => /(\A(\s*)\Z)|(\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z)/, :message => self.settings.error_messages[:invalid_email]
|
26
|
+
validates_uniqueness_of :email, :message => self.settings.error_messages[:taken_email]
|
27
|
+
|
28
|
+
if Proc.new { |t| t.new_record? }
|
29
|
+
validates_presence_of :password, :message => self.settings.error_messages[:missing_password]
|
30
|
+
validates_length_of :password, :minimum => self.settings.min_password_length, :message => self.settings.error_messages[:short_password]
|
31
|
+
validates_length_of :password, :maximum => self.settings.max_password_length, :message => self.settings.error_messages[:long_password]
|
32
|
+
|
33
|
+
if self.settings.use_password_confirmation
|
34
|
+
validates_presence_of :password_confirmation, :message => self.settings.error_messages[:missing_password_confirmation]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
if self.settings.use_password_confirmation
|
39
|
+
validates_confirmation_of :password, :message => self.settings.error_messages[:password_confirmation_dont_match_password]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def find_user(params)
|
44
|
+
self.where(params).first
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
module InstanceMethods
|
49
|
+
include Common::InstanceMethods
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'active_record'
|
5
|
+
require 'digest'
|
6
|
+
|
7
|
+
module Sinatra
|
8
|
+
module SimpleAuthentication
|
9
|
+
module Models
|
10
|
+
module ActiveRecord
|
11
|
+
unless ::ActiveRecord::Base.connection.table_exists?("ar_users")
|
12
|
+
class CreateUsers < ::ActiveRecord::Migration
|
13
|
+
def self.up
|
14
|
+
create_table :ar_users do |t|
|
15
|
+
t.string :email
|
16
|
+
t.string :hashed_password
|
17
|
+
t.string :salt
|
18
|
+
#t.timestamps
|
19
|
+
end
|
20
|
+
|
21
|
+
add_index :ar_users, :email, :unique => true
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.down
|
25
|
+
remove_index :ar_users, :email
|
26
|
+
drop_table :ar_users
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
CreateUsers.up
|
31
|
+
end
|
32
|
+
|
33
|
+
class ArUser < ::ActiveRecord::Base
|
34
|
+
include Adapter
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module SimpleAuthentication
|
5
|
+
module Models
|
6
|
+
module Common
|
7
|
+
module InstanceMethods
|
8
|
+
attr_accessor :password, :password_confirmation
|
9
|
+
|
10
|
+
def password=(pass)
|
11
|
+
if !pass.strip.empty?
|
12
|
+
@password = pass
|
13
|
+
self.salt = generate_salt unless self.salt
|
14
|
+
self.hashed_password = encrypt(pass, self.salt)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def generate_salt
|
19
|
+
(0..25).inject('') { |r, i| r << rand(93) + 33 }
|
20
|
+
end
|
21
|
+
|
22
|
+
def encrypt(password, salt)
|
23
|
+
Digest::SHA1.hexdigest(password + salt)
|
24
|
+
end
|
25
|
+
|
26
|
+
def authenticate(pass)
|
27
|
+
encrypt(pass, self.salt) == self.hashed_password
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require File.join(File.expand_path("../../common", __FILE__), 'instance_methods')
|
4
|
+
|
5
|
+
module Sinatra
|
6
|
+
module SimpleAuthentication
|
7
|
+
module Models
|
8
|
+
module DataMapper
|
9
|
+
module Adapter
|
10
|
+
class << self; attr_accessor :model_class; end
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
self.model_class = base
|
14
|
+
base.extend ClassMethods
|
15
|
+
base.class_eval do
|
16
|
+
base.property :id, ::DataMapper::Property::Serial
|
17
|
+
base.property :email, ::DataMapper::Property::String
|
18
|
+
base.property :hashed_password, ::DataMapper::Property::String
|
19
|
+
base.property :salt, ::DataMapper::Property::String
|
20
|
+
include InstanceMethods
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module ClassMethods
|
25
|
+
attr_accessor :settings
|
26
|
+
|
27
|
+
def set_validation_rules
|
28
|
+
validates_presence_of :email, :message => self.settings.error_messages[:missing_email]
|
29
|
+
validates_uniqueness_of :email, :message => self.settings.error_messages[:taken_email]
|
30
|
+
validates_format_of :email, :as => :email_address, :message => self.settings.error_messages[:invalid_email]
|
31
|
+
|
32
|
+
if Proc.new { |t| t.new_record? }
|
33
|
+
validates_presence_of :password, :message => self.settings.error_messages[:missing_password]
|
34
|
+
validates_length_of :password, :min => self.settings.min_password_length, :message => self.settings.error_messages[:short_password]
|
35
|
+
validates_length_of :password, :max => self.settings.max_password_length, :message => self.settings.error_messages[:long_password]
|
36
|
+
|
37
|
+
if self.settings.use_password_confirmation
|
38
|
+
validates_presence_of :password_confirmation, :message => self.settings.error_messages[:missing_password_confirmation]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
if self.settings.use_password_confirmation
|
43
|
+
validates_confirmation_of :password, :message => self.settings.error_messages[:password_confirmation_dont_match_password]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def find_user(params)
|
48
|
+
self.first(params)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
module InstanceMethods
|
53
|
+
include Common::InstanceMethods
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'dm-core'
|
5
|
+
require 'dm-validations'
|
6
|
+
require 'dm-migrations'
|
7
|
+
require 'digest'
|
8
|
+
|
9
|
+
module Sinatra
|
10
|
+
module SimpleAuthentication
|
11
|
+
module Models
|
12
|
+
module DataMapper
|
13
|
+
class DmUser
|
14
|
+
include ::DataMapper::Resource
|
15
|
+
include Adapter
|
16
|
+
end
|
17
|
+
|
18
|
+
DmUser.auto_upgrade!
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
%form{:action => @actionUrl, :method => "post", :enctype => "multipart/form-data"}
|
2
|
+
%fieldset
|
3
|
+
%table
|
4
|
+
%tbody
|
5
|
+
%tr
|
6
|
+
%td
|
7
|
+
%label{:for => "email"} Email:
|
8
|
+
%input{:type => "text", :name => "email", :class => "text", :value => @user[:email]}
|
9
|
+
%tr
|
10
|
+
%td
|
11
|
+
%label{:for => "password"} Password:
|
12
|
+
%input{:type => "password", :name => "password", :class => "text", :value => @user[:password]}
|
13
|
+
- if @password_confirmation
|
14
|
+
%tr
|
15
|
+
%td
|
16
|
+
%label{:for => "password_confirmation"} Password confirmation:
|
17
|
+
%input{:type => "password", :name => "password_confirmation", :class => "text"}
|
18
|
+
%input{:type => "submit", :value => "Send", :class => "button"}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
%h1 Login
|
2
|
+
%form{:action => "/login", :method => "post"}
|
3
|
+
.field
|
4
|
+
.label
|
5
|
+
%label{:for => "user_email'"} Email
|
6
|
+
%input{:id => "user_email", :name => "email", :size => 30, :type => "text"}
|
7
|
+
.field
|
8
|
+
.label
|
9
|
+
%label{:for => "user_password"} Password
|
10
|
+
%input{:id => "user_password", :name => "password", :size => 30, :type => "password"}
|
11
|
+
.buttons
|
12
|
+
%input{:value => "Login", :type => "submit"}
|
13
|
+
%a{:href => "/signup"}
|
14
|
+
Sign up
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'sinatra/base'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rack/test'
|
5
|
+
require 'active_record'
|
6
|
+
require 'sinatra/simple-authentication'
|
7
|
+
require 'nokogiri'
|
8
|
+
|
9
|
+
module Sinatra
|
10
|
+
class Base
|
11
|
+
set :environment, :test
|
12
|
+
::ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => "#{Dir.pwd}/test.db")
|
13
|
+
register Sinatra::SimpleAuthentication
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class TcActiveRecord < Test::Unit::TestCase
|
18
|
+
include Rack::Test::Methods
|
19
|
+
|
20
|
+
def app
|
21
|
+
Sinatra::Application
|
22
|
+
end
|
23
|
+
|
24
|
+
def teardown
|
25
|
+
Sinatra::SimpleAuthentication::Controllers::Session.model_class.delete_all
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_signup_page
|
29
|
+
get '/signup'
|
30
|
+
assert last_response.ok?
|
31
|
+
|
32
|
+
html = Nokogiri::HTML(last_response.body)
|
33
|
+
assert html.css('[name="email"]')
|
34
|
+
assert html.css('[name="password"]')
|
35
|
+
assert html.css('[name="password_confirmation"]')
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_login_page
|
39
|
+
get '/login'
|
40
|
+
assert last_response.ok?
|
41
|
+
|
42
|
+
html = Nokogiri::HTML(last_response.body)
|
43
|
+
assert html.css('[name="email"]')
|
44
|
+
assert html.css('[name="password"]')
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_user_validations
|
48
|
+
taken_email = "Email has already been taken."
|
49
|
+
missing_email = "Email can't be blank."
|
50
|
+
invalid_email = "Invalid email format."
|
51
|
+
missing_password = "Password can't be blank."
|
52
|
+
short_password = "Password is too short, must be between 4 and 16 characters long."
|
53
|
+
long_password = "Password is too long, must be between 4 and 16 characters long."
|
54
|
+
|
55
|
+
#Empty user
|
56
|
+
user = Sinatra::SimpleAuthentication::Controllers::Session.model_class.new
|
57
|
+
|
58
|
+
assert !user.save
|
59
|
+
assert user.errors[:email].include?(missing_email)
|
60
|
+
assert user.errors[:password].include?(missing_password)
|
61
|
+
assert user.errors[:password].include?(short_password)
|
62
|
+
|
63
|
+
#Short password
|
64
|
+
user = Sinatra::SimpleAuthentication::Controllers::Session.model_class.new
|
65
|
+
user.password = "X" * 3
|
66
|
+
|
67
|
+
assert !user.save
|
68
|
+
assert user.errors[:email].include?(missing_email)
|
69
|
+
assert user.errors[:password].include?(short_password)
|
70
|
+
|
71
|
+
#Long password
|
72
|
+
user = Sinatra::SimpleAuthentication::Controllers::Session.model_class.new
|
73
|
+
user.password = "X" * 17
|
74
|
+
|
75
|
+
assert !user.save
|
76
|
+
assert user.errors[:email].include?(missing_email)
|
77
|
+
assert user.errors[:password].include?(long_password)
|
78
|
+
|
79
|
+
#Wrong format email
|
80
|
+
user = Sinatra::SimpleAuthentication::Controllers::Session.model_class.new
|
81
|
+
user.email = "InvaidEmailFormat"
|
82
|
+
|
83
|
+
assert !user.save
|
84
|
+
assert user.errors[:email].include?(invalid_email)
|
85
|
+
assert user.errors[:password].include?(missing_password)
|
86
|
+
assert user.errors[:password].include?(short_password)
|
87
|
+
|
88
|
+
#Valid user
|
89
|
+
user = Sinatra::SimpleAuthentication::Controllers::Session.model_class.new
|
90
|
+
user.email = "test@mail.com"
|
91
|
+
user.password = "PASSWORD"
|
92
|
+
assert user.save
|
93
|
+
|
94
|
+
#user_class duplicated email
|
95
|
+
user = Sinatra::SimpleAuthentication::Controllers::Session.model_class.new
|
96
|
+
user.email = "test@mail.com"
|
97
|
+
user.password = "PASSWORD"
|
98
|
+
|
99
|
+
assert !user.save
|
100
|
+
assert user.errors[:email].include?(taken_email)
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'sinatra/base'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rack/test'
|
5
|
+
require 'dm-core'
|
6
|
+
require 'sinatra/simple-authentication'
|
7
|
+
require 'nokogiri'
|
8
|
+
|
9
|
+
module Sinatra
|
10
|
+
class Base
|
11
|
+
set :environment, :test
|
12
|
+
DataMapper::Logger.new($stdout, :debug)
|
13
|
+
DataMapper.setup(:default, "sqlite://#{Dir.pwd}/test.db")
|
14
|
+
register Sinatra::SimpleAuthentication
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class TcDataMapper < Test::Unit::TestCase
|
19
|
+
include Rack::Test::Methods
|
20
|
+
|
21
|
+
def app
|
22
|
+
Sinatra::Application
|
23
|
+
end
|
24
|
+
|
25
|
+
def teardown
|
26
|
+
Sinatra::SimpleAuthentication::Controllers::Session.model_class.all.destroy
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_signup_page
|
30
|
+
get '/signup'
|
31
|
+
assert last_response.ok?
|
32
|
+
|
33
|
+
html = Nokogiri::HTML(last_response.body)
|
34
|
+
assert html.css('[name="email"]')
|
35
|
+
assert html.css('[name="password"]')
|
36
|
+
assert html.css('[name="password_confirmation"]')
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_login_page
|
40
|
+
get '/login'
|
41
|
+
assert last_response.ok?
|
42
|
+
|
43
|
+
html = Nokogiri::HTML(last_response.body)
|
44
|
+
assert html.css('[name="email"]')
|
45
|
+
assert html.css('[name="password"]')
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_user_validations
|
49
|
+
taken_email = "Email has already been taken."
|
50
|
+
missing_email = "Email can't be blank."
|
51
|
+
invalid_email = "Invalid email format."
|
52
|
+
missing_password = "Password can't be blank."
|
53
|
+
short_password = "Password is too short, must be between 4 and 16 characters long."
|
54
|
+
long_password = "Password is too long, must be between 4 and 16 characters long."
|
55
|
+
|
56
|
+
#Empty user
|
57
|
+
user = Sinatra::SimpleAuthentication::Controllers::Session.model_class.new
|
58
|
+
|
59
|
+
assert !user.save
|
60
|
+
assert user.errors[:email].include?(missing_email)
|
61
|
+
assert user.errors[:password].include?(missing_password)
|
62
|
+
assert user.errors[:password].include?(short_password)
|
63
|
+
|
64
|
+
#Short password
|
65
|
+
user = Sinatra::SimpleAuthentication::Controllers::Session.model_class.new
|
66
|
+
user.password = "X" * 3
|
67
|
+
|
68
|
+
assert !user.save
|
69
|
+
assert user.errors[:email].include?(missing_email)
|
70
|
+
assert user.errors[:password].include?(short_password)
|
71
|
+
|
72
|
+
#Long password
|
73
|
+
user = Sinatra::SimpleAuthentication::Controllers::Session.model_class.new
|
74
|
+
user.password = "X" * 17
|
75
|
+
|
76
|
+
assert !user.save
|
77
|
+
assert user.errors[:email].include?(missing_email)
|
78
|
+
assert user.errors[:password].include?(long_password)
|
79
|
+
|
80
|
+
#Wrong format email
|
81
|
+
user = Sinatra::SimpleAuthentication::Controllers::Session.model_class.new
|
82
|
+
user.email = "InvaidEmailFormat"
|
83
|
+
|
84
|
+
assert !user.save
|
85
|
+
assert user.errors[:email].include?(invalid_email)
|
86
|
+
assert user.errors[:password].include?(missing_password)
|
87
|
+
assert user.errors[:password].include?(short_password)
|
88
|
+
|
89
|
+
#Valid user
|
90
|
+
user = Sinatra::SimpleAuthentication::Controllers::Session.model_class.new
|
91
|
+
user.email = "test@mail.com"
|
92
|
+
user.password = "PASSWORD"
|
93
|
+
user.password_confirmation = "PASSWORD"
|
94
|
+
assert user.save
|
95
|
+
|
96
|
+
#user_class duplicated email
|
97
|
+
user = Sinatra::SimpleAuthentication::Controllers::Session.model_class.new
|
98
|
+
user.email = "test@mail.com"
|
99
|
+
user.password = "PASSWORD"
|
100
|
+
user.password_confirmation = "PASSWORD"
|
101
|
+
|
102
|
+
assert !user.save
|
103
|
+
assert user.errors[:email].include?(taken_email)
|
104
|
+
end
|
105
|
+
end
|
metadata
ADDED
@@ -0,0 +1,221 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sinatra-simple-authentication
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Pablo Monfort
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-28 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: haml
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: sinatra
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: dm-core
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: dm-validations
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: dm-migrations
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: dm-sqlite-adapter
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: activerecord
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 3.2.3
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 3.2.3
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: sqlite3
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: nokogiri
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: rack-test
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
description: Basic authentication gem with support for Datamapper and ActiveRecord.
|
175
|
+
email:
|
176
|
+
- pmonfort@gmail.com
|
177
|
+
executables: []
|
178
|
+
extensions: []
|
179
|
+
extra_rdoc_files: []
|
180
|
+
files:
|
181
|
+
- lib/sinatra/simple_authentication/models/datamapper/user.rb
|
182
|
+
- lib/sinatra/simple_authentication/models/datamapper/adapter.rb
|
183
|
+
- lib/sinatra/simple_authentication/models/active_record/user.rb
|
184
|
+
- lib/sinatra/simple_authentication/models/active_record/adapter.rb
|
185
|
+
- lib/sinatra/simple_authentication/models/common/instance_methods.rb
|
186
|
+
- lib/sinatra/simple_authentication/views/login.haml
|
187
|
+
- lib/sinatra/simple_authentication/views/signup.haml
|
188
|
+
- lib/sinatra/simple_authentication/views/_form.haml
|
189
|
+
- lib/sinatra/simple_authentication/controllers/defaults.rb
|
190
|
+
- lib/sinatra/simple_authentication/controllers/helpers.rb
|
191
|
+
- lib/sinatra/simple_authentication/controllers/session.rb
|
192
|
+
- lib/sinatra/simple-authentication.rb
|
193
|
+
- test/tc_active_record.rb
|
194
|
+
- test/tc_datamapper.rb
|
195
|
+
homepage: https://github.com/pmonfort/sinatra-simple-authentication
|
196
|
+
licenses: []
|
197
|
+
post_install_message:
|
198
|
+
rdoc_options: []
|
199
|
+
require_paths:
|
200
|
+
- lib
|
201
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
202
|
+
none: false
|
203
|
+
requirements:
|
204
|
+
- - ! '>='
|
205
|
+
- !ruby/object:Gem::Version
|
206
|
+
version: '0'
|
207
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
208
|
+
none: false
|
209
|
+
requirements:
|
210
|
+
- - ! '>='
|
211
|
+
- !ruby/object:Gem::Version
|
212
|
+
version: '0'
|
213
|
+
requirements: []
|
214
|
+
rubyforge_project:
|
215
|
+
rubygems_version: 1.8.24
|
216
|
+
signing_key:
|
217
|
+
specification_version: 3
|
218
|
+
summary: Simple authentication plugin for sinatra.
|
219
|
+
test_files:
|
220
|
+
- test/tc_active_record.rb
|
221
|
+
- test/tc_datamapper.rb
|