entrance 0.3.0 → 0.3.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.
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ *~
1
2
  .DS_Store
2
3
  pkg
3
4
  Gemfile.lock
@@ -0,0 +1,179 @@
1
+ require 'entrance'
2
+ require 'omniauth'
3
+
4
+ =begin
5
+
6
+ require 'sinatra/base'
7
+ require 'omniauth-twitter'
8
+ require 'entrance/omniauth'
9
+
10
+ class Hello < Sinatra::Base
11
+ register Entrance::OmniAuth
12
+
13
+ set :auth_test, false # only true for testing
14
+ set :auth_providers {
15
+ :twitter => {
16
+ :key => 'foobar'
17
+ }
18
+ }
19
+ end
20
+
21
+ =end
22
+
23
+ module Entrance
24
+
25
+ module OmniAuth
26
+
27
+ class << self
28
+
29
+ def registered(app)
30
+
31
+ ::Entrance.model.class_eval do
32
+
33
+ def via_omniauth?
34
+ send(::Entrance.config.auth_provider_attr).present? \
35
+ && send(::Entrance.config.auth_uid_attr).present?
36
+ end
37
+
38
+ def password_required?
39
+ !via_omniauth? && (password.blank? || @password_changed)
40
+ end
41
+
42
+ end
43
+
44
+ app.include ::Entrance::Controller # provides redirects, etc
45
+
46
+ app.use ::OmniAuth::Builder do
47
+ # this is run after the app has initialized, so it's safe to use it here.
48
+ ::OmniAuth.config.test_mode = true if app.settings.auth_test?
49
+
50
+ app.settings.auth_providers.each do |name, options|
51
+ # puts "Initializing #{name} provider: #{options.inspect}"
52
+ provider(name, options)
53
+ end
54
+ end
55
+
56
+ # make _method=delete work in POST requests:
57
+ app.enable :method_override
58
+
59
+ [:get, :post].each do |action|
60
+
61
+ app.send(action, '/auth/:provider/callback') do
62
+ auth = request.env['omniauth.auth']
63
+ user = ::Entrance::OmniAuth.auth_or_create(auth) or return return_401
64
+
65
+ if ::Entrance::OmniAuth.valid_user?(user)
66
+ login!(user)
67
+ flash[:success] = 'Welcome back!' if respond_to?(:flash)
68
+ redirect_to_stored_or(to('/'))
69
+ else
70
+ redirect_with('/', :error, 'Unable to authenticate. Please try again.')
71
+ end
72
+ end
73
+
74
+ end # get, post
75
+
76
+ end # registered
77
+
78
+ def logger
79
+ @logger ||= Logger.new('./log/omniauth.log')
80
+ end
81
+
82
+ def log(str)
83
+ logger.info(str)
84
+ end
85
+
86
+ def valid_user?(user)
87
+ if user.respond_to?(:active?) and !user.active?
88
+ return false
89
+ end
90
+ user.valid?
91
+ end
92
+
93
+ def can_authenticate_with?(service)
94
+ return true if OmniAuth.config.test_mode and service.to_sym == :default
95
+
96
+ options.auth_providers.keys.map(&:to_sym).include?(service.to_sym)
97
+ end
98
+
99
+ def find_user_with_username(username)
100
+ query = {}
101
+ query[::Entrance.config.username_attr] = username # .to_s.downcase.strip
102
+ ::Entrance.model.where(query).first
103
+ end
104
+
105
+ def find_user_with_provider_and_uid(provider, uid)
106
+ query = {}
107
+ query[::Entrance.config.auth_provider_attr] = provider
108
+ query[::Entrance.config.auth_uid_attr] = uid
109
+ ::Entrance.model.where(query).first
110
+ end
111
+
112
+ def set_auth_credentials(user, provider, uid)
113
+ user[::Entrance.config.auth_provider_attr] = provider
114
+ user[::Entrance.config.auth_uid_attr] = uid
115
+ end
116
+
117
+ def store_auth_credentials(user, provider, uid)
118
+ set_auth_credentials(user, provider, uid)
119
+ user.save && user
120
+ end
121
+
122
+ def create_user(name, email, provider, uid)
123
+ data = {}
124
+ data[::Entrance.config.name_attr] = name
125
+ data[::Entrance.config.username_attr] = email
126
+ user = ::Entrance.model.new(data)
127
+ set_auth_credentials(user, provider, uid)
128
+
129
+ if user.valid?
130
+ return user.save && user
131
+ else
132
+ log "Invalid user: #{user.errors.to_a.join(', ')}"
133
+ end
134
+ end
135
+
136
+ # authorizes or creates a user with the given oauth credentials.
137
+ # does not check if user is banned or not (the /callback route does that)
138
+ def auth_or_create(auth)
139
+ provider, uid = auth['provider'], auth['uid']
140
+ info = auth['info'] || {}
141
+
142
+ log "Authenticating with #{provider}"
143
+
144
+ # if running on production, make sure the provider is actually valid
145
+ unless ::OmniAuth.config.test_mode
146
+ raise "Invalid provider: #{provider}" unless can_authenticate_with?(provider)
147
+ end
148
+
149
+ if u = find_user_with_provider_and_uid(provider, uid)
150
+
151
+ log "Authenticated! Provider: #{provider}, UID: #{uid}"
152
+ return u
153
+
154
+ else # no user with that provider/uid found
155
+ name, email = info['name'], info['email']
156
+
157
+ if email.present? and user = find_user_with_email(email)
158
+
159
+ # if using different provider, it will update it
160
+ log "Found user, but with different credentials."
161
+ return store_auth_credentials(user, provider, uid)
162
+
163
+ else
164
+
165
+ log "Creating new user: '#{name}', email #{email}"
166
+ name = name.is_a?(Array) ? name[0] : name
167
+
168
+ return create_user(name, email, provider, uid)
169
+ end
170
+
171
+ end
172
+
173
+ end # auth_or_create
174
+
175
+ end
176
+
177
+ end
178
+
179
+ end
@@ -1,20 +1,13 @@
1
1
  require 'entrance'
