challah 0.3.5 → 0.4.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/CHANGELOG.md +7 -0
- data/README.md +3 -2
- data/lib/challah/authable/user.rb +1 -1
- data/lib/challah/controller.rb +1 -1
- data/lib/challah/session.rb +23 -8
- data/lib/challah/techniques/api_key_technique.rb +5 -1
- data/lib/challah/version.rb +1 -1
- data/lib/challah.rb +1 -0
- data/test/cookie_store_test.rb +5 -0
- data/test/helper.rb +2 -1
- data/test/restrictions_controller_test.rb +62 -0
- data/test/session_test.rb +7 -1
- metadata +10 -10
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## Challah 0.4.0 (Unreleased)
|
2
|
+
|
3
|
+
* Enabled api key access. Passing ?key=xxxx into any URL will authenticate a user for a single page load. This option is turned off by default in new apps and can be enabled using `Challah.options[:api_key_enabled]`.
|
4
|
+
* Updated tests for API key access
|
5
|
+
* Authenticate users on page load
|
6
|
+
* Changed default api key length to 50 instead of 25
|
7
|
+
|
1
8
|
## Challah 0.3.5
|
2
9
|
|
3
10
|
* Now using [Highline](https://github.com/JEG2/highline) for rake tasks instead of sloppy custom methods.
|
data/README.md
CHANGED
@@ -77,9 +77,10 @@ Roles should only be used within your app to consolidate various permissions int
|
|
77
77
|
|
78
78
|
The default Challah installation creates two roles by default: 'Administrator' and 'Default'. Administrators have all permissions, now and in the future. Default users have no permissions other than being able to log in.
|
79
79
|
|
80
|
-
|
80
|
+
Once you've added a few other permissions, you can easily add them to a role. In this case, the `moderator` permission key is added to the default role:
|
81
81
|
|
82
|
-
role
|
82
|
+
role = Role[:default]
|
83
|
+
role.permission_keys = %w( moderator )
|
83
84
|
role.save
|
84
85
|
|
85
86
|
## Restricted access
|
@@ -211,7 +211,7 @@ module Challah
|
|
211
211
|
end
|
212
212
|
|
213
213
|
self.persistence_token = ::Challah::Random.token(125) if self.persistence_token.to_s.blank?
|
214
|
-
self.api_key = ::Challah::Random.token(
|
214
|
+
self.api_key = ::Challah::Random.token(50) if self.api_key.to_s.blank?
|
215
215
|
end
|
216
216
|
|
217
217
|
# Saves any updated permission keys to the database for this user.
|
data/lib/challah/controller.rb
CHANGED
@@ -124,7 +124,7 @@ module Challah
|
|
124
124
|
#
|
125
125
|
# @return [Session] The current browser session.
|
126
126
|
def current_user_session
|
127
|
-
@current_user_session ||= Challah::Session.find(request)
|
127
|
+
@current_user_session ||= Challah::Session.find(request, params)
|
128
128
|
end
|
129
129
|
|
130
130
|
# Checks the current user to see if they have the given permission key. If there is
|
data/lib/challah/session.rb
CHANGED
@@ -3,8 +3,8 @@ module Challah
|
|
3
3
|
extend ActiveModel::Naming
|
4
4
|
include ActiveModel::Conversion
|
5
5
|
|
6
|
-
attr_accessor :return_to, :ip, :user, :store
|
7
|
-
attr_reader :params, :request
|
6
|
+
attr_accessor :return_to, :ip, :user, :store, :persist
|
7
|
+
attr_reader :params, :request
|
8
8
|
|
9
9
|
def initialize(request = nil, params = {})
|
10
10
|
@request = request
|
@@ -24,6 +24,17 @@ module Challah
|
|
24
24
|
@user = nil
|
25
25
|
end
|
26
26
|
|
27
|
+
def find
|
28
|
+
self.read
|
29
|
+
|
30
|
+
# If no session was found, try and authenticate
|
31
|
+
unless valid?
|
32
|
+
self.authenticate!
|
33
|
+
end
|
34
|
+
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
27
38
|
def inspect
|
28
39
|
"#<Session:0x#{object_id.to_s(16)} valid=#{valid?} store=#{self.store.inspect} user=#{user_id || 'nil'}>"
|
29
40
|
end
|
@@ -49,11 +60,14 @@ module Challah
|
|
49
60
|
end
|
50
61
|
|
51
62
|
def save
|
52
|
-
return false unless
|
63
|
+
return false unless valid?
|
53
64
|
|
54
|
-
if self.user
|
65
|
+
if self.user and persist?
|
55
66
|
self.store.save(self.user.persistence_token, user_id)
|
67
|
+
return true
|
56
68
|
end
|
69
|
+
|
70
|
+
false
|
57
71
|
end
|
58
72
|
|
59
73
|
# Id of the current user.
|
@@ -95,6 +109,7 @@ module Challah
|
|
95
109
|
|
96
110
|
if user_record and user_record.active?
|
97
111
|
session.user = user_record
|
112
|
+
session.persist = true
|
98
113
|
end
|
99
114
|
|
100
115
|
session
|
@@ -117,7 +132,7 @@ module Challah
|
|
117
132
|
# Load any existing session from the session store
|
118
133
|
def find(*args)
|
119
134
|
session = Session.new(*args)
|
120
|
-
session.
|
135
|
+
session.find
|
121
136
|
session
|
122
137
|
end
|
123
138
|
end
|
@@ -125,13 +140,13 @@ module Challah
|
|
125
140
|
protected
|
126
141
|
# Try and authenticate against the various auth techniques. If one
|
127
142
|
# technique works, then just exist and make the session active.
|
128
|
-
def authenticate!
|
129
|
-
Challah.techniques.values.each do |klass|
|
143
|
+
def authenticate!
|
144
|
+
Challah.techniques.values.each do |klass|
|
130
145
|
technique = klass.new(self)
|
131
146
|
@user = technique.authenticate
|
132
147
|
|
133
148
|
if @user
|
134
|
-
@persist = technique.persist?
|
149
|
+
@persist = technique.respond_to?(:persist?) ? technique.persist? : false
|
135
150
|
break
|
136
151
|
end
|
137
152
|
end
|
@@ -1,10 +1,14 @@
|
|
1
1
|
module Challah
|
2
2
|
class ApiKeyTechnique
|
3
3
|
def initialize(session)
|
4
|
-
@key = session.
|
4
|
+
@key = session.key? ? session.key : nil
|
5
5
|
end
|
6
6
|
|
7
7
|
def authenticate
|
8
|
+
# Api key functionality is only enabled with the :api_key_enabled option. This is turned
|
9
|
+
# off by default and must be manually enabled for security reasons.
|
10
|
+
return nil unless Challah.options[:api_key_enabled]
|
11
|
+
|
8
12
|
unless @key.to_s.blank?
|
9
13
|
user = ::User.find_by_api_key(@key)
|
10
14
|
|
data/lib/challah/version.rb
CHANGED
data/lib/challah.rb
CHANGED
@@ -53,6 +53,7 @@ module Challah
|
|
53
53
|
# @option options [Class] :storage_class (CookieStore) The class to use for persistence of sessions.
|
54
54
|
def options
|
55
55
|
@options ||= {
|
56
|
+
:api_key_enabled => false,
|
56
57
|
:cookie_prefix => 'challah',
|
57
58
|
:access_denied_view => 'sessions/access_denied',
|
58
59
|
:storage_class => CookieStore,
|
data/test/cookie_store_test.rb
CHANGED
@@ -14,6 +14,7 @@ class CookieStoreTest < ActiveSupport::TestCase
|
|
14
14
|
|
15
15
|
session = Session.new(@request)
|
16
16
|
session.store = CookieStore.new(session)
|
17
|
+
session.persist = true
|
17
18
|
session.user = @user
|
18
19
|
session.save
|
19
20
|
|
@@ -28,6 +29,7 @@ class CookieStoreTest < ActiveSupport::TestCase
|
|
28
29
|
should "be able to inspect the store" do
|
29
30
|
session = Session.new(@request)
|
30
31
|
session.store = CookieStore.new(session)
|
32
|
+
session.persist = true
|
31
33
|
session.user = @user
|
32
34
|
session.save
|
33
35
|
|
@@ -39,6 +41,7 @@ class CookieStoreTest < ActiveSupport::TestCase
|
|
39
41
|
|
40
42
|
session = Session.new(@request)
|
41
43
|
session.store = CookieStore.new(session)
|
44
|
+
session.persist = true
|
42
45
|
session.user = @user
|
43
46
|
session.save
|
44
47
|
|
@@ -54,6 +57,7 @@ class CookieStoreTest < ActiveSupport::TestCase
|
|
54
57
|
session.store.stubs(:session_cookie).returns(session_cookie_val)
|
55
58
|
|
56
59
|
session2 = Session.new(@request)
|
60
|
+
session2.persist = true
|
57
61
|
session2.store = session.store
|
58
62
|
session2.read
|
59
63
|
|
@@ -75,6 +79,7 @@ class CookieStoreTest < ActiveSupport::TestCase
|
|
75
79
|
session = Session.new(@request)
|
76
80
|
session.store = CookieStore.new(session)
|
77
81
|
session.user = @user
|
82
|
+
session.persist = true
|
78
83
|
|
79
84
|
session.save
|
80
85
|
|
data/test/helper.rb
CHANGED
@@ -41,11 +41,12 @@ end
|
|
41
41
|
class MockController
|
42
42
|
include Challah::Controller
|
43
43
|
|
44
|
-
attr_accessor :request, :session
|
44
|
+
attr_accessor :request, :session, :params
|
45
45
|
|
46
46
|
def initialize()
|
47
47
|
@request = MockRequest.new
|
48
48
|
@session ||= {}
|
49
|
+
@params ||= {}
|
49
50
|
end
|
50
51
|
|
51
52
|
def redirect_to(*args)
|
@@ -86,5 +86,67 @@ class RestrictionsControllerTest < ActionController::TestCase
|
|
86
86
|
assert_response :success
|
87
87
|
end
|
88
88
|
end
|
89
|
+
|
90
|
+
context "With an api key" do
|
91
|
+
setup do
|
92
|
+
@user = Factory(:user)
|
93
|
+
end
|
94
|
+
|
95
|
+
context "and api_key functionality enabled" do
|
96
|
+
setup do
|
97
|
+
Challah.options[:api_key_enabled] = true
|
98
|
+
end
|
99
|
+
|
100
|
+
should "get to the index page" do
|
101
|
+
get :index, :key => @user.api_key
|
102
|
+
assert_response :success
|
103
|
+
assert_equal @user, assigns(:current_user)
|
104
|
+
end
|
105
|
+
|
106
|
+
should "get to the edit page" do
|
107
|
+
get :edit, :key => @user.api_key
|
108
|
+
assert_response :success
|
109
|
+
end
|
110
|
+
|
111
|
+
should "get to the show page" do
|
112
|
+
get :show, :key => @user.api_key
|
113
|
+
assert_response :success
|
114
|
+
end
|
115
|
+
|
116
|
+
should "not get to the new page" do
|
117
|
+
get :new, :key => @user.api_key
|
118
|
+
|
119
|
+
assert_template 'sessions/access_denied'
|
120
|
+
assert_response :unauthorized
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "and api_key functionality disabled" do
|
125
|
+
setup do
|
126
|
+
Challah.options[:api_key_enabled] = false
|
127
|
+
end
|
128
|
+
|
129
|
+
should "get to the index page" do
|
130
|
+
get :index, :key => @user.api_key
|
131
|
+
assert_response :success
|
132
|
+
assert_equal nil, assigns(:current_user)
|
133
|
+
end
|
134
|
+
|
135
|
+
should "get to the edit page" do
|
136
|
+
get :edit, :key => @user.api_key
|
137
|
+
assert_redirected_to '/login'
|
138
|
+
end
|
139
|
+
|
140
|
+
should "get to the show page" do
|
141
|
+
get :show, :key => @user.api_key
|
142
|
+
assert_redirected_to '/login'
|
143
|
+
end
|
144
|
+
|
145
|
+
should "not get to the new page" do
|
146
|
+
get :new, :key => @user.api_key
|
147
|
+
assert_redirected_to '/login'
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
89
151
|
end
|
90
152
|
end
|
data/test/session_test.rb
CHANGED
@@ -113,27 +113,33 @@ class SessionTest < ActiveSupport::TestCase
|
|
113
113
|
assert_equal user, session.user
|
114
114
|
assert_equal user.id, session.user_id
|
115
115
|
assert_equal true, session.persist?
|
116
|
+
assert_equal true, session.save
|
116
117
|
|
117
118
|
User.unstub(:find_for_session)
|
118
119
|
end
|
119
120
|
|
120
121
|
should "validate with an api key" do
|
122
|
+
Challah.options[:api_key_enabled] = true
|
123
|
+
|
121
124
|
user = Factory(:user, :api_key => '123456abcdefg')
|
122
125
|
|
123
126
|
User.stubs(:find_for_session).returns(user)
|
124
127
|
|
125
128
|
session = Session.new
|
126
129
|
session.ip = '127.0.0.1'
|
127
|
-
session.
|
130
|
+
session.key = '123456abcdefg'
|
128
131
|
|
129
132
|
assert_equal true, session.valid?
|
130
133
|
assert_equal user, session.user
|
131
134
|
assert_equal user.id, session.user_id
|
132
135
|
assert_equal false, session.persist?
|
136
|
+
assert_equal false, session.save
|
133
137
|
|
134
138
|
user.expects(:successful_authentication!).with('127.0.0.1').once
|
135
139
|
|
136
140
|
User.unstub(:find_for_session)
|
141
|
+
|
142
|
+
Challah.options[:api_key_enabled] = false
|
137
143
|
end
|
138
144
|
|
139
145
|
should "reject if password is incorrect" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: challah
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02-
|
12
|
+
date: 2012-02-08 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: highline
|
16
|
-
requirement: &
|
16
|
+
requirement: &70244762031040 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70244762031040
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rails
|
27
|
-
requirement: &
|
27
|
+
requirement: &70244762124220 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '3.1'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70244762124220
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rake
|
38
|
-
requirement: &
|
38
|
+
requirement: &70244762123720 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 0.9.2
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70244762123720
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: bcrypt-ruby
|
49
|
-
requirement: &
|
49
|
+
requirement: &70244762123260 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70244762123260
|
58
58
|
description: A simple ruby gem for authentication, users, roles and permissions.
|
59
59
|
email:
|
60
60
|
- john@johntornow.com
|