rack_warden 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MzJhMzZlZDM3YTVkYjE4MDczZTM2ZjhlYmU0MTQ0NmYyMjVkMmY3Mg==
4
+ ZjdjY2YyZWIwODFiZWVhY2FiNGNiOTNjNGE3ZGRiYjI0OWFlNWExMA==
5
5
  data.tar.gz: !binary |-
6
- NzIwOGNlNTQzZDBkZjk4NTgwYTllOTM3MTJkMzM2Y2EyNWUzNmY0NA==
6
+ ZjFjZTkwOTFhNWY5NTRlOTQxODM1NmZjOTAyNDlkMGE2OTFlMTk4NA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZGFlMzk2OTNiYWU0OGJjYmUxNjAyN2U1MTU0Y2YzMTUyZGI0NDg1MTEzYjgz
10
- NGFkOGU1ZDk5YjcxOGI5MTNlMmNkMjc2Nzk4OWQzZGY2MjM5NzFkMjgyODcw
11
- MTI4OGU3YTQxMDI1OTNlYTAwN2Q1MTYwMTFiZDQyMTQ5MzRkODc=
9
+ ODRhZDRjZTMyNGNmYmRkZTdmYzIyYWM5NGU3ZjcwZjEwOTdhNzI5OWZiOTg4
10
+ ZDZmMDdhYjA4ZWJhYWYzNTE4ZDNkNWJlZDZhZjg4MzcyZmNjMzYzN2U0YzUx
11
+ N2YxNDQyZjhmMjIzOTU3NjEzOTNjZDIzYzhmYzcyYTE3Mzc0NDQ=
12
12
  data.tar.gz: !binary |-
13
- Yjk0MWUyMTBjZmMyNmEwNjZlNTAwZmM1M2Q2NmJkYjViNzllYTlhMGIwNDA2
14
- YTc1NzY0MGY0NDQ4YmExMDA1NzQyYTNiM2YxZDE4ZWJhMmE0MTU4OTg3MGEx
15
- MWI1MDE5ZjNkOGRjNTUyNjBmMzU0YThkY2JkNzgzMmM0ZDFjNzg=
13
+ ZDdlMjNiMmIzMjU3N2Q3MGU2ZGQzYWU2ODY2NDJjZjM5MmVlZDk3MGEwYjZl
14
+ Zjc1NDI4YTQ5YTEzOWY1YmQzNmM0NTdhOTZmNGZjOTUyOWE0M2YzNDFhODU5
15
+ MTFhNDM3ZGQ5YjRjZmJiMmNjZDE1MzM2YmQ0M2JlNzdiZjZjMzg=
data/.gitignore CHANGED
@@ -19,4 +19,4 @@ todo.txt
19
19
  *.bak
20
20
  *.gem
21
21
  rack_warden.y*ml
22
-
22
+ .DS_Store
data/README.md CHANGED
@@ -6,12 +6,20 @@ RackWarden uses Sinatra for the mini-app, Warden for authentication, and DataMap
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
+ ## What Does it Do?
10
+
11
+ 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
+
13
+ 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
+
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.
16
+
9
17
 
10
18
  ## Installation
11
19
 
12
20
  In your Gemfile:
13
21
 
14
- gem 'rack_warden'
22
+ gem 'rack_warden'
15
23
 
16
24
  Then:
17
25
 
@@ -28,88 +36,127 @@ A few simple steps will have your entire app protected.
28
36
 
29
37
  ### Sinatra
30
38
 
31
- class MySinatraApp < Sinatra::Base
32
- use RackWarden::App
33
-
34
- before do
35
- require_login
36
- end
37
-
38
- get "/" do
39
- erb "All routes are now protected"
40
- end
41
- end
39
+ class MySinatraApp < Sinatra::Base
40
+ use RackWarden::App
41
+
42
+ get "/" do
43
+ erb "All routes are now protected"
44
+ end
45
+ end
42
46
 
43
47
  ### Rails
44
48
 
45
49
  application.rb or environment.rb
46
50
 
47
- config.middleware.use RackWarden::App
48
-
49
- application-controller.rb
50
-
51
- before_filter :require_login
52
-
51
+ config.middleware.use RackWarden::App
52
+
53
+ # All routes are now protected
54
+
53
55
 
54
56
 
55
57
  ## Configuration
56
58
 
