devise_autosigninable 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ devise_autosigninable/.idea/.name
2
+ devise_autosigninable/.idea/devise_autosigninable.iml
3
+ devise_autosigninable/.idea/encodings.xml
4
+ devise_autosigninable/.idea/misc.xml
5
+ devise_autosigninable/.idea/modules.xml
6
+ devise_autosigninable/.idea/vcs.xml
7
+ devise_autosigninable/.idea/workspace.xml
8
+ test/rails2/.idea/.generators
9
+ test/rails2/.idea/.name
10
+ test/rails2/.idea/.rakeTasks
11
+ test/rails2/.idea/dataSources.ids
12
+ test/rails2/.idea/dataSources.xml
13
+ test/rails2/.idea/encodings.xml
14
+ test/rails2/.idea/misc.xml
15
+ test/rails2/.idea/modules.xml
16
+ test/rails2/.idea/rails_app.iml
17
+ test/rails2/.idea/vcs.xml
18
+ test/rails2/.idea/workspace.xml
data/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "test/rails2/vendor/plugins/devise_autosigninable"]
2
+ path = test/rails2/vendor/plugins/devise_autosigninable
3
+ url = git@github.com:aderyabin/devise_autosigninable.git
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 [name of plugin creator]
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.md ADDED
@@ -0,0 +1,78 @@
1
+ Devise Autosigninable
2
+ =============
3
+ Devise Autosigninable adds functionality of auto sign in to your [devise][1] app.
4
+ Devise Autosigninable is compatibile with all default Devise modules.
5
+ If Lockable module is activated Devise Autosigninable uses Lockable functionality for failed attempts.
6
+ If user is blocked or not confirmed he can't sign in with Devise Autosigninable too.
7
+
8
+ Devise Autosigninable signs in a user based on an autosignin token (random hash with length 32).
9
+ If signed in user try to sign in with Devise Autosigninable he will be sign out firstly and than go to sign in.
10
+ So if token is incorrect user will be signed out anyway.
11
+
12
+ Devise Autosigninable compatible with Rails 2 and Rails 3.
13
+
14
+ Installation
15
+ -----------
16
+ * Add devise_autosigninable to Gemfile:
17
+
18
+ `gem 'devise_autosigninable', '1.0.0'`
19
+
20
+ * Add :autosigninable to your Devise modules in model, for example:
21
+
22
+ `devise :registerable, :authenticatable, :recoverable, :rememberable, :trackable, :validatable, :lockable, :autosigninable`
23
+
24
+ * Generate migration for autosigninable. It creates neccessary fields and fill already existed records.
25
+
26
+ `rails g devise_autosigninable MODEL`
27
+
28
+ Replace MODEL by the class name you want to add devise, like User, Admin, etc
29
+
30
+ * Run rake command for generation autosignin tokens
31
+
32
+ `rake devise:autosigninable:ensure[MODEL]`
33
+
34
+ Route and Helpers
35
+ -----------
36
+ Devise Autosigninable has two methods which help to generate url and link to auto sign in
37
+
38
+ auto_signin_url_for(object)
39
+
40
+ and
41
+
42
+ link_to_autosignin(object, title, options)
43
+
44
+
45
+ By default Devise Autosigninable uses `'/:object_id/autosignin/:autosignin_token'` route. For example, for User model:
46
+
47
+ /users/1/autosignin/c6718d1a2ebea0f716cb62ad2375af64
48
+
49
+ Also route understand optional parameter "return_to" to redirect after sign in.
50
+
51
+ Rake tasks
52
+ -----------
53
+ Devise Autosigninable has two rake task which help to reset all autosignin_tokens
54
+
55
+ rake devise:autosigninable:reset[User]
56
+
57
+ and generate all missed autosigninable tokens
58
+
59
+ rake devise:autosigninable:ensure[User]
60
+
61
+
62
+ Features
63
+ -----------
64
+
65
+ Devise Autosigninable has functionality of exipering token after sign in. To use it add this to the end of devise determing in model:
66
+
67
+ :autosignin_expire => true
68
+
69
+ For example:
70
+
71
+ devise :authenticatable, :confirmable, :recoverable, :validatable, :autosigninable, :autosignin_expire => true
72
+
73
+
74
+
75
+ Devise Autosigninable add method `autosigninable?` which detect need of generation autosignin token for record. It may be useful you don't want add
76
+ autosignin functionality for some records.
77
+
78
+ [1]:http://github.com/plataformatec/devise
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the devise_autosigninable plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.libs << 'test'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+ desc 'Generate documentation for the devise_autosigninable plugin.'
17
+ Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'DeviseAutosigninable'
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
@@ -0,0 +1,15 @@
1
+ class Devise::AutosigninController < ApplicationController
2
+
3
+ include Devise::Controllers::InternalHelpers
4
+ include Devise::Autosigninable::Helpers
5
+
6
+ def create
7
+ sign_out(resource_name)
8
+ if resource = warden.authenticate!(:scope => resource_name)
9
+ set_flash_message :notice, :signed_in
10
+ else
11
+ set_now_flash_message :alert, (warden.message || :invalid)
12
+ end
13
+ sign_in_and_redirect_to_url(resource, params[:return_to])
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ ru:
2
+ devise:
3
+ autosignin:
4
+ signed_in: "You have signed in successfully"
@@ -0,0 +1,4 @@
1
+ ru:
2
+ devise:
3
+ autosignin:
4
+ signed_in: 'Вы вошли'
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "devise_autosigninable/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = %q{devise_autosigninable}
7
+ s.version = DeviseAutosigninable::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Andrey Deryabin"]
10
+ s.date = Date.today
11
+ s.description = %q{It adds support to be logged in by uniq link.}
12
+ s.summary = %q{It adds support to be logged in by uniq link. It useful for mailing and access from admin panel.}
13
+ s.email = %q{deriabin@gmail.com}
14
+ s.homepage = %q{http://github.com/evilmartians/devise_autosigninable}
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+ end
21
+
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Explain the generator
3
+
4
+ Example:
5
+ ./script/generate devise_autosigninable Thing
6
+
7
+ This will create:
8
+ what/will/it/create
@@ -0,0 +1,7 @@
1
+ class DeviseAutosigninableGenerator < Rails::Generator::NamedBase
2
+ def manifest
3
+ record do |m|
4
+ m.migration_template 'migration.rb', 'db/migrate', :migration_file_name => "add_autosigninable_to_#{table_name}"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ class AddAutosigninableTo<%= table_name.camelize %> < ActiveRecord::Migration
2
+ def self.up
3
+ change_table :<%= table_name %> do |t|
4
+ t.autosigninable
5
+ end
6
+ add_index :<%= table_name %>, :autosignin_token, :unique => true
7
+ end
8
+
9
+ def self.down
10
+ remove_column :<%= table_name %>, :autosignin_token
11
+ end
12
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ # Include hook code here
data/install.rb ADDED
@@ -0,0 +1 @@
1
+ # Install hook code here
@@ -0,0 +1,118 @@
1
+ module Devise
2
+ module Models
3
+ module Autosigninable
4
+ # include Devise::Models::Lockable
5
+
6
+ def self.included(base)
7
+ base.extend ClassMethods
8
+
9
+ base.class_eval do
10
+ before_create :reset_autosignin_token
11
+
12
+ # indicator to expire autosignin token
13
+ mattr_accessor :autosignin_expire
14
+ @@autosignin_expire = false
15
+
16
+ end
17
+ end
18
+
19
+ def autosigninable?
20
+ true
21
+ end
22
+
23
+ def autosigninable_ready?
24
+ !self.autosignin_token.blank?
25
+ end
26
+
27
+ # Generate new autosignin token
28
+ def reset_autosignin_token
29
+ self.autosignin_token = self.autosigninable? ? self.class.autosignin_token : nil
30
+ end
31
+
32
+ # Generate new autosignin token and save the record.
33
+ def reset_autosignin_token!
34
+ reset_autosignin_token
35
+ self.save
36
+ end
37
+
38
+ # Generate autosignin token unless already exists.
39
+ def ensure_autosignin_token
40
+ self.reset_autosignin_token unless self.autosigninable_ready?
41
+ end
42
+
43
+ # Generate autosignin token unless already exists and save the record.
44
+ def ensure_autosignin_token!
45
+ self.reset_autosignin_token! unless self.autosigninable_ready?
46
+ end
47
+
48
+ # Verifies whether an +incoming_autosignin_token
49
+ # is the user authentication token.
50
+ def valid_autosignin_token?(incoming_autosignin_token)
51
+ incoming_autosignin_token == self.autosignin_token
52
+ end
53
+
54
+ # Checks if a resource is valid upon authentication.
55
+ # for verifying whether an user is allowed to sign in or not. If the user
56
+ # is locked, it should never be allowed.
57
+ def valid_for_autosignin_token_authentication?(attributes)
58
+ if (result = valid_autosignin_token?(attributes[:autosignin_token])) && self.class.devise_modules.include?(:lockable)
59
+ self.failed_attempts = 0 if self.class.devise_modules.include?(:lockable)
60
+ else
61
+ if self.class.devise_modules.include?(:lockable)
62
+ self.failed_attempts += 1
63
+ lock_access! if failed_attempts > self.class.maximum_attempts
64
+ end
65
+ end
66
+ reset_autosignin_token! if self.class.autosignin_expire
67
+ save(false) if changed?
68
+ result
69
+ end
70
+
71
+
72
+ module ClassMethods
73
+
74
+ RETRY_COUNT = 20
75
+
76
+ # Generate autosignin tokens unless already exists and save the records.
77
+ def ensure_all_autosignin_tokens(batch_size=500)
78
+ user_count = count( :conditions=>{:autosignin_token => nil})
79
+ find_in_batches(:batch_size =>batch_size, :conditions=>{:autosignin_token => nil}) do |group|
80
+ group.each { |user| user.ensure_autosignin_token! }
81
+ end
82
+ end
83
+
84
+ # Generate autosignin tokens and save the records.
85
+ def reset_all_autosignin_tokens(batch_size=500)
86
+ user_count = count
87
+ find_in_batches(:batch_size =>batch_size) do |group|
88
+ group.each { |user| user.reset_autosignin_token! }
89
+ end
90
+ end
91
+
92
+ # generation random autosignin token
93
+ def autosignin_token(uniq = false, field = 'autosignin_token')
94
+ if uniq
95
+ RETRY_COUNT.times do
96
+ token = Digest::SHA1.hexdigest("--#{Time.now.utc}--#{rand}--")
97
+ return token unless exists? field => token
98
+ end
99
+ raise Exception.new("Couldn't generate #{self.class}:#{field} for #{RETRY_COUNT} times")
100
+ else
101
+ Digest::SHA1.hexdigest("--#{Time.now.utc}--#{rand}--")
102
+ end
103
+ end
104
+
105
+ # Authenticate a user based on authentication token.
106
+ def authenticate_with_autosignin_token(attributes={})
107
+ resource = find_by_id(attributes[self.to_s.foreign_key.to_sym])
108
+ if resource.try(:valid_for_autosignin_token_authentication?, attributes)
109
+ resource
110
+ else
111
+ nil
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ end
@@ -0,0 +1,23 @@
1
+ if ActionController::Routing.name =~ /ActionDispatch/
2
+ #RAILS 3
3
+ ActionDispatch::Routing::Mapper.class_eval do
4
+ protected
5
+
6
+ # Setup routes for +AutosigninController+.
7
+ def devise_autosigninable(mapping, controllers)
8
+ match "/:#{mapping.name}_id/autosignin/:autosignin_token" => 'devise/autosignin#create',
9
+ :as => "autosignin", :via => :get
10
+ end
11
+ end
12
+
13
+ else
14
+ #RAILS 2
15
+ ActionController::Routing::RouteSet::Mapper.class_eval do
16
+ protected
17
+
18
+ # Setup routes for +AutosigninController+.
19
+ def autosigninable(routes, mapping)
20
+ routes.autosignin "/:#{mapping.name.to_s}_id/autosignin/:autosignin_token", :controller => 'devise/autosignin', :action => 'create', :conditions => { :method => :get }
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ Devise::Schema.class_eval do
2
+
3
+ # add to migration neccessary fields for autosignin
4
+ def autosigninable
5
+ apply_schema :autosignin_token, String, :limit=>40
6
+ end
7
+ end
@@ -0,0 +1,33 @@
1
+ require 'devise/strategies/base'
2
+
3
+ module Devise
4
+ module Strategies
5
+ class Autosigninable < Base
6
+
7
+ def valid?
8
+ valid_controller? && valid_params? && mapping.to.respond_to?('authenticate_with_autosignin_token')
9
+ end
10
+
11
+ def authenticate!
12
+ if resource = mapping.to.authenticate_with_autosignin_token(params)
13
+ success!(resource)
14
+ else
15
+ fail!(:invalid)
16
+ end
17
+ end
18
+
19
+ protected
20
+
21
+ def valid_controller?
22
+ 'devise/autosignin' == params[:controller]
23
+ end
24
+
25
+ def valid_params?
26
+ params[:autosignin_token].present?
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+
33
+ Warden::Strategies.add(:autosigninable, Devise::Strategies::Autosigninable)
@@ -0,0 +1,3 @@
1
+ module DeviseAutosigninable
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+ require 'devise/mapping'
3
+
4
+ module Devise #:nodoc:
5
+ module Autosigninable #:nodoc:
6
+
7
+ module Helpers
8
+
9
+ # Create the link to autosignin url based on resource with given link_text
10
+ # example: link_to_autosignin(user, user.email)
11
+ def link_to_autosignin(resource, link_text, options={})
12
+ link_to link_text, auto_signin_url_for(resource) , options
13
+ end
14
+
15
+
16
+ # return autosignin url for given resource
17
+ def auto_signin_url_for(resource)
18
+ resource_name = resource.class.to_s.downcase
19
+ send("#{resource_name}_autosignin_url",
20
+ {:"#{resource_name}_id" => resource.id,
21
+ :autosignin_token => resource.autosignin_token}
22
+ )
23
+ end
24
+
25
+ # Sign in and tries to redirect first to given url and
26
+ # then to the url specified by after_sign_in_path_for.
27
+ #
28
+ # If resource is blank than tries redirect to given url
29
+ # or root url
30
+ def sign_in_and_redirect_to_url(resource = nil, url=nil)
31
+ if resource
32
+ sign_out(resource)
33
+ sign_in(resource)
34
+ redirect_to url || after_sign_in_path_for(resource)
35
+ else
36
+ redirect_to url || root_url
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ ::ActionView::Base.send :include, Devise::Autosigninable::Helpers
@@ -0,0 +1,23 @@
1
+ require 'devise'
2
+
3
+ begin
4
+ Rails::Engine
5
+ rescue
6
+ else
7
+ module DeviseAutosigninable
8
+ class Engine < Rails::Engine
9
+ end
10
+ end
11
+
12
+ end
13
+
14
+ Devise.add_module :autosigninable,
15
+ :strategy => true,
16
+ :controller => :autosignin,
17
+ :model => 'devise_autosigninable/model',
18
+ :route => :autosigninable
19
+
20
+ require 'devise_autosigninable/routes'
21
+ require 'devise_autosigninable/schema'
22
+ require 'devise_autosigninable/view_helpers'
23
+ require 'devise_autosigninable/strategy'
@@ -0,0 +1,15 @@
1
+ namespace :devise do
2
+ namespace :autosigninable do
3
+ desc 'Generate missed autosignin tokens, by default for User model'
4
+ task :ensure, :model, :needs => [:environment] do |t, args|
5
+ args.with_defaults(:model => "User")
6
+ args.model.camelize.constantize.ensure_all_autosignin_tokens
7
+ end
8
+
9
+ desc 'Reset all autosignin tokens, by default for User model'
10
+ task :reset, :model, :needs => [:environment] do |t, args|
11
+ args.with_defaults(:model => "User")
12
+ args.model.camelize.constantize.reset_all_autosignin_tokens
13
+ end
14
+ end
15
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ # Include hook code here
2
+ require 'devise_autosigninable'
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class DeviseAutosigninableTest < ActiveSupport::TestCase
4
+ # Replace this with your real tests.
5
+ test "the truth" do
6
+ assert true
7
+ end
8
+ end
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'active_support'
3
+ require 'active_support/test_case'
4
+ require 'test/unit'
data/uninstall.rb ADDED
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: devise_autosigninable
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Andrey Deryabin
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-08-14 00:00:00 +04:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: It adds support to be logged in by uniq link.
23
+ email: deriabin@gmail.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - .gitignore
32
+ - .gitmodules
33
+ - MIT-LICENSE
34
+ - README.md
35
+ - Rakefile
36
+ - app/controllers/devise/autosignin_controller.rb
37
+ - config/locales/devise.en.yml
38
+ - config/locales/devise.ru.yml
39
+ - devise_autosigninable.gemspec
40
+ - generators/devise_autosigninable/USAGE
41
+ - generators/devise_autosigninable/devise_autosigninable_generator.rb
42
+ - generators/devise_autosigninable/templates/migration.rb
43
+ - init.rb
44
+ - install.rb
45
+ - lib/devise_autosigninable.rb
46
+ - lib/devise_autosigninable/model.rb
47
+ - lib/devise_autosigninable/routes.rb
48
+ - lib/devise_autosigninable/schema.rb
49
+ - lib/devise_autosigninable/strategy.rb
50
+ - lib/devise_autosigninable/version.rb
51
+ - lib/devise_autosigninable/view_helpers.rb
52
+ - lib/tasks/devise_autosigninable.rake
53
+ - rails/init.rb
54
+ - test/devise_autosigninable_test.rb
55
+ - test/test_helper.rb
56
+ - uninstall.rb
57
+ has_rdoc: true
58
+ homepage: http://github.com/evilmartians/devise_autosigninable
59
+ licenses: []
60
+
61
+ post_install_message:
62
+ rdoc_options: []
63
+
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ hash: 3
81
+ segments:
82
+ - 0
83
+ version: "0"
84
+ requirements: []
85
+
86
+ rubyforge_project:
87
+ rubygems_version: 1.6.2
88
+ signing_key:
89
+ specification_version: 3
90
+ summary: It adds support to be logged in by uniq link. It useful for mailing and access from admin panel.
91
+ test_files:
92
+ - test/devise_autosigninable_test.rb
93
+ - test/test_helper.rb