entrance 0.3.0 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
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