57
- Pass configuration settings to RackWarden through your ``use`` method. The params hash will be translated directly to the app's settings. You can currently specify :layout, :database, :default_route, and :recaptcha. You can also specify any of the standard Sinatra settings, like :views.
59
+ 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 settings that Sinatra recognizes.
58
60
 
59
- 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 two relevant objects.
61
+ 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.
60
62
 
61
- use RackWarden::App do |rack_warden_app_instance, parent_app_instance|
62
- set :somesetting, 'some_value'
63
- end
63
+ use RackWarden::App do |rack_warden_app_instance, parent_app_instance|
64
+ set :somesetting, 'some_value'
65
+ end
64
66
 
65
67
  ### Configuration Options
66
68
 
67
- Current list of settings specific to rack_warden, with defaults.
69
+ Current list of settings specific to rack\_warden, with defaults.
68
70
 
69
71
  #### :layout
70
72
 
71
73
  A symbol representing a layout file in any of the view paths.
72
-
73
- :layout => :'rack_warden_layout.html'
74
-
75
- #### :default_route
74
+
75
+ layout: :'rack_warden_layout.html'
76
+
77
+ #### :default\_route
76
78
 
77
79
  A Sinatra route to fall back on after logout, errors, or any action that has no specified route.
78
80
 
79
- :default_route => '/'
80
-
81
- #### :database
82
-
83
- A DataMapper database specification
84
-
85
- :database => "sqlite:///Absolute/path/to/your/project/rack_warden.sqlite.db"
86
-
81
+ default_route: '/'
82
+
83
+ #### :database\_config
84
+
85
+ A database specification hash or or url string.
86
+
87
+ database_config: "sqlite:///Absolute/path/to/your/rack_warden.sqlite3.db"
88
+
89
+ # or
90
+
91
+ database_config:
92
+ adapter: mysql2
93
+ encoding: utf8
94
+ database: my_db_name
95
+ username: root
96
+ password: my_password
97
+ host: 127.0.0.1
98
+ port: 3306
99
+
100
+ #### :require\_login
101
+
102
+ Parameters to pass to the before/before\_filter for require\_login.
103
+ So if you're main app is Sinatra,
104
+
105
+ require_login: /^\/.+/
106
+
107
+ is the same as
108
+
109
+ class MySinatraApp
110
+ require_login /^\/.+/
111
+ end
112
+
113
+ which is the same as
114
+
115
+ class MySinatraApp
116
+ before /^\/.+/ do
117
+ require_login
118
+ end
119
+ end
120
+
121
+ For Rails, you would be passing a hash of :only or :except keys.
122
+
123
+ require_login:
124
+ except: :index
125
+
126
+ 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 ``false``.
128
+
129
+ #### :allow\_public\_signup
130
+
131
+ Allows public access to the account creation view & action.
132
+
133
+ allow_public_signup: false
134
+
135
+
87
136
  #### :recaptcha
88
137
 
89
138
  Settings for Google's recaptcha service
90
139
 
91
- :recaptcha => {
92
- :sitekey => '',
93
- :secret => ''
94
- }
140
+ :recaptcha => {
141
+ :sitekey => '',
142
+ :secret => ''
143
+ }
95
144
 
96
145
  ## Customization
97
146
 
98
147
  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.
99
148
 
100
- use RackWarden::App, :views => File.join(Dir.pwd, 'app/views/rack_warden')
101
-
149
+ use RackWarden::App, :views => File.join(Dir.pwd, 'app/views/rack_warden')
150
+
102
151
  Or if you simply want RackWarden to use your own custom layout, pass it a file path in the :layout parameter.
103
152
 
104
- use RackWarden::App, :layout => :'layouts/rack_warden_layout.html'
105
-
106
- 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.
107
-
108
- Another way to customize RackWarden is to override its classes and methods, as you would with any other ruby code.
153
+ use RackWarden::App, :layout => :'layouts/rack_warden_layout.html'
154
+
155
+ 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.
109
156
 
110
- 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.
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.
111
158
 
112
- gem 'rack_warden', :path => "../RackWarden/"
159
+ gem 'rack_warden', :path => "../RackWarden/"
113
160
 
114
161
 
115
162
 
@@ -8,8 +8,10 @@ module RackWarden
8
8
  set :config_files, [ENV['RACK_WARDEN_CONFIG_FILE'], 'rack_warden.yml', 'config/rack_warden.yml'].compact.uniq
9
9
  set :layout, :'rack_warden_layout.html'
10
10
  set :default_route, '/'
