devise_revokable 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ .bundle
2
+ .document
3
+ *.swp
4
+ pkg
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
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,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -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,3 @@
1
+ <p>Hello <%= @resource.email %>!</p>
2
+
3
+ <p>Your account at <%= root_url %> has been deactivated.</p>
@@ -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,5 @@
1
+ %h2
2
+ = t(:revoke_confirmed_header, :scope => :"devise.revocations")
3
+
4
+ .instructions
5
+ = t(:revoke_confirmed_instructions, :scope => :"devise.revocations")
@@ -0,0 +1,4 @@
1
+ - if resource.errors.any? || !resource.revoked?
2
+ = render 'confirm_revoke'
3
+ - else
4
+ = render 'revoke_confirmed'
@@ -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
@@ -0,0 +1,10 @@
1
+ module DeviseRevokable
2
+ module Schema
3
+ def revokable
4
+ apply_devise_schema :revocation_token, String, :limit => 60
5
+ apply_devise_schema :revoked_at, DateTime
6
+ end
7
+ end
8
+ end
9
+
10
+ Devise::Schema.send :include, DeviseRevokable::Schema
@@ -0,0 +1,3 @@
1
+ module DeviseRevokable
2
+ VERSION = '0.0.2'
3
+ 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
+