sinatra-authentication-ottoman 0.0.2
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.
- checksums.yaml +15 -0
- data/lib/sinatra/authentication.rb +26 -0
- data/lib/sinatra/authentication/cookies.rb +45 -0
- data/lib/sinatra/authentication/helpers.rb +43 -0
- data/lib/sinatra/authentication/identification.rb +23 -0
- data/lib/sinatra/authentication/login_field.rb +17 -0
- data/lib/sinatra/authentication/password.rb +54 -0
- data/lib/sinatra/authentication/user.rb +20 -0
- data/lib/sinatra/authentication/validations.rb +38 -0
- metadata +109 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
!binary "U0hBMQ==":
|
|
3
|
+
metadata.gz: !binary |-
|
|
4
|
+
MTQ2N2FjNDlmNjRiM2FiMTBkNTcwOGNlYWJhOGZjMmJkOTNkYzFmZA==
|
|
5
|
+
data.tar.gz: !binary |-
|
|
6
|
+
MDBkNjhmNjUzYWY1M2NmODdlZmQ2YmE3YmRmNTFlMjhhNzNmYzAzOQ==
|
|
7
|
+
SHA512:
|
|
8
|
+
metadata.gz: !binary |-
|
|
9
|
+
MGViNGZiOTc1YzJmYjQ3M2FjNDg0NDAxZWE4MzUzY2Y5Mjg0ZjA4ZDM2MDI0
|
|
10
|
+
YWY3YzI5MGQxMzI4MjAzNjg2M2UyNGJlNTAxZmJhNTJmMmVmNDk2YWJkNDU1
|
|
11
|
+
NGRjMjZmNThhOWRhY2FkNmMxNjliNTE3OGQ4OWNhYzdjMThmNjM=
|
|
12
|
+
data.tar.gz: !binary |-
|
|
13
|
+
MTAxZmFkMDk5MjYxMGI1MzMxMDhhOWUwNDlhY2JlYWI4Mjg2ZTJhNjcwZGQw
|
|
14
|
+
YTM0ZTlhMWQzNmJjYzZmNWRjMWZjODczMzQ0MTg2M2EzNzFmYTRjZGNiY2M3
|
|
15
|
+
MGYwNWZhZmQwMjFiY2U5NTI0ZGVkMDRjYTNkMjNmZDI5OGZmNzA=
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'sinatra/base'
|
|
2
|
+
|
|
3
|
+
# NOTE these will have to change when gemified
|
|
4
|
+
require_relative 'authentication/helpers'
|
|
5
|
+
require_relative 'authentication/validations'
|
|
6
|
+
require_relative 'authentication/password'
|
|
7
|
+
require_relative 'authentication/cookies'
|
|
8
|
+
require_relative 'authentication/identification'
|
|
9
|
+
require_relative 'authentication/login_field'
|
|
10
|
+
require_relative 'authentication/user'
|
|
11
|
+
|
|
12
|
+
module Sinatra
|
|
13
|
+
module Authentication
|
|
14
|
+
VERSION = "0.0.1"
|
|
15
|
+
|
|
16
|
+
def require_auth(path_prefix)
|
|
17
|
+
before do
|
|
18
|
+
if request.fullpath =~ /^#{path_prefix}/
|
|
19
|
+
require_auth
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
register Authentication
|
|
26
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'digest/sha2'
|
|
2
|
+
|
|
3
|
+
module Sinatra
|
|
4
|
+
module Authentication
|
|
5
|
+
module Cookies
|
|
6
|
+
module Hashing
|
|
7
|
+
extend self
|
|
8
|
+
|
|
9
|
+
def encrypt(user_id, ip, key, salt = self.generate_salt)
|
|
10
|
+
hash = serialize(hash(user_id, ip, key, salt), salt)
|
|
11
|
+
{ :hash => hash, :salt => salt }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def decrypt(crypted, key)
|
|
15
|
+
Encryptor.decrypt(crypted, :key => key)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def check?(user_id, ip, key, crypted)
|
|
19
|
+
hash, salt = unserialize(crypted)
|
|
20
|
+
self.hash(user_id, ip, key, salt) == hash
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
protected
|
|
24
|
+
def generate_salt
|
|
25
|
+
salt = ""
|
|
26
|
+
64.times { salt << (i = Kernel.rand(62); i += ((i < 10) ? 48 : ((i < 36) ? 55 : 61))).chr }
|
|
27
|
+
salt
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# This method can be customized
|
|
31
|
+
def hash(user_id, ip, key, salt)
|
|
32
|
+
Digest::SHA512.hexdigest("#{ user_id }:#{ ip }:#{ key }:#{ salt }")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def serialize(hash, salt)
|
|
36
|
+
hash + salt
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def unserialize(serialized)
|
|
40
|
+
return serialized[0..127], serialized[128..-1]
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Sinatra
|
|
2
|
+
module Authentication
|
|
3
|
+
module Helpers
|
|
4
|
+
def require_auth cookies, required_roles = []
|
|
5
|
+
__USER__.user_auth(cookies, required_roles)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def current_user(finder = lambda { |id| __USER__[id] })
|
|
9
|
+
# Replace this with OttomanORM shit
|
|
10
|
+
# NOTE: not keeping session data
|
|
11
|
+
# @current_user ||= finder.call(session[:user]) if session[:user]
|
|
12
|
+
nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# def logged_in?
|
|
16
|
+
# !!curent_user
|
|
17
|
+
# end
|
|
18
|
+
|
|
19
|
+
def ensure_current_user(user)
|
|
20
|
+
halt 404 unless user == current_user
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def logout!
|
|
24
|
+
# NOTE: not keeping session data
|
|
25
|
+
# session.delete(:user)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def authenticate(opts)
|
|
29
|
+
if user = __USER__.authenticate(opts[:email], opts[:password])
|
|
30
|
+
user.id
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def __USER__
|
|
35
|
+
settings.login_user_class
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def should_return_to?(path, ignored = settings.ignored_by_return_to)
|
|
39
|
+
!(path =~ ignored)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Sinatra
|
|
2
|
+
module Authentication
|
|
3
|
+
module Identification
|
|
4
|
+
def authenticate(login, password)
|
|
5
|
+
if user = find_by_login(login)
|
|
6
|
+
if Password::Hashing.check?(password, user.password)
|
|
7
|
+
user
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# NOTE: This is overridden in Ottoman.User
|
|
13
|
+
def find_by_login(login)
|
|
14
|
+
find(__LOGIN_FIELD__ => login).first
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
protected
|
|
18
|
+
def __LOGIN_FIELD__
|
|
19
|
+
LoginField.attr_name
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Sinatra
|
|
2
|
+
module Authentication
|
|
3
|
+
module LoginField
|
|
4
|
+
def self.attr_name(attr_name = nil)
|
|
5
|
+
@attr_name = attr_name.to_sym if attr_name
|
|
6
|
+
@attr_name
|
|
7
|
+
end
|
|
8
|
+
attr_name :email
|
|
9
|
+
|
|
10
|
+
def self.included(user)
|
|
11
|
+
# NOTE these are Ohm specific, add some Ottoman-ORM shit if needed
|
|
12
|
+
# user.attribute LoginField.attr_name
|
|
13
|
+
# user.index LoginField.attr_name
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'digest/sha2'
|
|
2
|
+
|
|
3
|
+
module Sinatra
|
|
4
|
+
module Authentication
|
|
5
|
+
module Password
|
|
6
|
+
def self.included(model)
|
|
7
|
+
# model.attribute :crypted_password
|
|
8
|
+
# model.send :attr_accessor, :password, :password_confirmation
|
|
9
|
+
end
|
|
10
|
+
protected
|
|
11
|
+
def write
|
|
12
|
+
if !password.to_s.empty?
|
|
13
|
+
# NOTE: This is Ohm specific
|
|
14
|
+
# write_local :crypted_password, Hashing.encrypt(password)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
super
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
module Hashing
|
|
21
|
+
extend self
|
|
22
|
+
|
|
23
|
+
def encrypt(password, salt = self.generate_salt)
|
|
24
|
+
serialize(hash(password, salt), salt)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def check?(password, crypted)
|
|
28
|
+
hash, salt = unserialize(crypted)
|
|
29
|
+
self.hash(password, salt) == hash
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
protected
|
|
33
|
+
def generate_salt
|
|
34
|
+
salt = ""
|
|
35
|
+
64.times { salt << (i = Kernel.rand(62); i += ((i < 10) ? 48 : ((i < 36) ? 55 : 61))).chr }
|
|
36
|
+
salt
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# This method can be customized
|
|
40
|
+
def hash(password, salt)
|
|
41
|
+
Digest::SHA512.hexdigest("#{ password }:#{ salt }")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def serialize(hash, salt)
|
|
45
|
+
hash + salt
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def unserialize(serialized)
|
|
49
|
+
return serialized[0..127], serialized[128..-1]
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Sinatra
|
|
2
|
+
module Authentication
|
|
3
|
+
module User
|
|
4
|
+
# module ClassMethods
|
|
5
|
+
# def require_auth required_roles=[]
|
|
6
|
+
# user_auth required_roles
|
|
7
|
+
# end
|
|
8
|
+
# end
|
|
9
|
+
|
|
10
|
+
def self.included user
|
|
11
|
+
user.send :include, LoginField
|
|
12
|
+
user.send :include, Password
|
|
13
|
+
user.send :include, Validations
|
|
14
|
+
|
|
15
|
+
user.extend Identification
|
|
16
|
+
# user.extend ClassMethods
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Sinatra
|
|
2
|
+
module Authentication
|
|
3
|
+
module Validations
|
|
4
|
+
EMAIL_FORMAT = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
|
|
5
|
+
|
|
6
|
+
def validate
|
|
7
|
+
login_field = Sinatra::Authentication::LoginField.attr_name
|
|
8
|
+
|
|
9
|
+
if login_field == :email
|
|
10
|
+
assert_login_using_email :email
|
|
11
|
+
else
|
|
12
|
+
assert_present(login_field) and assert_unique(login_field)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
assert_password :password
|
|
16
|
+
|
|
17
|
+
super
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
protected
|
|
21
|
+
def assert_login_using_email(attribute, error = [att, :not_email])
|
|
22
|
+
if assert_present attribute
|
|
23
|
+
if assert_format attribute, EMAIL_FORMAT, error
|
|
24
|
+
assert_unique attribute
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def assert_password(attribute, error = [attribute, :not_present])
|
|
30
|
+
confirmation_attribute = :"#{ attribute }_confirmation"
|
|
31
|
+
|
|
32
|
+
if new? && assert_present(attribute) || !send(attribute).to_s.empty?
|
|
33
|
+
assert send(attribute) == send(confirmation_attribute), [attribute, :not_confirmed]
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: sinatra-authentication-ottoman
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Craig McCown
|
|
8
|
+
- Spencer Applegate
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2013-11-25 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: sinatra
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
requirements:
|
|
18
|
+
- - ! '>='
|
|
19
|
+
- !ruby/object:Gem::Version
|
|
20
|
+
version: '0'
|
|
21
|
+
type: :runtime
|
|
22
|
+
prerelease: false
|
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
24
|
+
requirements:
|
|
25
|
+
- - ! '>='
|
|
26
|
+
- !ruby/object:Gem::Version
|
|
27
|
+
version: '0'
|
|
28
|
+
- !ruby/object:Gem::Dependency
|
|
29
|
+
name: bundler
|
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
|
31
|
+
requirements:
|
|
32
|
+
- - '='
|
|
33
|
+
- !ruby/object:Gem::Version
|
|
34
|
+
version: 1.3.5
|
|
35
|
+
type: :development
|
|
36
|
+
prerelease: false
|
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
38
|
+
requirements:
|
|
39
|
+
- - '='
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: 1.3.5
|
|
42
|
+
- !ruby/object:Gem::Dependency
|
|
43
|
+
name: rake
|
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - ! '>='
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '0'
|
|
49
|
+
type: :development
|
|
50
|
+
prerelease: false
|
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
52
|
+
requirements:
|
|
53
|
+
- - ! '>='
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: '0'
|
|
56
|
+
- !ruby/object:Gem::Dependency
|
|
57
|
+
name: rspec
|
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
|
59
|
+
requirements:
|
|
60
|
+
- - '='
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: 2.14.5
|
|
63
|
+
type: :development
|
|
64
|
+
prerelease: false
|
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
66
|
+
requirements:
|
|
67
|
+
- - '='
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: 2.14.5
|
|
70
|
+
description: A lightweight authentication extension for Sinatra with PostgreSQL --
|
|
71
|
+
longer description
|
|
72
|
+
email: spencer@thotpod.com
|
|
73
|
+
executables: []
|
|
74
|
+
extensions: []
|
|
75
|
+
extra_rdoc_files: []
|
|
76
|
+
files:
|
|
77
|
+
- lib/sinatra/authentication/cookies.rb
|
|
78
|
+
- lib/sinatra/authentication/helpers.rb
|
|
79
|
+
- lib/sinatra/authentication/identification.rb
|
|
80
|
+
- lib/sinatra/authentication/login_field.rb
|
|
81
|
+
- lib/sinatra/authentication/password.rb
|
|
82
|
+
- lib/sinatra/authentication/user.rb
|
|
83
|
+
- lib/sinatra/authentication/validations.rb
|
|
84
|
+
- lib/sinatra/authentication.rb
|
|
85
|
+
homepage: https://github.com/Thotpod/sinatra-authentication
|
|
86
|
+
licenses:
|
|
87
|
+
- MIT
|
|
88
|
+
metadata: {}
|
|
89
|
+
post_install_message:
|
|
90
|
+
rdoc_options: []
|
|
91
|
+
require_paths:
|
|
92
|
+
- lib
|
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
94
|
+
requirements:
|
|
95
|
+
- - ! '>='
|
|
96
|
+
- !ruby/object:Gem::Version
|
|
97
|
+
version: '0'
|
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - ! '>='
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '0'
|
|
103
|
+
requirements: []
|
|
104
|
+
rubyforge_project:
|
|
105
|
+
rubygems_version: 2.1.5
|
|
106
|
+
signing_key:
|
|
107
|
+
specification_version: 4
|
|
108
|
+
summary: A lightweight authentication extension for Sinatra with PostgreSQL
|
|
109
|
+
test_files: []
|