11
- set :database, "sqlite://#{Dir.pwd}/rack_warden.sqlite.db"
11
+ set :database_config, "sqlite3:///#{Dir.pwd}/rack_warden.sqlite3.db"
12
12
  set :recaptcha, Hash.new
13
+ set :require_login, nil
14
+ set :allow_public_signup, false
13
15
 
14
16
  # Load config from file, if any exist.
15
17
  Hash.new.tap do |hash|
@@ -29,7 +31,7 @@ module RackWarden
29
31
  # end
30
32
  #
31
33
  def initialize(parent_app=nil, *args, &block)
32
- #puts "INITIALIZE RackWarden::App INSTANCE [parent_app, self, args, block]: #{[parent_app, self, args, block]}"
34
+ puts "INITIALIZE RackWarden::App INSTANCE [parent_app, self, args, block]: #{[parent_app, self, args, block]}"
33
35
  # extract options.
34
36
  opts = args.last.is_a?(Hash) ? args.pop : {}
35
37
  klass = self.class
@@ -58,9 +60,29 @@ module RackWarden
58
60
  when parent_app.class.ancestors.find{|x| x.to_s=='Sinatra::Base'}
59
61
  parent_app.class.helpers(RackWardenHelpers)
60
62
  default_parent_views = File.join(Dir.pwd,"views")
63
+
64
+ parent_app.class.instance_eval do
65
+ def self.require_login(*args)
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
61
73
  when parent_app.class.parents.find{|x| x.to_s=='ActionDispatch'}
62
74
  ApplicationController.send(:include, RackWardenHelpers)
63
75
  default_parent_views = File.join(Dir.pwd, "app/views")
76
+
77
+ parent_app.class.instance_eval do
78
+ def self.require_login(*args)
79
+ #options = args.last.is_a?(Hash) ? args.pop : Hash.new
80
+ before_filter(:require_login, *args) do
81
+ require_login
82
+ end
83
+ end
84
+ end
85
+ (ApplicationController.before_filter :require_login, *Array(klass.require_login).flatten) if klass.require_login != false
64
86
  end
65
87
 
66
88
  new_views = []
@@ -149,7 +171,7 @@ module RackWarden
149
171
  # TODO: Shouldn't these be in warden block above? But they don't work there for some reason.
150
172
 
151
173
  def valid_user_input?
152
- params['user'] && params['user']['username'] && params['user']['password']
174
+ params['user'] && params['user']['email'] && params['user']['password']
153
175
  end
154
176
 
155
177
  def create_user
@@ -157,9 +179,10 @@ module RackWarden
157
179
  verify_recaptcha if settings.recaptcha[:secret]
158
180
 
159
181
  return unless valid_user_input?
160
- user = User.create(username: params['user']['username'])
161
- user.password = params['user']['password']
162
- user.save && warden.set_user(user)
182
+ #user = User.create(username: params['user']['username'])
183
+ @user = User.new(params['user'])
184
+ #user.password = params['user']['password']
185
+ @user.save && warden.set_user(@user)
163
186
  end
164
187
 
165
188
  def verify_recaptcha(skip_redirect=false, ip=request.ip, response=params['g-recaptcha-response'])
@@ -214,8 +237,9 @@ module RackWarden
214
237
  redirect url(settings.default_route, false)
215
238
  end
216
239
 
217
- get '/auth/create' do
218
- erb :'create_user.html', :layout=>settings.layout, :locals=>{:recaptcha_sitekey=>settings.recaptcha[:sitekey]}
240
+ get '/auth/new' do
241
+ halt 403 unless settings.allow_public_signup or !(User.count > 0)
242
+ erb :'create_user.html', :layout=>settings.layout, :locals=>{:recaptcha_sitekey=>settings.recaptcha['sitekey']}
219
243
  end
220
244
 
221
245
  post '/auth/create' do
@@ -224,7 +248,7 @@ module RackWarden
224
248
  redirect session[:return_to] || url(settings.default_route, false)
225
249
  else
226
250
  flash(:rwarden)[:error] = warden.message || "Could not create account"
227
- redirect url('/auth/create', false)
251
+ redirect back #url('/auth/new', false)
228
252
  end
229
253
  end
230
254
 
@@ -233,8 +257,13 @@ module RackWarden
233
257
  session[:return_to] = env['warden.options'][:attempted_path] if !request.xhr? && !env['warden.options'][:attempted_path][/login/]
234
258
  puts "WARDEN ATTEMPTED PATH: #{env['warden.options'][:attempted_path]}"
