lperichon-devise_invitable 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/.document +5 -0
  2. data/.gitignore +22 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +92 -0
  5. data/Rakefile +54 -0
  6. data/VERSION +1 -0
  7. data/app/controllers/devise/invitations_controller.rb +52 -0
  8. data/app/views/devise/invitations/edit.html.erb +14 -0
  9. data/app/views/devise/invitations/new.html.erb +12 -0
  10. data/app/views/devise/mailer/invitation.html.erb +8 -0
  11. data/devise_invitable.gemspec +123 -0
  12. data/init.rb +1 -0
  13. data/lib/devise_invitable.rb +21 -0
  14. data/lib/devise_invitable/controllers/helpers.rb +6 -0
  15. data/lib/devise_invitable/controllers/url_helpers.rb +24 -0
  16. data/lib/devise_invitable/locales/en.yml +5 -0
  17. data/lib/devise_invitable/mailer.rb +8 -0
  18. data/lib/devise_invitable/model.rb +139 -0
  19. data/lib/devise_invitable/rails.rb +15 -0
  20. data/lib/devise_invitable/routes.rb +11 -0
  21. data/lib/devise_invitable/schema.rb +11 -0
  22. data/test/integration/invitable_test.rb +122 -0
  23. data/test/integration_tests_helper.rb +39 -0
  24. data/test/mailers/invitation_test.rb +62 -0
  25. data/test/model_tests_helper.rb +41 -0
  26. data/test/models/invitable_test.rb +172 -0
  27. data/test/models_test.rb +35 -0
  28. data/test/rails_app/app/controllers/admins_controller.rb +6 -0
  29. data/test/rails_app/app/controllers/application_controller.rb +10 -0
  30. data/test/rails_app/app/controllers/home_controller.rb +4 -0
  31. data/test/rails_app/app/controllers/users_controller.rb +12 -0
  32. data/test/rails_app/app/helpers/application_helper.rb +3 -0
  33. data/test/rails_app/app/models/user.rb +4 -0
  34. data/test/rails_app/app/views/home/index.html.erb +0 -0
  35. data/test/rails_app/config/boot.rb +110 -0
  36. data/test/rails_app/config/database.yml +22 -0
  37. data/test/rails_app/config/environment.rb +44 -0
  38. data/test/rails_app/config/environments/development.rb +17 -0
  39. data/test/rails_app/config/environments/production.rb +28 -0
  40. data/test/rails_app/config/environments/test.rb +28 -0
  41. data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  42. data/test/rails_app/config/initializers/devise.rb +105 -0
  43. data/test/rails_app/config/initializers/inflections.rb +2 -0
  44. data/test/rails_app/config/initializers/new_rails_defaults.rb +21 -0
  45. data/test/rails_app/config/initializers/session_store.rb +15 -0
  46. data/test/rails_app/config/routes.rb +3 -0
  47. data/test/rails_app/vendor/plugins/devise_invitable/init.rb +1 -0
  48. data/test/routes_test.rb +20 -0
  49. data/test/test_helper.rb +58 -0
  50. metadata +173 -0
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,22 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ test/rails_app/log
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Sergio Cambra
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,92 @@
1
+ = devise_invitable
2
+
3
+ It adds support to devise[http://github.com/plataformatec/devise] for send invitations by email (it requires to be authenticated) and accept the invitation setting the password.
4
+
5
+ == Installation
6
+
7
+ All gems are on gemcutter, so you need to add gemcutter to your sources if you haven’t yet:
8
+
9
+ sudo gem sources -a http://gemcutter.org/
10
+
11
+ Install devise_invitable gem, it should install dependencies (such as devise and warden):
12
+
13
+ sudo gem install devise_invitable
14
+
15
+ Configure devise_invitable inside your app (and warden and devise if you weren't using them):
16
+
17
+ config.gem 'warden'
18
+ config.gem 'devise'
19
+ config.gem 'devise_invitable'
20
+
21
+ == Basic Usage
22
+
23
+ Follow the walkthrough for devise with the following modifications.
24
+
25
+ Add t.invitable to the migration:
26
+
27
+ create_table :users do
28
+ ...
29
+ t.invitable
30
+ ...
31
+ end
32
+ add_index :users, :invitation_token # for invitable
33
+
34
+ Add :invitable to the devise line in your model:
35
+
36
+ class User < ActiveRecord::Base
37
+ devise ..., :invitable
38
+ end
39
+
40
+ If you are using devise :all, you can add :invitable to config.all in devise initializer:
41
+ Devise.setup do |config|
42
+ ...
43
+ config.all = [..., :invitable]
44
+ ...
45
+ end
46
+
47
+ == Model configuration
48
+
49
+ DeviseInvitable adds a new configuration option, :invite_for. It's the time a invitation is valid for. Default value is nil, which means invitation doesn't expire.
50
+
51
+ == Controller filters
52
+
53
+ It adds authenticate_resource! filter to restrict who can send invitations. You can override this method in your ApplicationController. Default behavior is require authentication of the same resource_name, so if you only have a model with devise it will allow to all authenticated users to send invitations.
54
+
55
+ You have to configure mailer as it's required for confirmable and recoverable.
56
+
57
+ == I18n
58
+
59
+ It uses two flash messages, :send_invitation and :updated, which are translated as other flash messages from devise.
60
+
61
+ == Adding Invitable to a running application
62
+
63
+ Define a migration to add invitable to your model:
64
+
65
+ change_table :your_table do |t|
66
+ t.string :invitation_token, :limit => 20
67
+ t.datetime :invitation_sent_at
68
+ t.index :invitation_token
69
+ end
70
+
71
+ # Allow null encrypted_password and password_salt
72
+ change_column :your_table, :encrypted_password, :string, :null => true
73
+ change_column :your_table, :password_salt, :string, :null => true
74
+
75
+ Add :invitable to the devise line of your model, or to config.all in devise initializer if your model uses devise :all.
76
+
77
+ Override authenticate_resource! filter if you need to customize who can send invitations.
78
+
79
+ == Note on Patches/Pull Requests
80
+
81
+ * Fork the project.
82
+ * Make your feature addition or bug fix.
83
+ * Add tests for it. This is important so I don't break it in a
84
+ future version unintentionally.
85
+ * Commit, do not mess with rakefile, version, or history.
86
+ (if you want to have your own version, that is fine but
87
+ bump version in a commit by itself I can ignore when I pull)
88
+ * Send me a pull request. Bonus points for topic branches.
89
+
90
+ == Copyright
91
+
92
+ Copyright (c) 2009 Sergio Cambra. See LICENSE for details.
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "lperichon-devise_invitable"
8
+ gem.summary = %Q{An invitation strategy for devise}
9
+ gem.description = %Q{It adds support for send invitations by email (it requires to be authenticated) and accept the invitation setting the password}
10
+ gem.email = "sergio@entrecables.com"
11
+ gem.homepage = "http://github.com/scambra/devise_invitable"
12
+ gem.authors = ["Sergio Cambra"]
13
+ gem.add_development_dependency 'mocha'
14
+ gem.add_development_dependency 'webrat'
15
+ gem.add_dependency 'devise', '~> 1.1.0'
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
20
+ end
21
+
22
+ require 'rake/testtask'
23
+ Rake::TestTask.new(:test) do |test|
24
+ test.libs << 'lib' << 'test'
25
+ test.pattern = 'test/**/*_test.rb'
26
+ test.verbose = true
27
+ end
28
+
29
+ begin
30
+ require 'rcov/rcovtask'
31
+ Rcov::RcovTask.new do |test|
32
+ test.libs << 'test'
33
+ test.pattern = 'test/**/test_*.rb'
34
+ test.verbose = true
35
+ end
36
+ rescue LoadError
37
+ task :rcov do
38
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
39
+ end
40
+ end
41
+
42
+ task :test => :check_dependencies
43
+
44
+ task :default => :test
45
+
46
+ require 'rake/rdoctask'
47
+ Rake::RDocTask.new do |rdoc|
48
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
49
+
50
+ rdoc.rdoc_dir = 'rdoc'
51
+ rdoc.title = "devise_invitable #{version}"
52
+ rdoc.rdoc_files.include('README*')
53
+ rdoc.rdoc_files.include('lib/**/*.rb')
54
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.0
@@ -0,0 +1,52 @@
1
+ class Devise::InvitationsController < ApplicationController
2
+ include Devise::Controllers::InternalHelpers
3
+ include Devise::Controllers::Helpers
4
+
5
+ before_filter :authenticate_resource!, :only => [:new, :create]
6
+ before_filter :require_no_authentication, :only => [:edit, :update]
7
+ helper_method :after_sign_in_path_for
8
+
9
+ # GET /resource/invitation/new
10
+ def new
11
+ build_resource
12
+ render_with_scope :new
13
+ end
14
+
15
+ # POST /resource/invitation
16
+ def create
17
+ self.resource = resource_class.send_invitation(params[resource_name])
18
+
19
+ if resource.errors.empty?
20
+ set_flash_message :notice, :send_instructions
21
+ redirect_to after_sign_in_path_for(resource_name)
22
+ else
23
+ render_with_scope :new
24
+ end
25
+ end
26
+
27
+ # GET /resource/invitation/edit?invitation_token=abcdef
28
+ def edit
29
+ self.resource = resource_class.new
30
+ resource.invitation_token = params[:invitation_token]
31
+ render_with_scope :edit
32
+ end
33
+
34
+ # PUT /resource/invitation
35
+ def update
36
+ self.resource = resource_class.accept_invitation!(params[resource_name])
37
+
38
+ if resource.errors.empty?
39
+ set_flash_message :notice, :updated
40
+ sign_in_and_redirect(resource_name, resource)
41
+ else
42
+ render_with_scope :edit
43
+ end
44
+ end
45
+
46
+ protected
47
+
48
+ def authenticate_resource!
49
+ send :"authenticate_#{resource_name}!"
50
+ end
51
+
52
+ end
@@ -0,0 +1,14 @@
1
+ <h2>Set your password</h2>
2
+
3
+ <% form_for resource, :as => resource_name, :url => invitation_path(resource_name), :html => { :method => :put } do |f| %>
4
+ <%= f.error_messages %>
5
+ <%= f.hidden_field :invitation_token %>
6
+
7
+ <p><%= f.label :password %></p>
8
+ <p><%= f.password_field :password %></p>
9
+
10
+ <p><%= f.label :password_confirmation %></p>
11
+ <p><%= f.password_field :password_confirmation %></p>
12
+
13
+ <p><%= f.submit "Set my password" %></p>
14
+ <% end %>
@@ -0,0 +1,12 @@
1
+ <h2>Send invitation</h2>
2
+
3
+ <% form_for resource, :as => resource_name, :url => invitation_path(resource_name) do |f| %>
4
+ <%= f.error_messages %>
5
+
6
+ <p><%= f.label :email %></p>
7
+ <p><%= f.text_field :email %></p>
8
+
9
+ <p><%= f.submit "Send an invitation" %></p>
10
+ <% end %>
11
+
12
+ <%= link_to "Home", after_sign_in_path_for(resource_name) %><br />
@@ -0,0 +1,8 @@
1
+ Hello <%= @resource.email %>!
2
+
3
+ Someone has invited you to <%= root_url %>, you can accept it through the link below.
4
+
5
+ <%= link_to 'Accept invitation', edit_invitation_url(@resource, :invitation_token => @resource.invitation_token) %>
6
+
7
+ If you don't want to accept the invitation, please ignore this email.
8
+ Your account won't be created until you access the link above and set your password.
@@ -0,0 +1,123 @@
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_invitable}
8
+ s.version = "0.3.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Sergio Cambra"]
12
+ s.date = %q{2010-05-17}
13
+ s.description = %q{It adds support for send invitations by email (it requires to be authenticated) and accept the invitation setting the password}
14
+ s.email = %q{sergio@entrecables.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "app/controllers/devise/invitations_controller.rb",
27
+ "app/views/devise/mailer/invitation.html.erb",
28
+ "app/views/devise/invitations/edit.html.erb",
29
+ "app/views/devise/invitations/new.html.erb",
30
+ "devise_invitable.gemspec",
31
+ "init.rb",
32
+ "lib/devise_invitable.rb",
33
+ "lib/devise_invitable/controllers/helpers.rb",
34
+ "lib/devise_invitable/controllers/url_helpers.rb",
35
+ "lib/devise_invitable/locales/en.yml",
36
+ "lib/devise_invitable/mailer.rb",
37
+ "lib/devise_invitable/model.rb",
38
+ "lib/devise_invitable/rails.rb",
39
+ "lib/devise_invitable/routes.rb",
40
+ "lib/devise_invitable/schema.rb",
41
+ "test/integration/invitable_test.rb",
42
+ "test/integration_tests_helper.rb",
43
+ "test/mailers/invitation_test.rb",
44
+ "test/model_tests_helper.rb",
45
+ "test/models/invitable_test.rb",
46
+ "test/models_test.rb",
47
+ "test/rails_app/app/controllers/admins_controller.rb",
48
+ "test/rails_app/app/controllers/application_controller.rb",
49
+ "test/rails_app/app/controllers/home_controller.rb",
50
+ "test/rails_app/app/controllers/users_controller.rb",
51
+ "test/rails_app/app/helpers/application_helper.rb",
52
+ "test/rails_app/app/models/user.rb",
53
+ "test/rails_app/app/views/home/index.html.erb",
54
+ "test/rails_app/config/boot.rb",
55
+ "test/rails_app/config/database.yml",
56
+ "test/rails_app/config/environment.rb",
57
+ "test/rails_app/config/environments/development.rb",
58
+ "test/rails_app/config/environments/production.rb",
59
+ "test/rails_app/config/environments/test.rb",
60
+ "test/rails_app/config/initializers/backtrace_silencers.rb",
61
+ "test/rails_app/config/initializers/devise.rb",
62
+ "test/rails_app/config/initializers/inflections.rb",
63
+ "test/rails_app/config/initializers/new_rails_defaults.rb",
64
+ "test/rails_app/config/initializers/session_store.rb",
65
+ "test/rails_app/config/routes.rb",
66
+ "test/rails_app/vendor/plugins/devise_invitable/init.rb",
67
+ "test/routes_test.rb",
68
+ "test/test_helper.rb"
69
+ ]
70
+ s.homepage = %q{http://github.com/scambra/devise_invitable}
71
+ s.rdoc_options = ["--charset=UTF-8"]
72
+ s.require_paths = ["lib"]
73
+ s.rubygems_version = %q{1.3.6}
74
+ s.summary = %q{An invitation strategy for devise}
75
+ s.test_files = [
76
+ "test/integration/invitable_test.rb",
77
+ "test/integration_tests_helper.rb",
78
+ "test/mailers/invitation_test.rb",
79
+ "test/model_tests_helper.rb",
80
+ "test/models/invitable_test.rb",
81
+ "test/models_test.rb",
82
+ "test/rails_app/app/controllers/admins_controller.rb",
83
+ "test/rails_app/app/controllers/application_controller.rb",
84
+ "test/rails_app/app/controllers/home_controller.rb",
85
+ "test/rails_app/app/controllers/users_controller.rb",
86
+ "test/rails_app/app/helpers/application_helper.rb",
87
+ "test/rails_app/app/models/user.rb",
88
+ "test/rails_app/config/boot.rb",
89
+ "test/rails_app/config/environment.rb",
90
+ "test/rails_app/config/environments/development.rb",
91
+ "test/rails_app/config/environments/production.rb",
92
+ "test/rails_app/config/environments/test.rb",
93
+ "test/rails_app/config/initializers/backtrace_silencers.rb",
94
+ "test/rails_app/config/initializers/inflections.rb",
95
+ "test/rails_app/config/initializers/new_rails_defaults.rb",
96
+ "test/rails_app/config/initializers/session_store.rb",
97
+ "test/rails_app/config/initializers/devise.rb",
98
+ "test/rails_app/config/routes.rb",
99
+ "test/rails_app/vendor/plugins/devise_invitable/init.rb",
100
+ "test/routes_test.rb",
101
+ "test/test_helper.rb"
102
+ ]
103
+
104
+ if s.respond_to? :specification_version then
105
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
106
+ s.specification_version = 3
107
+
108
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
109
+ s.add_development_dependency(%q<mocha>, [">= 0"])
110
+ s.add_development_dependency(%q<webrat>, [">= 0"])
111
+ s.add_runtime_dependency(%q<devise>, ["~> 1.1.0"])
112
+ else
113
+ s.add_dependency(%q<mocha>, [">= 0"])
114
+ s.add_dependency(%q<webrat>, [">= 0"])
115
+ s.add_dependency(%q<devise>, ["~> 1.1.0"])
116
+ end
117
+ else
118
+ s.add_dependency(%q<mocha>, [">= 0"])
119
+ s.add_dependency(%q<webrat>, [">= 0"])
120
+ s.add_dependency(%q<devise>, ["~> 1.1.0"])
121
+ end
122
+ end
123
+
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'devise_invitable'
@@ -0,0 +1,21 @@
1
+ unless defined?(Devise)
2
+ require 'devise'
3
+ end
4
+
5
+ Devise.module_eval do
6
+ # Time interval where the invitation token is valid.
7
+ mattr_accessor :invite_for
8
+ @@invite_for = 0
9
+ end
10
+
11
+ Devise.add_module :invitable, :controller => :invitations, :model => 'devise_invitable/model', :route => :invitation
12
+
13
+ module DeviseInvitable; end
14
+
15
+ # Had to comment those two lines out and add them to the application initialized
16
+
17
+ require 'devise_invitable/mailer'
18
+ require 'devise_invitable/routes'
19
+ require 'devise_invitable/schema'
20
+ require 'devise_invitable/controllers/url_helpers'
21
+ require 'devise_invitable/rails'
@@ -0,0 +1,6 @@
1
+ module Devise::Controllers::Helpers
2
+ protected
3
+ def authenticate_resource!
4
+ send :"authenticate_#{resource_name}!"
5
+ end
6
+ end