devise_revokable 0.0.2
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/.gitignore +4 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.rdoc +43 -0
- data/Rakefile +2 -0
- data/app/controllers/devise/revocations_controller.rb +34 -0
- data/app/views/devise/mailer/revocation_confirmation.html.erb +3 -0
- data/app/views/devise/mailer/revocation_instructions.html.erb +7 -0
- data/app/views/devise/revocations/_confirm_revoke.html.haml +11 -0
- data/app/views/devise/revocations/_revoke_confirmed.html.haml +5 -0
- data/app/views/devise/revocations/edit.html.haml +4 -0
- data/config/locales/en.yml +10 -0
- data/devise_revokable.gemspec +22 -0
- data/lib/devise_revokable.rb +37 -0
- data/lib/devise_revokable/controllers/url_helpers.rb +24 -0
- data/lib/devise_revokable/mailer.rb +13 -0
- data/lib/devise_revokable/model.rb +87 -0
- data/lib/devise_revokable/routes.rb +10 -0
- data/lib/devise_revokable/schema.rb +10 -0
- data/lib/devise_revokable/version.rb +3 -0
- metadata +156 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 e9digital
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
== Devise::Revokable
|
2
|
+
|
3
|
+
A module for Devise[http://github.com/plataformatec/devise]
|
4
|
+
|
5
|
+
This gem was created by "borrowing" heavily from Devise::Invitable[http://github.com/scambra/devise_invitable]
|
6
|
+
|
7
|
+
It exists to extend Devise to provide the basis for what is essentially the reverse of the standard
|
8
|
+
<tt>confirmable</tt> module. Where <tt>confirmable</tt> sends an email and awaits a response,
|
9
|
+
before confirming a new registration, <tt>revokable</tt> allows immediate access and sends an
|
10
|
+
email which provides a link to "revoke" the account if it was created fraudulently.
|
11
|
+
|
12
|
+
This is useful if you want to lower the barrier to entry to creating accounts, and clearly, if
|
13
|
+
account security isn't a concern.
|
14
|
+
|
15
|
+
Note that tests are non-existent. Use freely but at your own risk.
|
16
|
+
|
17
|
+
=== Configuring
|
18
|
+
|
19
|
+
It works like normal Devise modules. Add the <tt>:revokable</tt> module to the declaration.
|
20
|
+
|
21
|
+
# in user.rb
|
22
|
+
devise :revokable # plus other devise modules
|
23
|
+
|
24
|
+
Additionally, you will need to override <tt>#revoke!</tt> to actually perfom the revocation on your account, which
|
25
|
+
is yielded to from the module's method.
|
26
|
+
|
27
|
+
# in user.rb
|
28
|
+
def revoke!
|
29
|
+
super do
|
30
|
+
self.some_method_that_resets_me!
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
That's about the extent of it. As with typical devise modules you can override the mailers and views with your own.
|
35
|
+
Additionally you can define the module accessor <tt>@@mailer</tt> on the module with a proc to handle your mail if you need to.
|
36
|
+
This proc is yielded two arguments, the method name (e.g. :revocation_instructions), and the affected resource.
|
37
|
+
|
38
|
+
|
39
|
+
# in config/initializers/devise_revocation.rb
|
40
|
+
require 'devise_revocation'
|
41
|
+
require 'my_mailer'
|
42
|
+
|
43
|
+
DeviseRevocation.mailer = proc {|method_name, resource| MyMailer.send(:method_name, resource) }
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
class Devise::RevocationsController < ApplicationController
|
2
|
+
include Devise::Controllers::InternalHelpers
|
3
|
+
|
4
|
+
# GET /resource/revocation/confirm?revocation_token=abcdef
|
5
|
+
def edit
|
6
|
+
if params[:revocation_token] && self.resource = resource_class.find_by_revocation_token(params[:revocation_token])
|
7
|
+
render_with_scope :edit
|
8
|
+
else
|
9
|
+
set_error_and_redirect
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# PUT /resource/revocation
|
14
|
+
def update
|
15
|
+
token = params[resource_name].try(:[], :revocation_token)
|
16
|
+
|
17
|
+
self.resource = resource_class.revoke_by_token(token)
|
18
|
+
|
19
|
+
if resource.errors.empty?
|
20
|
+
set_flash_message :notice, :updated
|
21
|
+
sign_out(self.resource)
|
22
|
+
render_with_scope :edit
|
23
|
+
else
|
24
|
+
set_error_and_redirect
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
|
30
|
+
def set_error_and_redirect
|
31
|
+
set_flash_message(:alert, :revocation_token_invalid)
|
32
|
+
redirect_to after_sign_out_path_for(resource_name)
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<p>Hello <%= @resource.email %>!</p>
|
2
|
+
|
3
|
+
<p>You (or someone pretending to be you) has created an account at <%= root_url %>.</p>
|
4
|
+
|
5
|
+
<p>If you chose to sign up with us, please disregard this email!</p>
|
6
|
+
|
7
|
+
<p>However if this is not you, <%= link_to 'click here', confirm_revocation_url(@resource, :revocation_token => @resource.revocation_token) %> to take action.</p>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
%h2
|
2
|
+
= t(:confirm_revoke_header, :scope => :"devise.revocations")
|
3
|
+
|
4
|
+
= form_for resource, :as => resource_name, :url => revocation_path(resource_class), :html => { :method => :put } do |f|
|
5
|
+
= f.hidden_field :revocation_token
|
6
|
+
|
7
|
+
.instructions
|
8
|
+
= t(:confirm_revoke_instructions, :scope => :"devise.revocations")
|
9
|
+
|
10
|
+
.actions
|
11
|
+
= f.submit t(:confirm_revoke_submit, :scope => :"devise.revocations")
|
@@ -0,0 +1,10 @@
|
|
1
|
+
en:
|
2
|
+
devise:
|
3
|
+
revocations:
|
4
|
+
updated: 'Your account was reset successfully.'
|
5
|
+
revocation_token_invalid: 'The token provided is not valid, or this account has already been revoked!'
|
6
|
+
revoke_confirmed_header: 'Account Reset Successfully'
|
7
|
+
revoke_confirmed_instructions: "This account has been reset successfully."
|
8
|
+
confirm_revoke_header: 'Are You Sure?'
|
9
|
+
confirm_revoke_instructions: "If you submit this form your account and its credentials will be reset. Any activity that has taken place on this account will be lost."
|
10
|
+
confirm_revoke_submit: 'Reset this account!'
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
3
|
+
require 'devise_revokable/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "devise_revokable"
|
7
|
+
s.version = DeviseRevokable::VERSION.dup
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Travis Cox"]
|
10
|
+
s.email = "travis@e9digital.com"
|
11
|
+
s.homepage = "https://github.com/e9digital/devise_revokable"
|
12
|
+
s.summary = "A revocation strategy for Devise"
|
13
|
+
s.description = File.open('README.rdoc').read rescue ''
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_runtime_dependency('rails', '~> 3.0.0')
|
21
|
+
s.add_runtime_dependency('devise', '~> 1.1.5')
|
22
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'devise'
|
3
|
+
require 'devise_revokable/routes'
|
4
|
+
require 'devise_revokable/schema'
|
5
|
+
require 'devise_revokable/mailer'
|
6
|
+
require 'devise_revokable/controllers/url_helpers'
|
7
|
+
|
8
|
+
module DeviseRevokable
|
9
|
+
autoload :VERSION, 'devise_revokable/version'
|
10
|
+
|
11
|
+
##
|
12
|
+
# Allow for another mailer besides Devise
|
13
|
+
#
|
14
|
+
mattr_accessor :mailer
|
15
|
+
@@mailer = nil
|
16
|
+
|
17
|
+
def self.send_mail!(method_name, resource)
|
18
|
+
if @@mailer.respond_to?(:call)
|
19
|
+
@@mailer.call(method_name, resource)
|
20
|
+
else
|
21
|
+
::Devise.mailer.send(method_name, resource).deliver
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Engine < ::Rails::Engine
|
26
|
+
[:action_controller, :action_view].each do |klass|
|
27
|
+
ActiveSupport.on_load(klass) { include DeviseRevokable::Controllers::UrlHelpers }
|
28
|
+
end
|
29
|
+
|
30
|
+
config.after_initialize do
|
31
|
+
require 'devise/mailer'
|
32
|
+
::Devise::Mailer.send :include, DeviseRevokable::Mailer
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
Devise.add_module :revokable, :controller => :revocations, :model => 'devise_revokable/model', :route => :revocation
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module DeviseRevokable
|
2
|
+
module Controllers
|
3
|
+
module UrlHelpers
|
4
|
+
[:path, :url].each do |path_or_url|
|
5
|
+
[nil, :confirm_].each do |action|
|
6
|
+
class_eval <<-URL_HELPERS, __FILE__, __LINE__ + 1
|
7
|
+
def #{action}revocation_#{path_or_url}(resource, *args)
|
8
|
+
resource = case resource
|
9
|
+
when Symbol, String
|
10
|
+
resource
|
11
|
+
when Class
|
12
|
+
resource.name.underscore
|
13
|
+
else
|
14
|
+
resource.class.name.underscore
|
15
|
+
end
|
16
|
+
|
17
|
+
send("#{action}\#{resource}_revocation_#{path_or_url}", *args)
|
18
|
+
end
|
19
|
+
URL_HELPERS
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module DeviseRevokable
|
2
|
+
module Mailer
|
3
|
+
|
4
|
+
# Deliver an invitation email
|
5
|
+
def revocation_instructions(resource)
|
6
|
+
setup_mail(resource, :revocation_instructions)
|
7
|
+
end
|
8
|
+
|
9
|
+
def revocation_confirmation(resource)
|
10
|
+
setup_mail(resource, :revocation_confirmation)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Devise
|
2
|
+
module Models
|
3
|
+
module Revokable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
after_create :send_revocation_instructions
|
8
|
+
end
|
9
|
+
|
10
|
+
def revoke!
|
11
|
+
unless_revoked do
|
12
|
+
self.revocation_token = nil
|
13
|
+
self.revoked_at = Time.now.utc
|
14
|
+
|
15
|
+
# NOTE use this yield to perform any reset necessary on the
|
16
|
+
# account, e.g. reset password, change username, delete content posted
|
17
|
+
yield if block_given?
|
18
|
+
|
19
|
+
send_revocation_confirmation
|
20
|
+
|
21
|
+
save(:validate => false)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def revoked?
|
26
|
+
!!revoked_at
|
27
|
+
end
|
28
|
+
|
29
|
+
def active?
|
30
|
+
not revoked?
|
31
|
+
end
|
32
|
+
|
33
|
+
def inactive_message
|
34
|
+
super
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
|
39
|
+
def send_revocation_instructions
|
40
|
+
unless_revoked do
|
41
|
+
generate_revocation_token! if self.revocation_token.nil?
|
42
|
+
DeviseRevokable.send_mail!(:revocation_instructions, self)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def send_revocation_confirmation
|
47
|
+
DeviseRevokable.send_mail!(:revocation_confirmation, self)
|
48
|
+
end
|
49
|
+
|
50
|
+
def unless_revoked
|
51
|
+
unless revoked?
|
52
|
+
yield
|
53
|
+
else
|
54
|
+
self.errors.add(:email, :already_revoked)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def generate_revocation_token!
|
59
|
+
generate_revocation_token && save(:validate => false)
|
60
|
+
end
|
61
|
+
|
62
|
+
def generate_revocation_token
|
63
|
+
self.revoked_at = nil
|
64
|
+
self.revocation_token = self.class.revocation_token
|
65
|
+
end
|
66
|
+
|
67
|
+
module ClassMethods
|
68
|
+
def send_revocation_instructions(attributes = {})
|
69
|
+
return unless active?
|
70
|
+
revokable = find_or_initialize_with_error_by(:email, attributes[:email], :not_found)
|
71
|
+
revokable.send(:send_revocation_instructions) if revokable.persisted?
|
72
|
+
revokable
|
73
|
+
end
|
74
|
+
|
75
|
+
def revoke_by_token(token)
|
76
|
+
revokable = find_or_initialize_with_error_by(:revocation_token, token, :revocation_token_invalid)
|
77
|
+
revokable.revoke! if revokable.persisted?
|
78
|
+
revokable
|
79
|
+
end
|
80
|
+
|
81
|
+
def revocation_token
|
82
|
+
generate_token(:revocation_token)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module ActionDispatch::Routing
|
2
|
+
class Mapper
|
3
|
+
protected
|
4
|
+
def devise_revocation(mapping, controllers)
|
5
|
+
resource :revocation, :only => :update, :path => mapping.path_names[:revocation], :controller => controllers[:revocations] do
|
6
|
+
get :edit, :path => mapping.path_names[:confirm], :as => :confirm
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
metadata
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: devise_revokable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Travis Cox
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-03-18 00:00:00 -04:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rails
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 3
|
30
|
+
- 0
|
31
|
+
- 0
|
32
|
+
version: 3.0.0
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: devise
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 1
|
45
|
+
- 1
|
46
|
+
- 5
|
47
|
+
version: 1.1.5
|
48
|
+
type: :runtime
|
49
|
+
version_requirements: *id002
|
50
|
+
description: |
|
51
|
+
== Devise::Revokable
|
52
|
+
|
53
|
+
A module for Devise[http://github.com/plataformatec/devise]
|
54
|
+
|
55
|
+
This gem was created by "borrowing" heavily from Devise::Invitable[http://github.com/scambra/devise_invitable]
|
56
|
+
|
57
|
+
It exists to extend Devise to provide the basis for what is essentially the reverse of the standard
|
58
|
+
<tt>confirmable</tt> module. Where <tt>confirmable</tt> sends an email and awaits a response,
|
59
|
+
before confirming a new registration, <tt>revokable</tt> allows immediate access and sends an
|
60
|
+
email which provides a link to "revoke" the account if it was created fraudulently.
|
61
|
+
|
62
|
+
This is useful if you want to lower the barrier to entry to creating accounts, and clearly, if
|
63
|
+
account security isn't a concern.
|
64
|
+
|
65
|
+
Note that tests are non-existent. Use freely but at your own risk.
|
66
|
+
|
67
|
+
=== Configuring
|
68
|
+
|
69
|
+
It works like normal Devise modules. Add the <tt>:revokable</tt> module to the declaration.
|
70
|
+
|
71
|
+
# in user.rb
|
72
|
+
devise :revokable # plus other devise modules
|
73
|
+
|
74
|
+
Additionally, you will need to override <tt>#revoke!</tt> to actually perfom the revocation on your account, which
|
75
|
+
is yielded to from the module's method.
|
76
|
+
|
77
|
+
# in user.rb
|
78
|
+
def revoke!
|
79
|
+
super do
|
80
|
+
self.some_method_that_resets_me!
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
That's about the extent of it. As with typical devise modules you can override the mailers and views with your own.
|
85
|
+
Additionally you can define the module accessor <tt>@@mailer</tt> on the module with a proc to handle your mail if you need to.
|
86
|
+
This proc is yielded two arguments, the method name (e.g. :revocation_instructions), and the affected resource.
|
87
|
+
|
88
|
+
|
89
|
+
# in config/initializers/devise_revocation.rb
|
90
|
+
require 'devise_revocation'
|
91
|
+
require 'my_mailer'
|
92
|
+
|
93
|
+
DeviseRevocation.mailer = proc {|method_name, resource| MyMailer.send(:method_name, resource) }
|
94
|
+
|
95
|
+
email: travis@e9digital.com
|
96
|
+
executables: []
|
97
|
+
|
98
|
+
extensions: []
|
99
|
+
|
100
|
+
extra_rdoc_files: []
|
101
|
+
|
102
|
+
files:
|
103
|
+
- .gitignore
|
104
|
+
- Gemfile
|
105
|
+
- LICENSE
|
106
|
+
- README.rdoc
|
107
|
+
- Rakefile
|
108
|
+
- app/controllers/devise/revocations_controller.rb
|
109
|
+
- app/views/devise/mailer/revocation_confirmation.html.erb
|
110
|
+
- app/views/devise/mailer/revocation_instructions.html.erb
|
111
|
+
- app/views/devise/revocations/_confirm_revoke.html.haml
|
112
|
+
- app/views/devise/revocations/_revoke_confirmed.html.haml
|
113
|
+
- app/views/devise/revocations/edit.html.haml
|
114
|
+
- config/locales/en.yml
|
115
|
+
- devise_revokable.gemspec
|
116
|
+
- lib/devise_revokable.rb
|
117
|
+
- lib/devise_revokable/controllers/url_helpers.rb
|
118
|
+
- lib/devise_revokable/mailer.rb
|
119
|
+
- lib/devise_revokable/model.rb
|
120
|
+
- lib/devise_revokable/routes.rb
|
121
|
+
- lib/devise_revokable/schema.rb
|
122
|
+
- lib/devise_revokable/version.rb
|
123
|
+
has_rdoc: true
|
124
|
+
homepage: https://github.com/e9digital/devise_revokable
|
125
|
+
licenses: []
|
126
|
+
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
|
130
|
+
require_paths:
|
131
|
+
- lib
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
133
|
+
none: false
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
segments:
|
138
|
+
- 0
|
139
|
+
version: "0"
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
|
+
none: false
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
segments:
|
146
|
+
- 0
|
147
|
+
version: "0"
|
148
|
+
requirements: []
|
149
|
+
|
150
|
+
rubyforge_project:
|
151
|
+
rubygems_version: 1.3.7
|
152
|
+
signing_key:
|
153
|
+
specification_version: 3
|
154
|
+
summary: A revocation strategy for Devise
|
155
|
+
test_files: []
|
156
|
+
|