2
2
 
3
- module Sinatra
3
+ module Entrance
4
4
 
5
- module Entrance
5
+ module Sinatra
6
6
 
7
7
  def self.registered(app)
8
8
 
9
9
  app.include ::Entrance::Controller
10
10
 
11
- app.helpers do
12
- def redirect_with(url, type, message)
13
- flash[type] = message if respond_to?(:flash)
14
- redirect(to(url))
15
- end
16
- end
17
-
18
11
  app.get '/login' do
19
12
  if logged_in?
20
13
  redirect(to('/'))
@@ -34,7 +27,7 @@ module Sinatra
34
27
  end
35
28
 
36
29
  app.get '/logout' do
37
- kill_session!
30
+ logout!
38
31
  redirect_with('/login', :notice, 'Logged out! See you soon.')
39
32
  end
40
33
 
@@ -9,13 +9,18 @@ module Entrance
9
9
  access_denied_redirect_to access_denied_message_key
10
10
  reset_password_mailer reset_password_method reset_password_window remember_for
11
11
  cookie_domain cookie_secure cookie_path cookie_httponly
12
+ name_attr auth_provider_attr auth_uid_attr
12
13
  )
13
14
 
14
15
  def initialize
15
16
  @model = 'User'
16
- @cipher = Entrance::Ciphers::BCrypt # or Entrance::Ciphers::SHA1
17
+
18
+ # strategies
19
+ @cipher = Entrance::Ciphers::BCrypt # or Entrance::Ciphers::SHA1
17
20
  @secret = nil
18
21
  @stretches = 10
22
+
23
+ # fields
19
24
  @salt_attr = nil
20
25
  @unique_key = 'id'
21
26
  @username_attr = 'email'
@@ -24,16 +29,27 @@ module Entrance
24
29
  @remember_until_attr = 'remember_token_expires_at'
25
30
  @reset_token_attr = 'reset_token'
26
31
  @reset_until_attr = 'reset_token_expires_at'
32
+
33
+ # access denied
27
34
  @access_denied_redirect_to = '/'
28
35
  @access_denied_message_key = nil # e.g. 'messages.access_denied'
36
+
37
+ # reset password
29
38
  @reset_password_mailer = 'UserMailer'
30
39
  @reset_password_method = 'reset_password_request'
31
40
  @reset_password_window = 60 * 60 # 1.hour
41
+
42
+ # remember me & cookies
32
43
  @remember_for = 60 * 24 * 14 # 2.weeks
33
44
  @cookie_domain = nil
34
45
  @cookie_secure = true
35
46
  @cookie_path = '/'
36
47
  @cookie_httponly = false
48
+
49
+ # for omniauth support
50
+ @name_attr = 'name'
51
+ @auth_provider_attr = 'auth_provider'
52
+ @auth_uid_attr = 'auth_uid'
37
53
  end
38
54
 
39
55
  def validate!
@@ -56,4 +72,4 @@ module Entrance
56
72
 
57
73
  end
58
74
 
59
- end
75
+ end
@@ -1,7 +1,7 @@
1
1
  module Entrance
2
2
 
3
3
  module Controller
4
-
4
+
5
5
  REMEMBER_ME_TOKEN = 'auth_token'.freeze
6
6
 
7
7
  def self.included(base)
@@ -58,8 +58,8 @@ module Entrance
58
58
  Entrance.config.permit!(:remember)
59
59
 
60
60
  if remember_me
61
- current_user.remember_me!
62
- set_remember_cookie
61
+ token = current_user.remember_me!
62
+ set_remember_cookie(token) if token
63
63
  else
64
64
  current_user.forget_me!
65
65
  delete_remember_cookie
@@ -109,13 +109,13 @@ module Entrance
109
109
  common_redirect(request.env['HTTP_REFERER'] || default_path)
110
110
  end
111
111
 
112
- def set_remember_cookie
112
+ def set_remember_cookie(token)
113
113
  values = {
114
114
  :expires => Time.now + Entrance.config.remember_for.to_i,
115
115
  :httponly => Entrance.config.cookie_httponly,
116
116
  :path => Entrance.config.cookie_path,
117
117
  :secure => Entrance.config.cookie_secure,
118
- :value => current_user.send(Entrance.config.remember_token_attr)
118
+ :value => token
119
119
  }
