rack_warden 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.gitignore +3 -0
- data/README.md +45 -16
- data/lib/rack_warden.rb +18 -5
- data/lib/rack_warden/app.rb +70 -83
- data/lib/rack_warden/frameworks.rb +51 -0
- data/lib/rack_warden/frameworks/rails.rb +35 -0
- data/lib/rack_warden/frameworks/sinatra.rb +33 -0
- data/lib/rack_warden/models.rb +33 -0
- data/lib/rack_warden/models/user.rb +37 -0
- data/lib/rack_warden/version.rb +1 -1
- data/lib/rack_warden/views/rw_admin.html.erb +17 -15
- data/lib/rack_warden/views/rw_index.html.erb +3 -0
- data/lib/rack_warden/views/{rack_warden_layout.html.erb → rw_layout.html.erb} +13 -9
- data/lib/rack_warden/views/{login_user.html.erb → rw_login.html.erb} +2 -2
- data/lib/rack_warden/views/{create_user.html.erb → rw_new_user.html.erb} +4 -4
- data/lib/rack_warden/views/rw_protected.html.erb +3 -0
- metadata +12 -8
- data/lib/rack_warden/model.rb +0 -37
- data/lib/rack_warden/views/rack_warden_index.html.erb +0 -1
- data/lib/rack_warden/views/rack_warden_protected.html.erb +0 -1
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NDMyOGMzYTQzNmVlODAwMTRjMDIxZGE4ZmQyNmJjNDRmNDIxNGUwZA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NzIwMTkzZWNhMmFkYjk5MmE4MGRhYzMxODE3MTA1MjMwZWFlMmI4MA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YmUzYWRkMDZjZWI4MTBiZmYxZGMyZGE1M2ZmMGI3ZTU0ZDA4NDZkYzAzOThm
|
10
|
+
YjE3NTI1ZmViNDZmMmJkNDBmMTAxZGU4NTUyYWJhNDY0YzRkYzkxODJlYWI5
|
11
|
+
MDA4MTJlNTM0YTk1MDc0NzlmNTQ3YTdhMTk4M2MwNTY2M2E3Njk=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZjMyZjgwNzlmYWZkOTllODA2OTVhNDZmMzM4ZjU2ZTlhYzA1ZmIzZTVkMDdl
|
14
|
+
MjMzODU4ZTVjOWYyNGEwNmFmYzY2NGI0ZWVhNjY0MjZmOTlhZTQ0OTAyODYz
|
15
|
+
YTEwMjZkYzdkZDM1M2ZlOTMxZjBiMzBmNjdjMjQyOTM0NTllNDI=
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -2,17 +2,19 @@
|
|
2
2
|
|
3
3
|
RackWarden is a rack middleware mini-app that provides user authentication and management to any rack-based app (currently supports Sinatra and Rails, with more on the way). This project is in its infancy. It is currently a great starter to get you going with plug-in authentication for your ruby app. Over time it will grow into a more fully featured package while maintaining a focus on simplicity, modularity, and transparency.
|
4
4
|
|
5
|
-
RackWarden uses Sinatra for the mini-app, Warden for authentication, and DataMapper for database connections. It is based on the sinatra-warden-example at https://github.com/sklise/sinatra-warden-example. If you are new to
|
5
|
+
RackWarden uses Sinatra for the mini-app, Warden for authentication, and DataMapper for database connections. It is based on the sinatra-warden-example at https://github.com/sklise/sinatra-warden-example. If you are new to Warden or Sinatra, I highly recommend downloading and experimenting with that example.
|
6
6
|
|
7
7
|
My goal in developing this software is to have drop-in authentication containing most of the features you see in user/account management sections of a typical web site. But I don't want to be strapped by this module in any of my projects, so it must be customizable. Or rather, overridable. The basics of this flexibility are already in place, and it will be a central theme throughout. See below for examples on overriding and customizing RackWarden.
|
8
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
|
+
|
9
11
|
## What Does it Do?
|
10
12
|
|
11
13
|
RackWarden acts as a self-sufficient 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 tables to store user data.
|
12
14
|
|
13
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.
|
14
16
|
|
15
|
-
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. The easiest (and possibly the most dramatic) customization is to provide RackWarden with your own layout template, giving RackWarden the look-and-feel of your own application.
|
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 look-and-feel of your own application.
|
16
18
|
|
17
19
|
|
18
20
|
## Installation
|
@@ -56,31 +58,39 @@ application.rb or environment.rb
|
|
56
58
|
|
57
59
|
## Configuration
|
58
60
|
|
59
|
-
|
61
|
+
RackWarden will look for a configuration file named rack\_warden.yml in your project root or in your project/config/ directory.
|
62
|
+
|
63
|
+
---
|
64
|
+
database: sqlite3:///usr/local/some_other_database.sqlite3.db
|
65
|
+
layout: :'my_custom_layout.html.erb'
|
66
|
+
|
60
67
|
|
61
|
-
|
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 in any standard Sinatra settings.
|
69
|
+
|
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 app class itself. While in the block, you also have access to the current instance of RackWarden::App and the current instance of the parent app.
|
62
71
|
|
63
72
|
use RackWarden::App do |rack_warden_app_instance, parent_app_instance|
|
64
73
|
set :somesetting, 'some_value'
|
65
74
|
end
|
75
|
+
|
66
76
|
|
67
|
-
|
77
|
+
## Configuration Options
|
68
78
|
|
69
79
|
Current list of settings specific to rack\_warden, with defaults.
|
70
80
|
|
71
|
-
|
81
|
+
### :layout
|
72
82
|
|
73
83
|
A symbol representing a layout file in any of the view paths.
|
74
84
|
|
75
85
|
layout: :'rack_warden_layout.html'
|
76
86
|
|
77
|
-
|
87
|
+
### :default\_route
|
78
88
|
|
79
89
|
A Sinatra route to fall back on after logout, errors, or any action that has no specified route.
|
80
90
|
|
81
91
|
default_route: '/'
|
82
92
|
|
83
|
-
|
93
|
+
### :database\_config
|
84
94
|
|
85
95
|
A database specification hash or or url string.
|
86
96
|
|
@@ -97,7 +107,7 @@ A database specification hash or or url string.
|
|
97
107
|
host: 127.0.0.1
|
98
108
|
port: 3306
|
99
109
|
|
100
|
-
|
110
|
+
### :require\_login
|
101
111
|
|
102
112
|
Parameters to pass to the before/before\_filter for require\_login.
|
103
113
|
So if you're main app is Sinatra,
|
@@ -124,16 +134,16 @@ For Rails, you would be passing a hash of :only or :except keys.
|
|
124
134
|
except: :index
|
125
135
|
|
126
136
|
The default for :require\_login is nil, which means require login on every route or action.
|
127
|
-
To disable automatic activation of require\_login, pass it
|
137
|
+
To disable automatic activation of require\_login, pass it ```false```.
|
128
138
|
|
129
|
-
|
139
|
+
### :allow\_public\_signup
|
130
140
|
|
131
141
|
Allows public access to the account creation view & action.
|
132
142
|
|
133
143
|
allow_public_signup: false
|
134
144
|
|
135
145
|
|
136
|
-
|
146
|
+
### :recaptcha
|
137
147
|
|
138
148
|
Settings for Google's recaptcha service
|
139
149
|
|
@@ -142,21 +152,40 @@ Settings for Google's recaptcha service
|
|
142
152
|
:secret => ''
|
143
153
|
}
|
144
154
|
|
155
|
+
### :log\_path
|
156
|
+
|
157
|
+
File.join(Dir.pwd, 'log', 'rack_warden.log')
|
158
|
+
|
145
159
|
## Customization
|
146
160
|
|
161
|
+
### Views
|
162
|
+
|
147
163
|
To customize RackWarden for your specific project, you can set :views to point to a directory within your project. Then create templates that match the names of RackWarden templates, and they will be picked up and rendered. RackWarden looks for templates at the top level of your views directory as a default. You can change or add to this when you define the middleware in your project.
|
148
164
|
|
149
|
-
|
165
|
+
Update: also looks in views/rack\_warden/ for view templates.
|
166
|
+
|
167
|
+
use RackWarden::App, :views => File.join(Dir.pwd, 'app/views/another_directory')
|
150
168
|
|
151
169
|
Or if you simply want RackWarden to use your own custom layout, pass it a file path in the :layout parameter.
|
152
170
|
|
153
171
|
use RackWarden::App, :layout => :'layouts/rack_warden_layout.html'
|
154
172
|
|
155
|
-
Just remember that RackWarden is Sinatra, and any templates you pass must use Sinatra-specific code. For example, Sinatra uses
|
173
|
+
Just 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.
|
174
|
+
|
175
|
+
|
176
|
+
### Database
|
177
|
+
|
178
|
+
As a default, RackWarden will use the database specified in your project. You can also pass a database specification with the ```:database_config``` setting.
|
179
|
+
|
180
|
+
# As a url
|
181
|
+
database_config: 'sqlite3:///path/to/my/database.sqlite3.db'
|
182
|
+
|
183
|
+
# As a hash
|
184
|
+
database_config: {adapter: 'sqlite3', database: '/path/to/my/database.sqlite3.db'}
|
185
|
+
|
186
|
+
If your project has no database, or if you pass ```false``` to the ```:database_config``` setting, RackWarden will create its own database in the working directory as 'rack_warden.sqlite3.db'.
|
156
187
|
|
157
|
-
Another way to customize RackWarden is to override its classes and methods, as you would with any other ruby code. And if you want to customize RackWarden more extensively, you can always download the source from github and directly modify the app file and templates. Then point to this modified gem in your project Gemfile.
|
158
188
|
|
159
|
-
gem 'rack_warden', :path => "../RackWarden/"
|
160
189
|
|
161
190
|
|
162
191
|
|
data/lib/rack_warden.rb
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
module RackWarden
|
2
|
+
# Incase you are using this library without the gem loaded.
|
3
|
+
PATH = File.expand_path(File.dirname(__FILE__))
|
4
|
+
puts "RW PATH #{PATH}"
|
5
|
+
$LOAD_PATH.unshift(PATH) unless $LOAD_PATH.include?(PATH)
|
6
|
+
end
|
7
|
+
|
1
8
|
require "sinatra/base"
|
2
9
|
require "sinatra/flash"
|
3
10
|
require 'bcrypt'
|
@@ -9,11 +16,17 @@ require 'open-uri'
|
|
9
16
|
# gem 'dm-sqlite-adapter'
|
10
17
|
# gem 'warden'
|
11
18
|
|
12
|
-
require "rack_warden/app"
|
13
|
-
require "rack_warden/version"
|
14
|
-
autoload :User, "rack_warden/model"
|
15
|
-
|
19
|
+
# require "rack_warden/app"
|
20
|
+
# require "rack_warden/version"
|
16
21
|
|
17
22
|
module RackWarden
|
18
|
-
|
23
|
+
autoload :App, 'rack_warden/app'
|
24
|
+
autoload :User, "rack_warden/models"
|
25
|
+
autoload :Pref, "rack_warden/models"
|
26
|
+
autoload :VERSION, "rack_warden/version"
|
27
|
+
module Frameworks
|
28
|
+
autoload :Base, 'rack_warden/frameworks'
|
29
|
+
autoload :Sinatra, 'rack_warden/frameworks/sinatra'
|
30
|
+
autoload :Rails, 'rack_warden/frameworks/rails'
|
31
|
+
end
|
19
32
|
end
|
data/lib/rack_warden/app.rb
CHANGED
@@ -5,13 +5,15 @@ module RackWarden
|
|
5
5
|
class App < Sinatra::Base
|
6
6
|
enable :sessions
|
7
7
|
register Sinatra::Flash
|
8
|
+
|
8
9
|
set :config_files, [ENV['RACK_WARDEN_CONFIG_FILE'], 'rack_warden.yml', 'config/rack_warden.yml'].compact.uniq
|
9
|
-
set :layout, :'
|
10
|
+
set :layout, :'rw_layout.html'
|
10
11
|
set :default_route, '/'
|
11
|
-
set :database_config
|
12
|
+
set :database_config => nil #, "sqlite3:///#{Dir.pwd}/rack_warden.sqlite3.db"
|
12
13
|
set :recaptcha, Hash.new
|
13
14
|
set :require_login, nil
|
14
15
|
set :allow_public_signup, false
|
16
|
+
set :log_path, File.join(Dir.pwd, 'log', 'rack_warden.log')
|
15
17
|
|
16
18
|
# Load config from file, if any exist.
|
17
19
|
Hash.new.tap do |hash|
|
@@ -30,69 +32,43 @@ module RackWarden
|
|
30
32
|
# set :myvar, 'something'
|
31
33
|
# end
|
32
34
|
#
|
33
|
-
def initialize(
|
34
|
-
|
35
|
+
def initialize(parent_app_instance=nil, *args, &block)
|
36
|
+
initialization_args = args.dup
|
37
|
+
puts "INITIALIZE middleware instance [parent_app_instance, self, args, block]: #{[parent_app_instance, self, args, block]}"
|
35
38
|
# extract options.
|
36
39
|
opts = args.last.is_a?(Hash) ? args.pop : {}
|
37
|
-
|
38
|
-
if
|
39
|
-
|
40
|
-
|
41
|
-
#
|
42
|
-
|
43
|
-
|
44
|
-
#
|
45
|
-
|
46
|
-
# do parent_app setup.
|
47
|
-
setup_parent_app(parent_app, args, opts)
|
48
|
-
#parent_app.class.helpers(RackWardenHelpers) rescue ApplicationController.send(:include, RackWardenHelpers)
|
49
|
-
end
|
50
|
-
# finally, send parent app to super, but don't send the use-block (thus the empty proc)
|
51
|
-
super(parent_app, &Proc.new{})
|
52
|
-
end
|
53
|
-
|
54
|
-
def setup_parent_app(parent_app, args, opts)
|
55
|
-
puts "RACKWARDEN initializing parent app: #{parent_app}"
|
56
|
-
#puts "RACKWARDEN parent app parents: #{parent_app.class.parents}"
|
57
|
-
#puts "RACKWARDEN parent app ancestors: #{parent_app.class.ancestors}"
|
58
|
-
klass = self.class
|
59
|
-
case
|
60
|
-
when parent_app.class.ancestors.find{|x| x.to_s=='Sinatra::Base'}
|
61
|
-
parent_app.class.helpers(RackWardenHelpers)
|
62
|
-
default_parent_views = File.join(Dir.pwd,"views")
|
40
|
+
rack_warden_app_class = self.class
|
41
|
+
if parent_app_instance
|
42
|
+
puts "RW has parent: #{parent_app_instance}"
|
43
|
+
|
44
|
+
# Save original views from opts.
|
45
|
+
rack_warden_app_class.set(:original_views, opts.has_key?(:views) ? rack_warden_app_class.views : nil)
|
46
|
+
|
47
|
+
# Set app settings with remainder of opts.
|
48
|
+
rack_warden_app_class.set opts if opts.any?
|
63
49
|
|
64
|
-
|
65
|
-
|
66
|
-
#options = args.last.is_a?(Hash) ? args.pop : Hash.new
|
67
|
-
before(*args) do
|
68
|
-
require_login
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
parent_app.class.require_login(klass.require_login) if klass.require_login != false
|
73
|
-
when parent_app.class.parents.find{|x| x.to_s=='ActionDispatch'}
|
74
|
-
ApplicationController.send(:include, RackWardenHelpers)
|
75
|
-
default_parent_views = File.join(Dir.pwd, "app/views")
|
50
|
+
# Eval the use-block from the parent app, in context of this app.
|
51
|
+
rack_warden_app_class.instance_exec(self, parent_instance, &block) if block_given?
|
76
52
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
53
|
+
# Do framework setup.
|
54
|
+
framework_module = Frameworks::Base.select_framework(binding)
|
55
|
+
if framework_module
|
56
|
+
framework_module.setup_framework
|
57
|
+
|
58
|
+
# Manipulate views
|
59
|
+
new_views = []
|
60
|
+
original_views = self.class.original_views
|
61
|
+
# append parent rails views folder unless opts.has_key?(:views)
|
62
|
+
#new_views << default_parent_views unless opts.has_key?(:views)
|
63
|
+
new_views << framework_module.views_path unless opts.has_key?(:views)
|
64
|
+
# append original_views, if original_views
|
65
|
+
new_views << original_views if original_views
|
66
|
+
self.class.set(:views => [new_views, Array(self.class.views)].flatten.compact.uniq) if new_views.any?
|
67
|
+
puts "RW views: #{self.class.views}"
|
68
|
+
end
|
86
69
|
end
|
87
|
-
|
88
|
-
|
89
|
-
original_views = klass.original_views
|
90
|
-
# append parent rails views folder unless opts.has_key?(:views)
|
91
|
-
new_views << default_parent_views unless opts.has_key?(:views)
|
92
|
-
# append original_views, if original_views
|
93
|
-
new_views << original_views if original_views
|
94
|
-
klass.set(:views => [Array(klass.views), new_views].flatten.compact.uniq) if new_views.any?
|
95
|
-
puts "RACKWARDEN views: #{klass.views}"
|
70
|
+
# finally, send parent app to super, but don't send the use-block (thus the empty proc)
|
71
|
+
super(parent_app_instance, &Proc.new{})
|
96
72
|
end
|
97
73
|
|
98
74
|
use Warden::Manager do |config|
|
@@ -127,7 +103,7 @@ module RackWarden
|
|
127
103
|
end
|
128
104
|
|
129
105
|
def authenticate!
|
130
|
-
user = User.first(username: params['user']['username'])
|
106
|
+
user = User.first(['username = ? or email = ?', params['user']['username'], params['user']['username']]) #(username: params['user']['username'])
|
131
107
|
|
132
108
|
if user.nil?
|
133
109
|
fail!("The username you entered does not exist.")
|
@@ -174,16 +150,15 @@ module RackWarden
|
|
174
150
|
params['user'] && params['user']['email'] && params['user']['password']
|
175
151
|
end
|
176
152
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
end
|
153
|
+
# def create_user
|
154
|
+
#
|
155
|
+
# verify_recaptcha if settings.recaptcha[:secret]
|
156
|
+
#
|
157
|
+
# #return unless valid_user_input?
|
158
|
+
#
|
159
|
+
# @user = User.new(params['user'])
|
160
|
+
# @user.save #&& warden.set_user(@user)
|
161
|
+
# end
|
187
162
|
|
188
163
|
def verify_recaptcha(skip_redirect=false, ip=request.ip, response=params['g-recaptcha-response'])
|
189
164
|
secret = settings.recaptcha[:secret]
|
@@ -197,7 +172,7 @@ module RackWarden
|
|
197
172
|
end
|
198
173
|
|
199
174
|
def default_page
|
200
|
-
erb :'
|
175
|
+
erb :'rw_index.html', :layout=>settings.layout
|
201
176
|
end
|
202
177
|
|
203
178
|
end # RackWardenHelpers
|
@@ -214,7 +189,12 @@ module RackWarden
|
|
214
189
|
end
|
215
190
|
|
216
191
|
get '/auth/login' do
|
217
|
-
|
192
|
+
if User.count > 0
|
193
|
+
erb :'rw_login.html', :layout=>settings.layout
|
194
|
+
else
|
195
|
+
flash(:rwarden)[:error] = warden.message || "Please create an admin account"
|
196
|
+
redirect url('/auth/new', false)
|
197
|
+
end
|
218
198
|
end
|
219
199
|
|
220
200
|
post '/auth/login' do
|
@@ -239,37 +219,43 @@ module RackWarden
|
|
239
219
|
|
240
220
|
get '/auth/new' do
|
241
221
|
halt 403 unless settings.allow_public_signup or !(User.count > 0)
|
242
|
-
erb :'
|
222
|
+
erb :'rw_new_user.html', :layout=>settings.layout, :locals=>{:recaptcha_sitekey=>settings.recaptcha['sitekey']}
|
243
223
|
end
|
244
224
|
|
245
225
|
post '/auth/create' do
|
246
|
-
if
|
226
|
+
verify_recaptcha if settings.recaptcha[:secret]
|
227
|
+
Halt "Could not create account", :layout=>settings.layout unless params[:user]
|
228
|
+
params[:user].delete_if {|k,v| v.nil? || v==''}
|
229
|
+
@user = User.new(params['user'])
|
230
|
+
if @user.save
|
231
|
+
warden.set_user(@user)
|
247
232
|
flash(:rwarden)[:success] = warden.message || "Account created"
|
248
233
|
redirect session[:return_to] || url(settings.default_route, false)
|
249
234
|
else
|
250
|
-
flash(:rwarden)[:error] = warden.message
|
235
|
+
flash(:rwarden)[:error] = "#{warden.message} => #{@user.errors.entries.join('. ')}"
|
236
|
+
puts "RW /auth/create #{@user.errors.entries}"
|
251
237
|
redirect back #url('/auth/new', false)
|
252
238
|
end
|
253
239
|
end
|
254
240
|
|
255
241
|
post '/auth/unauthenticated' do
|
256
242
|
# I had to remove the condition, since it was not updating return path when it should have.
|
257
|
-
session[:return_to] = env['warden.options'][:attempted_path] if !request.xhr? && !env['warden.options'][:attempted_path][/login/]
|
243
|
+
session[:return_to] = env['warden.options'][:attempted_path] if !request.xhr? && !env['warden.options'][:attempted_path][/login|new|create/]
|
258
244
|
puts "WARDEN ATTEMPTED PATH: #{env['warden.options'][:attempted_path]}"
|
259
245
|
puts warden
|
260
|
-
if User.count > 0
|
246
|
+
# if User.count > 0
|
261
247
|
flash(:rwarden)[:error] = warden.message || "Please login to continue"
|
262
248
|
redirect url('/auth/login', false)
|
263
|
-
else
|
264
|
-
|
265
|
-
|
266
|
-
end
|
249
|
+
# else
|
250
|
+
# flash(:rwarden)[:error] = warden.message || "Please create an admin account"
|
251
|
+
# redirect url('/auth/new', false)
|
252
|
+
# end
|
267
253
|
end
|
268
254
|
|
269
255
|
get '/auth/protected' do
|
270
256
|
warden.authenticate!
|
271
257
|
|
272
|
-
erb :'
|
258
|
+
erb :'rw_protected.html', :layout=>settings.layout
|
273
259
|
end
|
274
260
|
|
275
261
|
get '/auth/admin' do
|
@@ -280,3 +266,4 @@ module RackWarden
|
|
280
266
|
end # App
|
281
267
|
end # RackWarden
|
282
268
|
|
269
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module RackWarden
|
2
|
+
module Frameworks
|
3
|
+
module Base
|
4
|
+
|
5
|
+
# Module methods to be called on Base from RackWarden::App (and instance).
|
6
|
+
class << self
|
7
|
+
# Select the framework of the parent app.
|
8
|
+
def select_framework(env)
|
9
|
+
puts "RW framework constants: #{Frameworks.constants}"
|
10
|
+
Frameworks.constants.dup.tap{|_constants| _constants.delete(Base)}.each do |c|
|
11
|
+
r = Frameworks.const_get(c).framework_selector(env) #rescue nil
|
12
|
+
return r if r
|
13
|
+
end
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
|
17
|
+
# Extend target with target (like saying 'extend self').
|
18
|
+
def extended(target)
|
19
|
+
target.extend target
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
### Methods extended into framework module ###
|
25
|
+
|
26
|
+
attr_accessor :parent_app_instance, :parent_app_class, :rack_warden_app_instance, :rack_warden_app_class
|
27
|
+
|
28
|
+
# Sets framework module with variables from env (the scope of the parent app's initializer),
|
29
|
+
# and runs the framework selector logic.
|
30
|
+
# Returns the framework module or nil.
|
31
|
+
def framework_selector(env)
|
32
|
+
#puts "BASE.framework_selector #{self} env: #{env.eval 'self'} locals: #{env.eval 'local_variables'}"
|
33
|
+
@initialization_args = env.eval 'initialization_args'
|
34
|
+
@parent_app_instance = env.eval 'parent_app_instance'
|
35
|
+
@parent_app_class = @parent_app_instance.class
|
36
|
+
@rack_warden_app_instance = env.eval 'self'
|
37
|
+
@rack_warden_app_class = @rack_warden_app_instance.class
|
38
|
+
selector && self
|
39
|
+
end
|
40
|
+
|
41
|
+
# # Best guess at framework database settings.
|
42
|
+
# def get_database_config
|
43
|
+
# ActiveRecord::Base.connection_config rescue nil ||
|
44
|
+
# DataMapper.repository(:default).adapter[:options] rescue nil
|
45
|
+
# end
|
46
|
+
|
47
|
+
### End methods extended into framework module ###
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module RackWarden
|
2
|
+
module Frameworks
|
3
|
+
module Rails
|
4
|
+
|
5
|
+
extend Base
|
6
|
+
|
7
|
+
def selector
|
8
|
+
puts "RW Rails.selector"
|
9
|
+
parent_app_class.parents.find{|x| x.to_s=='ActionDispatch'}
|
10
|
+
end
|
11
|
+
|
12
|
+
def views_path
|
13
|
+
[File.join(Dir.pwd, "app/views/rack_warden"), File.join(Dir.pwd, "app/views")]
|
14
|
+
end
|
15
|
+
|
16
|
+
def setup_framework
|
17
|
+
puts "RW Rails.setup_framework parent_app_class #{parent_app_class}"
|
18
|
+
ApplicationController.send(:include, RackWarden::App::RackWardenHelpers)
|
19
|
+
|
20
|
+
# Define class method 'require_login' on framework controller.
|
21
|
+
#parent_app_class.instance_eval do #This seems to work too.
|
22
|
+
ApplicationController.instance_eval do
|
23
|
+
def self.require_login(*args)
|
24
|
+
before_filter(:require_login, *args) do
|
25
|
+
require_login
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
(ApplicationController.before_filter :require_login, *Array(rack_warden_app_class.require_login).flatten) if rack_warden_app_class.require_login != false
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module RackWarden
|
2
|
+
module Frameworks
|
3
|
+
module Sinatra
|
4
|
+
|
5
|
+
extend Base
|
6
|
+
|
7
|
+
def selector
|
8
|
+
puts "RW Sinatra.selector"
|
9
|
+
parent_app_class.ancestors.find{|x| x.to_s=='Sinatra::Base'}
|
10
|
+
end
|
11
|
+
|
12
|
+
def views_path
|
13
|
+
[File.join(Dir.pwd, "views/rack_warden"), File.join(Dir.pwd,"views")
|
14
|
+
end
|
15
|
+
|
16
|
+
def setup_framework
|
17
|
+
puts "RW Sinatra.setup_framework parent_app_class #{parent_app_class}"
|
18
|
+
parent_app_class.helpers(RackWarden::App::RackWardenHelpers)
|
19
|
+
|
20
|
+
# Define class method 'require_login' on framework controller.
|
21
|
+
parent_app_class.instance_eval do
|
22
|
+
def self.require_login(*args)
|
23
|
+
before(*args) do
|
24
|
+
require_login
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
parent_app_class.require_login(rack_warden_app_class.require_login) if rack_warden_app_class.require_login != false
|
29
|
+
end
|
30
|
+
|
31
|
+
end # Sinatra
|
32
|
+
end # Frameworks
|
33
|
+
end # RackWarden
|
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
module RackWarden
|
3
|
+
|
4
|
+
# Best guess at framework database settings.
|
5
|
+
def self.get_database_config
|
6
|
+
App.database_config ||
|
7
|
+
(App.database_config == false && "sqlite3:///#{Dir.pwd}/rack_warden.sqlite3.db") ||
|
8
|
+
(ActiveRecord::Base.connection_config rescue nil) ||
|
9
|
+
(DataMapper.repository(:default).adapter[:options] rescue nil) ||
|
10
|
+
"sqlite3:///#{Dir.pwd}/rack_warden.sqlite3.db"
|
11
|
+
end
|
12
|
+
|
13
|
+
puts "RW DataMapper using log_path #{App.log_path}"
|
14
|
+
DataMapper::Logger.new(App.log_path)
|
15
|
+
|
16
|
+
puts "RW get_database_config #{get_database_config}"
|
17
|
+
DataMapper.setup(:default, get_database_config)
|
18
|
+
# Do DataMapper.repository.adapter to get connection info for this connection.
|
19
|
+
|
20
|
+
puts "RW requiring model files in #{File.join(File.dirname(__FILE__), 'models/*')}"
|
21
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'models/*')).each {|f| puts f; require f}
|
22
|
+
|
23
|
+
puts "RW finalizing"
|
24
|
+
# Tell DataMapper the models are done being defined
|
25
|
+
DataMapper.finalize
|
26
|
+
|
27
|
+
puts "RW DataMapper.auto_upgrade!"
|
28
|
+
# Update the database to match the properties of User.
|
29
|
+
DataMapper.auto_upgrade!
|
30
|
+
|
31
|
+
puts "RW DataMapper repository #{DataMapper.repository.adapter.options}"
|
32
|
+
|
33
|
+
end # module
|
@@ -0,0 +1,37 @@
|
|
1
|
+
|
2
|
+
module RackWarden
|
3
|
+
|
4
|
+
class User
|
5
|
+
include DataMapper::Resource
|
6
|
+
include BCrypt
|
7
|
+
|
8
|
+
property :id, Serial, key: true
|
9
|
+
property :username, String, length: 128, unique: true, required: true, default: lambda {|r,v| r.instance_variable_get :@email}
|
10
|
+
property :email, String, length: 128, unique: true, required: true #, default: 'error'
|
11
|
+
|
12
|
+
property :password, BCryptHash
|
13
|
+
|
14
|
+
# before :valid?, :set_username
|
15
|
+
# before :save, :set_username
|
16
|
+
|
17
|
+
# def set_username
|
18
|
+
# puts "SETTING USERNAME"
|
19
|
+
# @username = @email unless @username
|
20
|
+
# end
|
21
|
+
|
22
|
+
def authenticate(attempted_password)
|
23
|
+
if self.password == attempted_password
|
24
|
+
true
|
25
|
+
else
|
26
|
+
false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# # Create a test User
|
32
|
+
# if User.count == 0
|
33
|
+
# @user = User.create(username: "admin")
|
34
|
+
# @user.password = "admin"
|
35
|
+
# @user.save
|
36
|
+
# end
|
37
|
+
end # module
|
data/lib/rack_warden/version.rb
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
<% @section_title = "RackWarden Admin" %>
|
2
|
-
<
|
3
|
-
<
|
4
|
-
<
|
5
|
-
<th>Email</th>
|
6
|
-
<th>User</th>
|
7
|
-
<th>Id</th>
|
8
|
-
</tr>
|
9
|
-
<tbody>
|
10
|
-
<% User.all(:limit=>100).each do |user| %>
|
2
|
+
<p>
|
3
|
+
<table>
|
4
|
+
<thead>
|
11
5
|
<tr>
|
12
|
-
<
|
13
|
-
<
|
14
|
-
<
|
6
|
+
<th>Email</th>
|
7
|
+
<th>User</th>
|
8
|
+
<th>Id</th>
|
15
9
|
</tr>
|
16
|
-
|
17
|
-
|
18
|
-
|
10
|
+
<tbody>
|
11
|
+
<% RackWarden::User.all(:limit=>100).each do |user| %>
|
12
|
+
<tr>
|
13
|
+
<td><%=user.email%></td>
|
14
|
+
<td><%=user.username%></td>
|
15
|
+
<td><%=user.id%></td>
|
16
|
+
</tr>
|
17
|
+
<% end %>
|
18
|
+
</tbody>
|
19
|
+
</table>
|
20
|
+
</p>
|
@@ -18,21 +18,25 @@
|
|
18
18
|
<p>
|
19
19
|
<a href="<%=url('/auth/login', false)%>">Log In</a> |
|
20
20
|
<a href="<%=url('/', false)%>">Home</a> |
|
21
|
-
<a href="<%=url('/auth/protected', false)%>">Protected Page</a> |
|
22
|
-
<a href="<%=url('/auth/
|
21
|
+
<a href="<%=url('/auth/protected', false)%>">Test Protected Page</a> |
|
22
|
+
<a href="<%=url('/auth/admin', false)%>">RackWarden Admin</a> |
|
23
|
+
<a href="<%=url('/auth/logout', false)%>">Log Out</a>
|
24
|
+
</p>
|
23
25
|
|
24
26
|
<% if flash(:rwarden)[:success] %>
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
<div style="color:green;">
|
28
|
+
<%= flash(:rwarden)[:success] %>
|
29
|
+
</div>
|
28
30
|
<% end %>
|
29
31
|
|
30
32
|
<% if flash(:rwarden)[:error] %>
|
31
|
-
|
32
|
-
|
33
|
-
|
33
|
+
<div style="color:red;">
|
34
|
+
<%= flash(:rwarden)[:error] %>
|
35
|
+
</div>
|
34
36
|
<% end %>
|
35
37
|
|
36
|
-
|
38
|
+
<div id="content">
|
39
|
+
<%= yield %>
|
40
|
+
</div>
|
37
41
|
</body>
|
38
42
|
</html>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<% @section_title = "Login" %>
|
2
2
|
<form action="<%=url('/auth/login', false)%>" method="post">
|
3
|
-
<p>Username
|
4
|
-
<p>Password
|
3
|
+
<p>Username or Email <input type="text" name="user[username]" /></p>
|
4
|
+
<p>Password <input type="password" name="user[password]" /></p>
|
5
5
|
<input type="submit" value="Log In" />
|
6
6
|
<% if settings.allow_public_signup %>
|
7
7
|
or <a href="<%=url('/auth/new', false)%>">Create a new account</a>
|
@@ -1,9 +1,9 @@
|
|
1
1
|
<% @section_title = "Create Account" %>
|
2
2
|
<form action="<%=url('/auth/create', false)%>" method="post">
|
3
|
-
<p>Email
|
4
|
-
<p>Username
|
5
|
-
<p>Password
|
6
|
-
<% if recaptcha_sitekey && User.count > 0 %>
|
3
|
+
<p>Email <input type="text" name="user[email]" /></p>
|
4
|
+
<p>Username <input type="text" name="user[username]" /></p>
|
5
|
+
<p>Password <input type="password" name="user[password]" /></p>
|
6
|
+
<% if recaptcha_sitekey && RackWarden::User.count > 0 %>
|
7
7
|
<div class="g-recaptcha control text-control" data-sitekey="<%=recaptcha_sitekey%>"></div>
|
8
8
|
<% end %>
|
9
9
|
<input type="submit" value="Create" />
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack_warden
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- William Richardson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -166,14 +166,18 @@ files:
|
|
166
166
|
- config.ru
|
167
167
|
- lib/rack_warden.rb
|
168
168
|
- lib/rack_warden/app.rb
|
169
|
-
- lib/rack_warden/
|
169
|
+
- lib/rack_warden/frameworks.rb
|
170
|
+
- lib/rack_warden/frameworks/rails.rb
|
171
|
+
- lib/rack_warden/frameworks/sinatra.rb
|
172
|
+
- lib/rack_warden/models.rb
|
173
|
+
- lib/rack_warden/models/user.rb
|
170
174
|
- lib/rack_warden/version.rb
|
171
|
-
- lib/rack_warden/views/create_user.html.erb
|
172
|
-
- lib/rack_warden/views/login_user.html.erb
|
173
|
-
- lib/rack_warden/views/rack_warden_index.html.erb
|
174
|
-
- lib/rack_warden/views/rack_warden_layout.html.erb
|
175
|
-
- lib/rack_warden/views/rack_warden_protected.html.erb
|
176
175
|
- lib/rack_warden/views/rw_admin.html.erb
|
176
|
+
- lib/rack_warden/views/rw_index.html.erb
|
177
|
+
- lib/rack_warden/views/rw_layout.html.erb
|
178
|
+
- lib/rack_warden/views/rw_login.html.erb
|
179
|
+
- lib/rack_warden/views/rw_new_user.html.erb
|
180
|
+
- lib/rack_warden/views/rw_protected.html.erb
|
177
181
|
- rack_warden.gemspec
|
178
182
|
homepage: ''
|
179
183
|
licenses:
|
data/lib/rack_warden/model.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
#require 'bcrypt'
|
2
|
-
DataMapper::Logger.new(File.join(Dir.pwd, 'log', 'rack_warden.log'))
|
3
|
-
DataMapper.setup(:default, RackWarden::App.database_config)
|
4
|
-
|
5
|
-
# Do DataMapper.repository.adapter to get connection info for this connection.
|
6
|
-
|
7
|
-
class User
|
8
|
-
include DataMapper::Resource
|
9
|
-
include BCrypt
|
10
|
-
|
11
|
-
property :id, Serial, key: true
|
12
|
-
property :username, String, length: 128, required: true, unique: true, default: lambda {|r,v| r.instance_variable_get :@email}
|
13
|
-
property :email, String, length: 128, required: true, unique: true, default: 'error'
|
14
|
-
|
15
|
-
property :password, BCryptHash
|
16
|
-
|
17
|
-
def authenticate(attempted_password)
|
18
|
-
if self.password == attempted_password
|
19
|
-
true
|
20
|
-
else
|
21
|
-
false
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
# Tell DataMapper the models are done being defined
|
27
|
-
DataMapper.finalize
|
28
|
-
|
29
|
-
# Update the database to match the properties of User.
|
30
|
-
DataMapper.auto_upgrade!
|
31
|
-
|
32
|
-
# # Create a test User
|
33
|
-
# if User.count == 0
|
34
|
-
# @user = User.create(username: "admin")
|
35
|
-
# @user.password = "admin"
|
36
|
-
# @user.save
|
37
|
-
# end
|
@@ -1 +0,0 @@
|
|
1
|
-
<h2>Warden authentication for any rack based app<h2>
|
@@ -1 +0,0 @@
|
|
1
|
-
<h2>Protected Page Example</h2>
|