rack_warden 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.gitignore +2 -0
- data/Gemfile +13 -10
- data/README.md +115 -53
- data/config.ru +1 -0
- data/lib/rack_warden.rb +33 -5
- data/lib/rack_warden/app.rb +73 -58
- data/lib/rack_warden/core_patches.rb +20 -0
- data/lib/rack_warden/env.rb +27 -0
- data/lib/rack_warden/frameworks.rb +34 -36
- data/lib/rack_warden/frameworks/rack.rb +36 -0
- data/lib/rack_warden/frameworks/rails.rb +29 -9
- data/lib/rack_warden/frameworks/sinatra.rb +15 -11
- data/lib/rack_warden/helpers.rb +197 -29
- data/lib/rack_warden/mail.rb +26 -0
- data/lib/rack_warden/models.rb +79 -40
- data/lib/rack_warden/models/user.rb +180 -22
- data/lib/rack_warden/routes.rb +159 -83
- data/lib/rack_warden/sinatra/decompile.rb +127 -0
- data/lib/rack_warden/sinatra/json.rb +131 -0
- data/lib/rack_warden/sinatra/namespace.rb +285 -0
- data/lib/rack_warden/sinatra/respond_with.rb +277 -0
- data/lib/rack_warden/version.rb +1 -1
- data/lib/rack_warden/views/rw_account_widget.html.erb +8 -0
- data/lib/rack_warden/views/rw_activation.email.erb +3 -0
- data/lib/rack_warden/views/rw_admin.html.erb +7 -5
- data/lib/rack_warden/views/rw_dbinfo.html.erb +5 -4
- data/lib/rack_warden/views/rw_error.html.erb +1 -0
- data/lib/rack_warden/views/rw_flash_widget.html.erb +12 -0
- data/lib/rack_warden/views/rw_index.html.erb +1 -1
- data/lib/rack_warden/views/rw_layout.html.erb +13 -19
- data/lib/rack_warden/views/rw_layout_admin.html.erb +6 -6
- data/lib/rack_warden/views/rw_login.html.erb +18 -5
- data/lib/rack_warden/views/rw_new_user.html.erb +22 -6
- data/lib/rack_warden/views/rw_protected.xml.erb +10 -0
- data/lib/rack_warden/views/rw_session.html.erb +34 -0
- data/lib/rack_warden/warden.rb +161 -30
- data/rack_warden.gemspec +16 -13
- metadata +84 -29
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
Yzg2NzVkNGE1Yzc3NWIwYmNhZDkxMGNkMDE3MzZiZGU3MTNkMDQwOQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
M2UzZTNiM2UxOGFhYjBhN2VmNzI4OGM1N2UyMDk1NDBmNWI5MjI1OQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZTk4MmI2YmU5YTg1OTM3MWFkMjc3YjExOTQwYjY5ZTI5N2U4NWI3YmE2ZWU2
|
10
|
+
YjAwMGE1NDBjODU5NGE4OWVmYjIzM2FhYzUyY2VlYTJhYjEyNTk3YTk1M2E5
|
11
|
+
NmJkNDA0NDI0N2JlZmM2ZjcyZTVmY2RiNzM3Zjg1M2RiZTM5NzU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MmYxYWIzOWQ5YWNhZDE1ZTNlYTAwNTYwMzRlZWVhM2QxMTkzNWVlYTcyNGNm
|
14
|
+
ZDNmNDAyNjFlMzBlMTYzNzMwNWFhY2Y2Zjg1MGIxMjQyY2ExNTQ4MmJjMTY3
|
15
|
+
M2VjZmFiMzU1NDNiNDc5ODc4YTI3OTM1MWUyNzM0OWY1Yzk1MzU=
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -3,15 +3,18 @@ source 'https://rubygems.org'
|
|
3
3
|
# Specify your gem's dependencies in rack_warden.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
+
# To use edge sinatra, which should fix "NoMethodError: undefined method `join' for #<String:0x000001016a7c58>",
|
7
|
+
# put this in your gemfile:
|
8
|
+
#gem 'sinatra', git: 'git@github.com:sinatra/sinatra.git'
|
6
9
|
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# gem 'dm-sqlite-adapter'
|
12
|
-
# gem 'warden'
|
13
|
-
#
|
14
|
-
# #gem 'shotgun'
|
15
|
-
# #gem 'tux'
|
16
|
-
# #gem 'thin'
|
10
|
+
# Extra utilities that you might want.
|
11
|
+
#gem 'shotgun'
|
12
|
+
#gem 'tux'
|
13
|
+
#gem 'thin'
|
17
14
|
|
15
|
+
# If you have trouble with failing dependencies or templating errors in rails 2.3,
|
16
|
+
# you may need to activate any or all of these.
|
17
|
+
#gem "i18n", "0.6.11"
|
18
|
+
#gem "mime-types", "~> 1.25"
|
19
|
+
#gem "nokogiri", "1.5.11"
|
20
|
+
#gem "erubis"
|
data/README.md
CHANGED
@@ -1,45 +1,50 @@
|
|
1
1
|
# RackWarden
|
2
2
|
|
3
|
-
RackWarden is a
|
3
|
+
RackWarden is a ruby gatekeeper mini-app providing authentication and user management for rack based apps. Protecting your entire application with only a few lines of code, RackWarden uses its own controllers, views, models, and database. You can also drop in your own views and layouts, specify your own database, and use your existing users table for seamless custom integration.
|
4
4
|
|
5
|
-
RackWarden uses Sinatra for
|
5
|
+
RackWarden is Rack middleware that uses Sinatra for UI, Warden for authentication, and DataMapper for database connections. It is based on the sinatra-warden-example at <https://github.com/sklise/sinatra-warden-example>.
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
Please note that RackWarden is a work-in-progress. The gemspec, the files, the code, and the documentation can and will change over time. Follow on github for the latest fixes, changes, and developments.
|
10
|
-
|
11
|
-
## What Does it Do?
|
12
|
-
|
13
|
-
RackWarden is a modular gatekeeper for your ruby web app. Once you enable RackWarden in your rack-based project, all routes/actions in your project will require a login and will redirect browsers to an authentication page. RackWarden provides its own view & layout templates to facilitate user authentication. RackWarden also provides it's own database & table structure to store user data. Views, layouts, databases, and tables are easily customized and/or overridden, however.
|
14
|
-
|
15
|
-
Once RackWarden authenticates a user, it gets out of the way, and the user is returned to your application. RackWarden also provides a number of user management tools for common actions like creating, updating, and deleting users.
|
16
|
-
|
17
|
-
Most of the RackWarden features can be customized. You can override the views, the database, the actions, and even the authentication logic with your own templates and code. The easiest (and possibly the most dramatic) customization is to provide RackWarden with your own layout template, giving RackWarden the appearane of the application you're integrating it with.
|
7
|
+
RackWarden is a work-in-progress. The gemspec, the files, the code, and the documentation are likely to change over time. Follow on [rubygems.org](https://rubygems.org/gems/rack_warden) or [github](https://github.com/ginjo/rack_warden) for the latest updates.
|
18
8
|
|
19
9
|
|
20
10
|
## Installation
|
21
11
|
|
22
|
-
In your Gemfile
|
12
|
+
In your Gemfile.
|
23
13
|
|
24
14
|
gem 'rack_warden'
|
25
15
|
|
26
|
-
Then
|
16
|
+
Then.
|
27
17
|
|
28
18
|
$ bundle
|
29
19
|
|
30
|
-
Or install manually
|
20
|
+
Or install manually.
|
31
21
|
|
32
22
|
$ gem install rack_warden
|
33
23
|
|
24
|
+
If you are using a database other than sqlite, and you want RackWarden to use that database as well, install the corresponding DataMapper database adapter. For sqlite, the dm-sqlite-adapter is already included in the RackWarden gemspec.
|
25
|
+
|
26
|
+
gem 'dm-mysql-adapter'
|
27
|
+
gem 'dm-postgres-adapter'
|
28
|
+
|
29
|
+
See the [DataMapper](https://github.com/datamapper/dm-core/wiki/Adapters) site for more info on adapters.
|
34
30
|
|
35
31
|
## Usage
|
36
32
|
|
37
33
|
A few simple steps will have your entire app protected.
|
34
|
+
If not using bundler, don't forget to ```require 'rack_warden'```.
|
38
35
|
|
39
36
|
### Sinatra
|
40
37
|
|
38
|
+
# classic
|
39
|
+
register RackWarden
|
40
|
+
|
41
|
+
get "/" do
|
42
|
+
erb "All routes are now protected"
|
43
|
+
end
|
44
|
+
|
45
|
+
# modular
|
41
46
|
class MySinatraApp < Sinatra::Base
|
42
|
-
|
47
|
+
register RackWarden
|
43
48
|
|
44
49
|
get "/" do
|
45
50
|
erb "All routes are now protected"
|
@@ -54,53 +59,96 @@ application.rb or environment.rb
|
|
54
59
|
|
55
60
|
# All routes are now protected
|
56
61
|
|
62
|
+
### Rack
|
63
|
+
|
64
|
+
You can also use RackWarden with bare Rack applications. A ruby application framework is not necessary.
|
65
|
+
|
66
|
+
config.ru
|
67
|
+
|
68
|
+
map "/" do
|
69
|
+
use RackWarden
|
70
|
+
run MyApp
|
71
|
+
end
|
57
72
|
|
58
73
|
|
59
74
|
## Configuration
|
60
75
|
|
61
|
-
RackWarden will look for a configuration file named
|
76
|
+
RackWarden will look for a yaml configuration file named rack_warden.yml in your project root or in your project-root/config/ directory. You can specify any of RackWarden's settings here.
|
62
77
|
|
63
78
|
---
|
64
79
|
database: sqlite3:///usr/local/some_other_database.sqlite3.db
|
65
80
|
layout: :'my_custom_layout.html.erb'
|
66
81
|
|
67
82
|
|
68
|
-
You an also pass configuration settings to RackWarden through the ```use``` method of your framework. The params hash of ```use``` will be translated directly to RackWarden's settings. In addition to RackWarden's specific configuration options, you can also pass
|
83
|
+
You an also pass configuration settings to RackWarden through the ```use``` method of your framework. The params hash of ```use``` will be translated directly to RackWarden's settings. In addition to RackWarden's specific configuration options, you can also pass standard Sinatra settings.
|
69
84
|
|
70
|
-
If you pass a block with the ```use``` method, the block will be evaluated in the context of the RackWarden::App class. Anything you do in that block is just as if you were writing code in the
|
85
|
+
If you pass a block with the ```use``` method, the block will be evaluated in the context of the RackWarden::App class. Anything you do in that block is just as if you were writing code in the RackWarden::App class itself. While in the block, you also have access to the current _instance_ of RackWarden::App.
|
71
86
|
|
72
87
|
use RackWarden::App do |rack_warden_app_instance|
|
73
|
-
set :
|
88
|
+
set :some_setting, 'some_value'
|
74
89
|
end
|
90
|
+
|
91
|
+
You can also set RackWarden settings directly from inside your application.
|
92
|
+
|
93
|
+
RackWarden::App.set({:setting1 => val1, :setting2 => val2})
|
75
94
|
|
95
|
+
Note that with some frameworks, the RackWarden middleware instance will be lazy-loaded only when it is needed (usually with the first request). This is a function of the ruby framework you are using and is not under control of RackWarden. This means that some settings you pass with the ```use``` method (or block) may have 'missed the boat'. RackWarden tries to integrate these settings in lazy-loaded situations as best as it can. However, if you suspect your settings might not be taking, put your settings in the rack\_warden.yml config file. The config file will always be loaded with the RackWarden module. If you are using Sinatra, load up RackWarden with ```register RackWarden```, as that will initialize RackWarden as soon as your Sinatra project loads.
|
96
|
+
|
76
97
|
|
77
98
|
## Configuration Options
|
78
99
|
|
79
100
|
Current list of settings specific to rack\_warden, with defaults.
|
80
101
|
|
102
|
+
set :config_files, [ENV['RACK_WARDEN_CONFIG_FILE'], 'rack_warden.yml', 'config/rack_warden.yml'].compact.uniq
|
103
|
+
set :layout, :'rw_layout.html'
|
104
|
+
set :default_route, '/'
|
105
|
+
set :exclude_from_return_to, 'login|logout|new|create'
|
106
|
+
set :repository_name, :default
|
107
|
+
set :database_config => nil
|
108
|
+
set :database_default => "sqlite3:///#{Dir.pwd}/rack_warden.sqlite3.db"
|
109
|
+
set :recaptcha, Hash.new
|
110
|
+
set :require_login, nil
|
111
|
+
set :rack_authentication, nil
|
112
|
+
set :allow_public_signup, false
|
113
|
+
set :logging, true
|
114
|
+
set :log_path, "#{Dir.pwd}/log/rack_warden.#{settings.environment}.log"
|
115
|
+
set :use_common_logger, false
|
116
|
+
set :sessions, true
|
117
|
+
set :remember_token_cookie_name, 'rack_warden_remember_token'
|
118
|
+
set :user_table_name, 'rack_warden_users'
|
119
|
+
set :views, File.expand_path("../views/", __FILE__) unless views
|
120
|
+
set :login_on_create, true
|
121
|
+
set :login_on_activate, false
|
122
|
+
set :rw_prefix, '/auth'
|
123
|
+
set :mail_options,
|
124
|
+
:delivery_method => :test,
|
125
|
+
:delivery_options => {:from => 'my@email.com'}
|
126
|
+
|
127
|
+
|
128
|
+
Some of the configuration settings in more detail.
|
129
|
+
|
81
130
|
### :layout
|
82
131
|
|
83
|
-
A symbol representing a layout file in any of the view paths.
|
132
|
+
A symbol representing a (Sinatra) layout file in any of the view paths.
|
84
133
|
|
85
134
|
layout: :'rack_warden_layout.html'
|
86
135
|
|
87
136
|
### :default\_route
|
88
137
|
|
89
|
-
A Sinatra route to fall back on after logout, errors, or any
|
138
|
+
A Sinatra route to fall back on after logout, errors, or any redirect that has no specified route.
|
90
139
|
|
91
140
|
default_route: '/'
|
92
141
|
|
93
142
|
### :database\_config
|
94
143
|
|
95
|
-
A database specification hash or
|
144
|
+
A database specification hash or url string.
|
96
145
|
|
97
146
|
database_config: "sqlite:///Absolute/path/to/your/rack_warden.sqlite3.db"
|
98
147
|
|
99
148
|
# or
|
100
149
|
|
101
150
|
database_config:
|
102
|
-
adapter:
|
103
|
-
encoding: utf8
|
151
|
+
adapter: mysql
|
104
152
|
database: my_db_name
|
105
153
|
username: root
|
106
154
|
password: my_password
|
@@ -110,31 +158,30 @@ A database specification hash or or url string.
|
|
110
158
|
### :require\_login
|
111
159
|
|
112
160
|
Parameters to pass to the before/before\_filter for require\_login.
|
113
|
-
So if
|
161
|
+
So if your main app is Sinatra,
|
114
162
|
|
115
|
-
require_login:
|
163
|
+
require_login: '/admin*'
|
116
164
|
|
117
165
|
is the same as
|
118
166
|
|
119
167
|
class MySinatraApp
|
120
|
-
require_login
|
168
|
+
require_login '/admin*'
|
121
169
|
end
|
122
170
|
|
123
171
|
which is the same as
|
124
172
|
|
125
173
|
class MySinatraApp
|
126
|
-
before
|
174
|
+
before '/admin*' do
|
127
175
|
require_login
|
128
176
|
end
|
129
177
|
end
|
130
178
|
|
131
179
|
For Rails, you would be passing a hash of :only or :except keys.
|
132
180
|
|
133
|
-
require_login:
|
134
|
-
except: :index
|
181
|
+
require_login: {:except => [:index, :show]}
|
135
182
|
|
136
183
|
The default for :require\_login is nil, which means require login on every route or action.
|
137
|
-
To disable automatic activation of require\_login,
|
184
|
+
To disable automatic activation of require\_login, set it to ```false```.
|
138
185
|
|
139
186
|
### :allow\_public\_signup
|
140
187
|
|
@@ -145,44 +192,54 @@ Allows public access to the account creation view & action.
|
|
145
192
|
|
146
193
|
### :recaptcha
|
147
194
|
|
148
|
-
Settings for Google's recaptcha service
|
195
|
+
Settings for Google's recaptcha service. If these settings exist, recaptcha will be required on account creation and password reset/recover actions.
|
149
196
|
|
150
197
|
:recaptcha => {
|
151
198
|
:sitekey => '',
|
152
199
|
:secret => ''
|
153
200
|
}
|
154
201
|
|
155
|
-
### :log\_path
|
156
202
|
|
157
|
-
File.join(Dir.pwd, 'log', 'rack_warden.log')
|
158
|
-
|
159
|
-
### :user\_table\_name
|
160
203
|
|
161
|
-
|
162
|
-
|
163
|
-
### :views
|
204
|
+
## Customization
|
164
205
|
|
165
|
-
|
206
|
+
### Actions
|
166
207
|
|
208
|
+
RackWarden adds a handful of helpers to your base controller class, giving you finer control over what actions (or routes) are protected. One of these helpers is ```require_login```. Run this helper in any action that you want protected behind a login session. If the user is not logged in, they will be redirected to the login action provided by RackWarden. Once they have successfully completed the login, the user will be redirected back to the protected page they were originally trying to access.
|
209
|
+
|
210
|
+
The default for RackWarden is to enable the ```require_login``` helper on every action in your project. To disable this default, set ```:require_login``` (in your RackWarden configuration) to anything other than nil. Setting ```:require_login => false``` will disable automatic activation of the ```require_login``` helper entirely.
|
211
|
+
|
212
|
+
To control authentication inclusion/exclusion of routes & actions on a per-controller or per-application basis, use the class method ```require_login```. This creates a before filter in the context where you declare it. You can pass any options to ```require_login``` that are allowed by your framework's before filter.
|
213
|
+
|
214
|
+
# Rails
|
215
|
+
class Products < ActionController::Base
|
216
|
+
require_login :only=>[:new, :create, :edit, :update]
|
217
|
+
...
|
218
|
+
end
|
219
|
+
|
220
|
+
# Sinatra
|
221
|
+
class MyApp < Sinatra::Base
|
222
|
+
require_login '/admin*', :agent => /Songbird/
|
223
|
+
...
|
224
|
+
end
|
167
225
|
|
168
|
-
## Customization
|
169
226
|
|
170
227
|
### Views
|
171
228
|
|
172
|
-
|
229
|
+
RackWarden looks for templates at the top level of your views directory and in views/rack\_warden/ (if it exists) as a default. You can change or add to this with the ```:views``` setting.
|
173
230
|
|
174
231
|
use RackWarden::App, :views => File.join(Dir.pwd, 'app/views/another_directory')
|
175
232
|
|
176
|
-
Or if you simply want RackWarden to
|
233
|
+
Or if you simply want RackWarden to wrap all of its views in your own custom layout, pass it a file path in the :layout parameter.
|
177
234
|
|
178
235
|
use RackWarden::App, :layout => :'layouts/rack_warden_layout.html'
|
179
236
|
|
180
|
-
|
237
|
+
Remember that RackWarden is Sinatra, and any templates you pass must use Sinatra-specific code. For example, Sinatra uses ```url``` instead of Rails' ```url_for```. Also remember that template names in Sinatra must always be symbols. Have a look at the readme on Sinatra's web site for more details on Sinatra's DSL.
|
181
238
|
|
182
239
|
|
183
240
|
### Database
|
184
241
|
|
185
|
-
As a default, RackWarden will use a sqlite3
|
242
|
+
As a default, RackWarden will use a sqlite3 database created in your app's root. To use the database specified in your project, just pass ```:auto``` to the ```:database_config``` setting. Pass ```:file``` to set up a sqlite3 database in your app's working directory. Or pass your own custom database specification (a url or hash). If you use a database other than sqlite3, you will need to include the respective DataMapper extension gem in your Gemfile or in your manually installed gem list. For MySQL, use dm-mysql-adapter, for Postgres use dm-postgres-adapter. See the DataMapper site for more info on database adapters.
|
186
243
|
|
187
244
|
# Database specification as a url
|
188
245
|
database_config: 'sqlite3:///path/to/my/database.sqlite3.db'
|
@@ -190,12 +247,17 @@ As a default, RackWarden will use a sqlite3 in-memory database (that starts fres
|
|
190
247
|
# Database specification as a hash
|
191
248
|
database_config: {adapter: 'sqlite3', database: '/path/to/my/database.sqlite3.db'}
|
192
249
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
250
|
+
# Use a remote MySQL database
|
251
|
+
database_config: {adapter: 'mysql', username: 'will', password: 'mypass',
|
252
|
+
host: 'somehost', database: 'my_database'}
|
253
|
+
|
254
|
+
# Format for database urls
|
255
|
+
#<adapter>://<username>:<password>@<host>:<port>/<database_name>
|
256
|
+
|
257
|
+
#### A note about DataMapper and ActiveRecord
|
258
|
+
|
259
|
+
ActiveRecord and DataMapper should be able to coexist in the same ruby process. Note that the database adapters for ActiveRecord are not the same as those for DataMapper. So for example, if you are using mysql, you will need the activerecord-mysql2-adapter for ActiveRecord (or mysql2 or mysql, if you're on older rails versions) and the dm-mysql-adapter for DataMapper.
|
260
|
+
|
199
261
|
|
200
262
|
|
201
263
|
|
data/config.ru
CHANGED
data/lib/rack_warden.rb
CHANGED
@@ -6,25 +6,42 @@ module RackWarden
|
|
6
6
|
end
|
7
7
|
|
8
8
|
require "sinatra/base"
|
9
|
-
require "sinatra/
|
9
|
+
#require "sinatra/contrib" # not compatible with rails 2.3 because of rack dependency conflict.
|
10
|
+
require "rack/flash" # this somehow loads rack/flash3
|
11
|
+
require "rack/contrib/cookies" # This is needed to set cookies in warden callbacks.
|
10
12
|
require 'bcrypt'
|
11
13
|
require 'data_mapper'
|
12
14
|
require 'warden'
|
13
|
-
require 'open-uri'
|
14
15
|
require 'yaml'
|
16
|
+
require 'tilt/erb' # An error somwhere suggested this be explicity required.
|
17
|
+
require 'rack_warden/core_patches'
|
18
|
+
|
19
|
+
autoload :Mail, 'mail'
|
20
|
+
autoload :URI, 'open-uri'
|
21
|
+
autoload :Base64, 'base64'
|
15
22
|
|
16
23
|
module RackWarden
|
17
24
|
autoload :App, 'rack_warden/app'
|
25
|
+
autoload :Env, 'rack_warden/env'
|
18
26
|
autoload :User, "rack_warden/models"
|
19
27
|
autoload :Pref, "rack_warden/models"
|
28
|
+
autoload :Mail, "rack_warden/mail"
|
20
29
|
autoload :Routes, "rack_warden/routes"
|
21
30
|
autoload :VERSION, "rack_warden/version"
|
22
31
|
autoload :WardenConfig, "rack_warden/warden"
|
32
|
+
autoload :AppClassMethods, "rack_warden/helpers"
|
33
|
+
autoload :UniversalHelpers, "rack_warden/helpers"
|
23
34
|
autoload :RackWardenHelpers, "rack_warden/helpers"
|
35
|
+
# Autload patched versions of respond_with & namespace.
|
36
|
+
# respond_with handles uri dot-format extension,
|
37
|
+
# and namespace handles require_login.
|
38
|
+
autoload :RespondWith, "rack_warden/sinatra/respond_with"
|
39
|
+
autoload :Namespace, "rack_warden/sinatra/namespace"
|
40
|
+
autoload :Frameworks, "rack_warden/frameworks"
|
24
41
|
module Frameworks
|
25
|
-
autoload :Base, 'rack_warden/frameworks'
|
26
42
|
autoload :Sinatra, 'rack_warden/frameworks/sinatra'
|
27
43
|
autoload :Rails, 'rack_warden/frameworks/rails'
|
44
|
+
autoload :Rack, 'rack_warden/frameworks/rack'
|
28
45
|
end
|
29
46
|
|
30
47
|
# Make this module a pseudo-class appropriate for middlware stack. Use RackWarden for older rails apps (rather than 'RackWarden::App')
|
@@ -50,8 +67,19 @@ module RackWarden
|
|
50
67
|
end
|
51
68
|
|
52
69
|
def self.included(base)
|
53
|
-
|
54
|
-
|
70
|
+
App.logger.warn "RW self.included into BASE #{base}, ID #{base.object_id}"
|
71
|
+
# Force initialize rack_warden, even if not all the settings are known yet.
|
72
|
+
#App.new base
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.registered(app)
|
76
|
+
App.setup_framework app
|
77
|
+
# TODO: Do we need to check installed middleware to make sure we only have one instance of RW,
|
78
|
+
# in case someone registers RW with multiple sinatra apps in the same ruby process (which seems to be a common practice)?
|
79
|
+
app.use self
|
55
80
|
end
|
81
|
+
|
82
|
+
# Enable this for automatic sinatra top-level registration.
|
83
|
+
#Sinatra.register self
|
56
84
|
|
57
85
|
end
|
data/lib/rack_warden/app.rb
CHANGED
@@ -1,49 +1,47 @@
|
|
1
1
|
# require 'bundler'
|
2
2
|
# Bundler.require
|
3
3
|
|
4
|
+
require 'logger'
|
5
|
+
|
4
6
|
module RackWarden
|
5
7
|
class App < Sinatra::Base
|
6
|
-
|
8
|
+
|
7
9
|
set :config_files, [ENV['RACK_WARDEN_CONFIG_FILE'], 'rack_warden.yml', 'config/rack_warden.yml'].compact.uniq
|
8
10
|
set :layout, :'rw_layout.html'
|
9
11
|
set :default_route, '/'
|
10
|
-
set :
|
11
|
-
set :
|
12
|
+
set :exclude_from_return_to, 'login|logout|new|create'
|
13
|
+
set :repository_name, :default
|
14
|
+
set :database_config => nil
|
15
|
+
set :database_default => "sqlite3:///#{Dir.pwd}/rack_warden.sqlite3.db"
|
12
16
|
set :recaptcha, Hash.new
|
13
17
|
set :require_login, nil
|
18
|
+
set :rack_authentication, nil
|
14
19
|
set :allow_public_signup, false
|
20
|
+
set :logging, true
|
15
21
|
set :log_path, "#{Dir.pwd}/log/rack_warden.#{settings.environment}.log"
|
16
|
-
set :
|
22
|
+
set :log_file, ($0[/rails|irb|ruby|rack|server/i] && development? ? $stdout : nil)
|
23
|
+
set :log_level => ENV['RACK_WARDEN_LOG_LEVEL'] || (development? ? 'INFO' : 'WARN')
|
24
|
+
set :logger, nil
|
25
|
+
set :use_common_logger, false
|
26
|
+
set :reset_logger, false
|
27
|
+
set :sessions, true # Will use parent app sessions. Pass in :key=>'something' to enable RW-specific sessions (maybe).
|
28
|
+
set :remember_token_cookie_name, 'rack_warden_remember_token'
|
29
|
+
set :user_table_name, 'rack_warden_users'
|
17
30
|
set :views, File.expand_path("../views/", __FILE__) unless views
|
18
31
|
set :initialized, false
|
32
|
+
set :login_on_create, true
|
33
|
+
set :login_on_activate, false
|
34
|
+
set :rw_prefix, '/auth'
|
35
|
+
set :mail_options,
|
36
|
+
:delivery_method => :test,
|
37
|
+
:delivery_options => {:from => 'my@email.com'} #, :openssl_verify_mode => OpenSSL::SSL::VERIFY_NONE
|
38
|
+
|
19
39
|
|
20
|
-
# Load config from file, if any exist.
|
21
|
-
Hash.new.tap do |hash|
|
22
|
-
config_files.each {|c| hash.merge!(YAML.load_file(File.join(Dir.pwd, c))) rescue nil}
|
23
|
-
set hash
|
24
|
-
end
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
enable :sessions
|
29
|
-
register Sinatra::Flash
|
30
|
-
|
31
|
-
begin
|
32
|
-
enable :logging
|
33
|
-
set :log_file, File.new(settings.log_path, 'a+')
|
34
|
-
settings.log_file.sync = true
|
35
|
-
use Rack::CommonLogger, settings.log_file
|
36
|
-
rescue
|
37
|
-
end
|
38
40
|
|
39
|
-
|
40
|
-
include RackWarden::Routes
|
41
|
+
register AppClassMethods
|
41
42
|
|
42
|
-
helpers RackWardenHelpers
|
43
|
-
helpers UniversalHelpers
|
44
|
-
|
45
|
-
|
46
43
|
|
44
|
+
|
47
45
|
# WBR - This will receive params and a block from the parent "use" statement.
|
48
46
|
# This middleware app has been modified to process the parent use-block in
|
49
47
|
# the context of the RackWarden class. So you can set settings on RackWarden,
|
@@ -54,40 +52,30 @@ module RackWarden
|
|
54
52
|
# set :myvar, 'something'
|
55
53
|
# end
|
56
54
|
#
|
55
|
+
# TODO: Move most of this functionality to a class method, so it can be called from self.registered(app)
|
57
56
|
def initialize(parent_app_instance=nil, *args, &block)
|
58
57
|
super(parent_app_instance, &Proc.new{}) # Must send empty proc, not original proc, since we're calling original block here.
|
59
58
|
initialization_args = args.dup
|
60
|
-
|
61
|
-
# extract options.
|
59
|
+
logger.info "RW new app instance with parent: #{@app}"
|
62
60
|
opts = args.last.is_a?(Hash) ? args.pop : {}
|
61
|
+
|
62
|
+
|
63
|
+
|
63
64
|
if app && !settings.initialized
|
64
|
-
|
65
|
+
logger.warn "RW initializing settings from app instance"
|
65
66
|
|
66
|
-
|
67
|
-
|
68
|
-
settings.set(:original_views, settings.views)
|
69
|
-
|
70
|
-
# Set app settings with remainder of opts.
|
71
|
-
settings.set opts if opts.any?
|
72
|
-
|
67
|
+
self.class.setup_framework(parent_app_instance, *initialization_args) #unless Frameworks.selected_framework
|
68
|
+
|
73
69
|
# Eval the use-block from the parent app, in context of this app.
|
74
70
|
settings.instance_exec(self, &block) if block_given?
|
75
71
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
new_views = []
|
84
|
-
new_views.unshift settings.original_views
|
85
|
-
new_views.unshift framework_module.views_path unless settings.views==false
|
86
|
-
new_views.unshift settings.views
|
87
|
-
settings.set :views, new_views.flatten.compact.uniq
|
88
|
-
|
89
|
-
puts "RW compiled views: #{settings.views.inspect}"
|
90
|
-
end
|
72
|
+
# Set global layout (remember to use :layout=>false in your calls to partials).
|
73
|
+
settings.set :erb, :layout=>settings.layout
|
74
|
+
|
75
|
+
settings.initialize_logging
|
76
|
+
|
77
|
+
logger.info "RW compiled views: #{settings.views.inspect}"
|
78
|
+
|
91
79
|
settings.set :initialized, true
|
92
80
|
end
|
93
81
|
|
@@ -95,14 +83,41 @@ module RackWarden
|
|
95
83
|
|
96
84
|
# Store this app instance in the env.
|
97
85
|
def call(env)
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
86
|
+
logger.debug "RW app.call extending env with Env."
|
87
|
+
env.extend Env
|
88
|
+
logger.debug "RW app.call next app: #{@app}"
|
89
|
+
|
90
|
+
# Set this now, so you can access the rw app instance from the endpoint app.
|
91
|
+
logger.debug "RW app.call storing app instance in env['rack_warden_instance'] #{self}"
|
92
|
+
self.request= Rack::Request.new(env)
|
93
|
+
env.rack_warden = self
|
94
|
+
|
95
|
+
# Authenticate here-and-now.
|
96
|
+
if !request.path_info.to_s.match(/^\/auth/) && settings.rack_authentication
|
97
|
+
logger.debug "RW rack_authentication for path_info: #{request.path_info}"
|
98
|
+
Array(settings.rack_authentication).each do |rule|
|
99
|
+
logger.debug "RW rack_authentication rule #{rule}"
|
100
|
+
(require_login) if rule && request.path_info.to_s.match(Regexp.new rule.to_s)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Send to super, then build & process response.
|
105
|
+
# resp = Rack::Response.new *super(env).tap{|e| e.unshift e.pop}
|
106
|
+
# #resp.set_cookie :wbr_cookie, :value=>"Yay!", :expires=>Time.now+60*10
|
107
|
+
# logger.debug "App.call: #{resp.finish}"
|
108
|
+
# resp.finish
|
109
|
+
super(env)
|
102
110
|
end
|
111
|
+
|
112
|
+
# Only initialize app after all above have loaded.
|
113
|
+
#initialize_app_class
|
103
114
|
|
104
115
|
|
105
|
-
end # App
|
116
|
+
end # App
|
117
|
+
|
118
|
+
# TODO: This is not working:
|
119
|
+
#Sinatra::Application.register self
|
106
120
|
end # RackWarden
|
107
121
|
|
108
122
|
|
123
|
+
|