120
120
  values[:domain] = Entrance.config.cookie_domain if Entrance.config.cookie_domain
121
121
 
@@ -153,13 +153,18 @@ module Entrance
153
153
  end
154
154
  end
155
155
 
156
+ def redirect_with(url, type, message)
157
+ flash[type] = message if respond_to?(:flash)
158
+ common_redirect(url)
159
+ end
160
+
156
161
  def set_flash_message
157
162
  return unless respond_to?(:flash)
158
163
 
159
164
  if Entrance.config.access_denied_message_key
160
165
  flash[:notice] = I18n.t(Entrance.config.access_denied_message_key)
161
166
  else
162
- flash[:notice] = 'Access denied.'
167
+ flash[:notice] = 'Please log in first.'
163
168
  end
164
169
  end
165
170
 
@@ -174,4 +179,4 @@ module Entrance
174
179
 
175
180
  end
176
181
 
177
- end
182
+ end
@@ -103,8 +103,10 @@ module Entrance
103
103
  module RememberMethods
104
104
 
105
105
  def remember_me!(until_date = nil)
106
- update_attribute(Entrance.config.remember_token_attr, Entrance.generate_token)
106
+ token = Entrance.generate_token
107
+ update_attribute(Entrance.config.remember_token_attr, token) or return
107
108
  update_remember_token_expiration!(until_date) if Entrance.config.remember_until_attr
109
+ token
108
110
  end
109
111
 
110
112
  def update_remember_token_expiration!(until_date = nil)
@@ -1,7 +1,7 @@
1
1
  module Entrance
2
2
  MAJOR = 0
3
3
  MINOR = 3
4
- PATCH = 0
4
+ PATCH = 2
5
5
 
6
6
  VERSION = [MAJOR, MINOR, PATCH].join('.')
7
7
  end
metadata CHANGED
@@ -1,27 +1,30 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: entrance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.2
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Tomás Pollak
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2015-03-12 00:00:00.000000000 Z
12
+ date: 2015-03-13 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: bcrypt
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
- - - "~>"
19
+ - - ~>
18
20
  - !ruby/object:Gem::Version
19
21
  version: '3.0'
20
22
  type: :runtime
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
- - - "~>"
27
+ - - ~>
25
28
  - !ruby/object:Gem::Version
26
29
  version: '3.0'
27
30
  description: Doesn't fiddle with your controllers and routes.
@@ -31,7 +34,7 @@ executables: []
31
34
  extensions: []
32
35
  extra_rdoc_files: []
33
36
  files:
34
- - ".gitignore"
37
+ - .gitignore
35
38
  - README.md
36
39
  - Rakefile
37
40
  - entrance.gemspec
@@ -109,34 +112,35 @@ files:
109
112
  - examples/sinatra-app/app/views/welcome.erb
110
113
  - examples/sinatra-app/config.ru
111
114
  - lib/entrance.rb
115
+ - lib/entrance/addons/omniauth.rb
116
+ - lib/entrance/addons/sinatra.rb
112
117
  - lib/entrance/ciphers.rb
113
118
  - lib/entrance/config.rb
114
119
  - lib/entrance/controller.rb
115
120
  - lib/entrance/model.rb
116
- - lib/entrance/sinatra.rb
117
121
  - lib/entrance/version.rb
118
122
  homepage: https://github.com/tomas/entrance
119
123
  licenses: []
120
- metadata: {}
121
124
  post_install_message:
122
125
  rdoc_options: []
123
126
  require_paths:
124
127
  - lib
125
128
  required_ruby_version: !ruby/object:Gem::Requirement
129
+ none: false
126
130
  requirements:
127
- - - ">="
131
+ - - ! '>='
128
132
  - !ruby/object:Gem::Version
129
133
  version: '0'
130
134
  required_rubygems_version: !ruby/object:Gem::Requirement
135
+ none: false
131
136
  requirements:
132
- - - ">="
137
+ - - ! '>='
133
138
  - !ruby/object:Gem::Version
134
139
  version: 1.3.6
135
140
  requirements: []
136
141
  rubyforge_project: entrance
137
- rubygems_version: 2.2.0
142
+ rubygems_version: 1.8.23
138
143
  signing_key:
139
- specification_version: 4
144
+ specification_version: 3
140
145
  summary: Lean authentication alternative for Rails and Sinatra.
141
146
  test_files: []
142
- has_rdoc:
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 9db48b6f4e950ecfecf95a8c51d17fd8e29296cc
4
- data.tar.gz: 7cd2766497f3634f0ba201d1360055a11201e80d
5
- SHA512:
6
- metadata.gz: bbde9df5134233c9eee47139dd28643ed09653fd1f4509db82551e5d85b76fa6dc62bcce43e888dc55130f15525322af62920db80b5a378c34effe333b2fb18e
7
- data.tar.gz: 6a2da9b7a78dcb87c790a9d1833f7d8591fb99e5bc604f5a51c02002ec70dc39655b78f436df11c5b62b4b5c54d76c5e14a7d83948cf60270d8d9d365c617487