235
259
  puts warden
236
- flash(:rwarden)[:error] = warden.message || "Please login to continue"
237
- redirect url('/auth/login', false)
260
+ if User.count > 0
261
+ flash(:rwarden)[:error] = warden.message || "Please login to continue"
262
+ redirect url('/auth/login', false)
263
+ else
264
+ flash(:rwarden)[:error] = warden.message || "Please create an admin account"
265
+ redirect url('/auth/new', false)
266
+ end
238
267
  end
239
268
 
240
269
  get '/auth/protected' do
@@ -242,6 +271,11 @@ module RackWarden
242
271
 
243
272
  erb :'rack_warden_protected.html', :layout=>settings.layout
244
273
  end
274
+
275
+ get '/auth/admin' do
276
+ warden.authenticate!
277
+ erb :'rw_admin.html', :layout=>settings.layout
278
+ end
245
279
 
246
280
  end # App
247
281
  end # RackWarden
@@ -1,12 +1,16 @@
1
1
  #require 'bcrypt'
2
- DataMapper.setup(:default, RackWarden::App.database)
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.
3
6
 
4
7
  class User
5
8
  include DataMapper::Resource
6
9
  include BCrypt
7
10
 
8
11
  property :id, Serial, key: true
9
- property :username, String, length: 128
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'
10
14
 
11
15
  property :password, BCryptHash
12
16
 
@@ -1,3 +1,3 @@
1
1
  module RackWarden
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -1,9 +1,11 @@
1
1
  <% @section_title = "Create Account" %>
2
2
  <form action="<%=url('/auth/create', false)%>" method="post">
3
+ <p>Email: <input type="text" name="user[email]" /></p>
3
4
  <p>Username: <input type="text" name="user[username]" /></p>
4
5
  <p>Password: <input type="password" name="user[password]" /></p>
5
- <% if recaptcha_sitekey %>
6
+ <% if recaptcha_sitekey && User.count > 0 %>
6
7
  <div class="g-recaptcha control text-control" data-sitekey="<%=recaptcha_sitekey%>"></div>
7
8
  <% end %>
8
9
  <input type="submit" value="Create" />
10
+ <p><%= @user.errors.to_yaml if @user && @user.errors %></p>
9
11
  </form>
@@ -2,5 +2,8 @@
2
2
  <form action="<%=url('/auth/login', false)%>" method="post">
3
3
  <p>Username: <input type="text" name="user[username]" /></p>
4
4
  <p>Password: <input type="password" name="user[password]" /></p>
5
- <input type="submit" value="Log In" /> or <a href="<%=url('/auth/create', false)%>">Create a new account</a>
5
+ <input type="submit" value="Log In" />
6
+ <% if settings.allow_public_signup %>
7
+ or <a href="<%=url('/auth/new', false)%>">Create a new account</a>
8
+ <% end %>
6
9
  </form>
@@ -0,0 +1,18 @@
1
+ <% @section_title = "RackWarden Admin" %>
2
+ <table>
3
+ <thead>
4
+ <tr>
5
+ <th>Email</th>
6
+ <th>User</th>
7
+ <th>Id</th>
8
+ </tr>
9
+ <tbody>
10
+ <% User.all(:limit=>100).each do |user| %>
11
+ <tr>
12
+ <td><%=user.email%></td>
13
+ <td><%=user.username%></td>
14
+ <td><%=user.id%></td>
15
+ </tr>
16
+ <% end %>
17
+ </tbody>
18
+ </table>
data/lib/rack_warden.rb CHANGED
@@ -10,8 +10,9 @@ require 'open-uri'
10
10
  # gem 'warden'
11
11
 
12
12
  require "rack_warden/app"
13
- require "rack_warden/model"
14
13
  require "rack_warden/version"
14
+ autoload :User, "rack_warden/model"
15
+
15
16
 
16
17
  module RackWarden
17
18
  # Your code goes here...
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
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Richardson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-29 00:00:00.000000000 Z
11
+ date: 2014-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -173,6 +173,7 @@ files:
173
173
  - lib/rack_warden/views/rack_warden_index.html.erb
174
174
  - lib/rack_warden/views/rack_warden_layout.html.erb
175
175
  - lib/rack_warden/views/rack_warden_protected.html.erb
176
+ - lib/rack_warden/views/rw_admin.html.erb
176
177
  - rack_warden.gemspec
177
178
  homepage: ''
178
179
  licenses: