devise_imapable 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 [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.
@@ -0,0 +1,133 @@
1
+ Devise - Imapable
2
+ =================
3
+
4
+ Devise-Imapable is a imap based authentication strategy for the [Devise](github.com/plataformatec/devise) authentication framework.
5
+
6
+ If you are building applications for use within your organisation which require authentication and don't have access to a LDAP server, using imap can be a great alternative.
7
+
8
+ Installation
9
+ ------------
10
+
11
+ Currently this can only be installed as a plugin.
12
+
13
+ script/plugin install git@github.com:joshk/devise_imapable.git
14
+
15
+ *Gem coming soon!*
16
+
17
+
18
+ **And don't forget to add [Devise](github.com/plataformatec/devise)!**
19
+
20
+ either in config/environment.rb:
21
+
22
+ config.gem 'devise'
23
+
24
+ or in bundler
25
+
26
+ gem 'devise'
27
+
28
+
29
+ Setup
30
+ -----
31
+
32
+ Once devise-imapable is installed, all you need to do is setup the user model which includes a small addition to the model itself and to the schema.
33
+
34
+ First the schema :
35
+
36
+ create_table :users do |t|
37
+
38
+ t.facebook_connectable
39
+
40
+ end
41
+
42
+ and indexes (optional) :
43
+
44
+ add_index :users, :email, :unique => true
45
+
46
+ and don’t forget to migrate :
47
+
48
+ rake db:migrate.
49
+
50
+ then finally the model :
51
+
52
+ class User < ActiveRecord::Base
53
+
54
+ devise :rememberable, :trackable, :timeoutable, :imapable
55
+
56
+ # Setup accessible (or protected) attributes for your model
57
+ attr_accessible :email, :password, :remember_me
58
+
59
+ ...
60
+ end
61
+
62
+ I recommend using :rememberable, :trackable, :timeoutable along with :imapable as it gives a full feature set for logins.
63
+
64
+
65
+ Usage
66
+ -----
67
+
68
+ Devise-Imapable works in replacement of Authenticatable, allowing for user name (or email) and password authentication. The standard sign\_in routes and views work out of the box as these are just reused from devise. I recommend you run :
69
+
70
+ script/generate devise_views
71
+
72
+ so you can customize your login pages.
73
+
74
+ ------------------------------------------------------------
75
+
76
+ **please note**
77
+
78
+ This devise plugin has not been tested with Authenticatable enabled at the same time. This is meant as a drop in replacement for Authenticatable allowing for a semi single sign on approach.
79
+
80
+
81
+ Advanced Configuration
82
+ ----------------------
83
+
84
+ In initializer `config/initializers/devise.rb` :
85
+
86
+ Devise.setup do |config|
87
+ # ...
88
+ config.imap_server = 'bigcorporation.com'
89
+ config.default_email_suffix = 'friendly-corporation.com'
90
+ # ...
91
+ end
92
+
93
+ Imap servers usually allow a user to login using their full email address or just the identifier part, eg: josh.kalderimis and josh.kalderimis@gmail.com will both work. It is recommend that you set the default\_email\_suffix so the login is kept consistent and the users email is correctly stored in the User model.
94
+
95
+ So remember ...
96
+ ---------------
97
+
98
+ - don't use Authenticatable
99
+
100
+ - add imap\_server and default\_email\_suffix settings in the devise initializer
101
+
102
+ - generate the devise views and make them pretty
103
+
104
+
105
+ References
106
+ ----------
107
+
108
+ * [Devise](github.com/plataformatec/devise)
109
+ * [Warden](github.com/hassox/warden)
110
+
111
+
112
+ TODO
113
+ ----
114
+
115
+ - email validation
116
+
117
+ - add update\_with\_password to the model, similar to Authenticatable
118
+
119
+ - assert Authenticatable is not being used
120
+
121
+ - assert imap\_server is present, and warn if default\_email\_suffix isn't present
122
+
123
+ - tests, tests, tests
124
+
125
+ - allow for setups which require profile information before creating a user
126
+
127
+ - investigate how well this works with other devise modules like http\_authenticatable, token\_authenticatable lockable, confirmable, and activatable
128
+
129
+
130
+
131
+ Released under the MIT license
132
+
133
+ Copyright (c) 2010 Josh Kalderimis,
@@ -0,0 +1,40 @@
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_imapable 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_imapable plugin.'
17
+ Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'DeviseImapable'
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
24
+
25
+
26
+ begin
27
+ require 'jeweler'
28
+ Jeweler::Tasks.new do |gemspec|
29
+ gemspec.name = "devise_imapable"
30
+ gemspec.summary = "Devise Imap authentication module"
31
+ gemspec.description = "For when you don't have access to LDAP"
32
+ gemspec.email = "josh.kalderimis@gmail.com"
33
+ gemspec.homepage = "http://github.com/joshk/devise_imapable"
34
+ gemspec.authors = ["Josh Kalderimis"]
35
+ gemspec.add_runtime_dependency "devise", "> 1.0.4"
36
+ end
37
+ Jeweler::GemcutterTasks.new
38
+ rescue LoadError
39
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
40
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.5.0
@@ -0,0 +1,57 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{devise_imapable}
8
+ s.version = "0.5.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Josh Kalderimis"]
12
+ s.date = %q{2010-03-27}
13
+ s.description = %q{For when you don't have access to LDAP}
14
+ s.email = %q{josh.kalderimis@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "README.md"
17
+ ]
18
+ s.files = [
19
+ "MIT-LICENSE",
20
+ "README.md",
21
+ "Rakefile",
22
+ "VERSION",
23
+ "devise_imapable.gemspec",
24
+ "lib/devise_imapable.rb",
25
+ "lib/devise_imapable/imap_adapter.rb",
26
+ "lib/devise_imapable/model.rb",
27
+ "lib/devise_imapable/routes.rb",
28
+ "lib/devise_imapable/schema.rb",
29
+ "lib/devise_imapable/strategy.rb",
30
+ "rails/init.rb",
31
+ "test/devise_imapable_test.rb",
32
+ "test/test_helper.rb"
33
+ ]
34
+ s.homepage = %q{http://github.com/joshk/devise_imapable}
35
+ s.rdoc_options = ["--charset=UTF-8"]
36
+ s.require_paths = ["lib"]
37
+ s.rubygems_version = %q{1.3.6}
38
+ s.summary = %q{Devise Imap authentication module}
39
+ s.test_files = [
40
+ "test/devise_imapable_test.rb",
41
+ "test/test_helper.rb"
42
+ ]
43
+
44
+ if s.respond_to? :specification_version then
45
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
46
+ s.specification_version = 3
47
+
48
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
49
+ s.add_runtime_dependency(%q<devise>, ["> 1.0.4"])
50
+ else
51
+ s.add_dependency(%q<devise>, ["> 1.0.4"])
52
+ end
53
+ else
54
+ s.add_dependency(%q<devise>, ["> 1.0.4"])
55
+ end
56
+ end
57
+
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ require 'devise'
3
+
4
+ require 'devise_imapable/schema'
5
+ require 'devise_imapable/imap_adapter'
6
+ require 'devise_imapable/routes'
7
+
8
+ module Devise
9
+ # imap server address for authentication.
10
+ mattr_accessor :imap_server
11
+ @@imap_server = nil
12
+
13
+ # default email suffix
14
+ mattr_accessor :default_email_suffix
15
+ @@default_email_suffix = nil
16
+ end
17
+
18
+ # Add +:imapable+ strategy to defaults.
19
+ #
20
+ Devise.add_module(:imapable,
21
+ :strategy => true,
22
+ :controller => :sessions,
23
+ :model => 'devise_imapable/model',
24
+ :routes => :imapable)
@@ -0,0 +1,21 @@
1
+ require 'net/imap'
2
+
3
+ module Devise
4
+
5
+ # simple adapter for imap credential checking
6
+ # (i don't like to add stuff like this directly to the model)
7
+ module ImapAdapter
8
+
9
+ def self.valid_credentials?(username, password)
10
+ imap = Net::IMAP.new(::Devise.imap_server)
11
+ imap.authenticate("cram-md5", username, password)
12
+ true
13
+ rescue Net::IMAP::ResponseError => e
14
+ false
15
+ ensure
16
+ imap.disconnect
17
+ end
18
+
19
+ end
20
+
21
+ end
@@ -0,0 +1,68 @@
1
+ require 'devise_imapable/strategy'
2
+
3
+ module Devise
4
+ module Models
5
+ # Imapable Module, responsible for validating the user credentials via an imap server.
6
+ #
7
+ # Examples:
8
+ #
9
+ # User.authenticate('email@test.com', 'password123') # returns authenticated user or nil
10
+ # User.find(1).valid_password?('password123') # returns true/false
11
+ #
12
+ module Imapable
13
+ def self.included(base)
14
+ base.class_eval do
15
+ extend ClassMethods
16
+
17
+ attr_accessor :password
18
+ end
19
+ end
20
+
21
+ # Set password to nil
22
+ def clean_up_passwords
23
+ self.password = nil
24
+ end
25
+
26
+ # Checks if a resource is valid upon authentication.
27
+ def valid_imap_authentication?(password)
28
+ Devise::ImapAdapter.valid_credentials?(self.email, password)
29
+ end
30
+
31
+ module ClassMethods
32
+ # Authenticate a user based on configured attribute keys. Returns the
33
+ # authenticated user if it's valid or nil.
34
+ def authenticate_with_imap(attributes={})
35
+ return unless attributes[:email].present?
36
+ conditions = attributes.slice(:email)
37
+
38
+ unless conditions[:email] && conditions[:email].include?('@') && !Devise.default_email_suffix
39
+ conditions[:email] = "#{conditions[:email]}@#{Devise.default_email_suffix}"
40
+ end
41
+
42
+ resource = find_for_imap_authentication(conditions) || new(conditions)
43
+
44
+ if resource.try(:valid_imap_authentication?, attributes[:password])
45
+ resource.new_record? ? create(conditions) : resource
46
+ end
47
+ end
48
+
49
+
50
+ protected
51
+
52
+ # Find first record based on conditions given (ie by the sign in form).
53
+ # Overwrite to add customized conditions, create a join, or maybe use a
54
+ # namedscope to filter records while authenticating.
55
+ # Example:
56
+ #
57
+ # def self.find_for_imap_authentication(conditions={})
58
+ # conditions[:active] = true
59
+ # find(:first, :conditions => conditions)
60
+ # end
61
+ #
62
+ def find_for_imap_authentication(conditions)
63
+ find(:first, :conditions => conditions)
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,8 @@
1
+ ActionController::Routing::RouteSet::Mapper.class_eval do
2
+
3
+ protected
4
+
5
+ # reuse the session routes and controller
6
+ alias :imapable :authenticatable
7
+
8
+ end
@@ -0,0 +1,13 @@
1
+ Devise::Schema.class_eval do
2
+
3
+ # Creates email
4
+ #
5
+ # == Options
6
+ # * :null - When true, allow columns to be null.
7
+ def imapable(options={})
8
+ null = options[:null] || false
9
+
10
+ apply_schema :email, String, :null => null
11
+ end
12
+
13
+ end
@@ -0,0 +1,36 @@
1
+ require 'devise/strategies/base'
2
+
3
+ module Devise
4
+ module Strategies
5
+ # Strategy for signing in a user based on his email and password using imap.
6
+ # Redirects to sign_in page if it's not authenticated
7
+ class Imapable < Base
8
+ def valid?
9
+ valid_controller? && valid_params? && mapping.to.respond_to?(:authenticate_with_imap)
10
+ end
11
+
12
+ # Authenticate a user based on email and password params, returning to warden
13
+ # success and the authenticated user if everything is okay. Otherwise redirect
14
+ # to sign in page.
15
+ def authenticate!
16
+ if resource = mapping.to.authenticate_with_imap(params[scope])
17
+ success!(resource)
18
+ else
19
+ fail!(:invalid)
20
+ end
21
+ end
22
+
23
+ protected
24
+
25
+ def valid_controller?
26
+ params[:controller] == 'sessions'
27
+ end
28
+
29
+ def valid_params?
30
+ params[scope] && params[scope][:password].present?
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ Warden::Strategies.add(:imapable, Devise::Strategies::Imapable)
@@ -0,0 +1,2 @@
1
+ # Include hook code here
2
+ require 'devise_imapable'
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class DeviseImapableTest < ActiveSupport::TestCase
4
+ # Replace this with your real tests.
5
+ test "the truth" do
6
+ assert true
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'active_support'
3
+ require 'active_support/test_case'
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: devise_imapable
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 5
8
+ - 0
9
+ version: 0.5.0
10
+ platform: ruby
11
+ authors:
12
+ - Josh Kalderimis
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-03-27 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: devise
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">"
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 0
30
+ - 4
31
+ version: 1.0.4
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ description: For when you don't have access to LDAP
35
+ email: josh.kalderimis@gmail.com
36
+ executables: []
37
+
38
+ extensions: []
39
+
40
+ extra_rdoc_files:
41
+ - README.md
42
+ files:
43
+ - MIT-LICENSE
44
+ - README.md
45
+ - Rakefile
46
+ - VERSION
47
+ - devise_imapable.gemspec
48
+ - lib/devise_imapable.rb
49
+ - lib/devise_imapable/imap_adapter.rb
50
+ - lib/devise_imapable/model.rb
51
+ - lib/devise_imapable/routes.rb
52
+ - lib/devise_imapable/schema.rb
53
+ - lib/devise_imapable/strategy.rb
54
+ - rails/init.rb
55
+ - test/devise_imapable_test.rb
56
+ - test/test_helper.rb
57
+ has_rdoc: true
58
+ homepage: http://github.com/joshk/devise_imapable
59
+ licenses: []
60
+
61
+ post_install_message:
62
+ rdoc_options:
63
+ - --charset=UTF-8
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ segments:
71
+ - 0
72
+ version: "0"
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ requirements: []
81
+
82
+ rubyforge_project:
83
+ rubygems_version: 1.3.6
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: Devise Imap authentication module
87
+ test_files:
88
+ - test/devise_imapable_test.rb
89
+ - test/test_helper.rb