refinerycms-authentication 0.9.9.1

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.
Files changed (66) hide show
  1. data/app/controllers/admin/users_controller.rb +90 -0
  2. data/app/controllers/passwords_controller.rb +43 -0
  3. data/app/controllers/registrations_controller.rb +67 -0
  4. data/app/controllers/sessions_controller.rb +23 -0
  5. data/app/helpers/sessions_helper.rb +2 -0
  6. data/app/helpers/users_helper.rb +2 -0
  7. data/app/mailers/user_mailer.rb +20 -0
  8. data/app/models/role.rb +16 -0
  9. data/app/models/roles_users.rb +6 -0
  10. data/app/models/user.rb +60 -0
  11. data/app/models/user_plugin.rb +5 -0
  12. data/app/views/admin/users/_form.html.erb +92 -0
  13. data/app/views/admin/users/_user.html.erb +19 -0
  14. data/app/views/admin/users/_users.html.erb +4 -0
  15. data/app/views/admin/users/edit.html.erb +1 -0
  16. data/app/views/admin/users/index.html.erb +12 -0
  17. data/app/views/admin/users/new.html.erb +1 -0
  18. data/app/views/layouts/login.html.erb +21 -0
  19. data/app/views/passwords/edit.html.erb +31 -0
  20. data/app/views/passwords/new.html.erb +18 -0
  21. data/app/views/registrations/new.html.erb +41 -0
  22. data/app/views/sessions/new.html.erb +29 -0
  23. data/app/views/user_mailer/reset_notification.html.erb +12 -0
  24. data/app/views/user_mailer/reset_notification.text.plain.erb +7 -0
  25. data/config/locales/cs.yml +75 -0
  26. data/config/locales/da.yml +72 -0
  27. data/config/locales/de.yml +72 -0
  28. data/config/locales/el.yml +72 -0
  29. data/config/locales/en.yml +72 -0
  30. data/config/locales/es.yml +100 -0
  31. data/config/locales/fr.yml +72 -0
  32. data/config/locales/it.yml +97 -0
  33. data/config/locales/lolcat.yml +55 -0
  34. data/config/locales/lt.yml +55 -0
  35. data/config/locales/lv.yml +72 -0
  36. data/config/locales/nb.yml +72 -0
  37. data/config/locales/nl.yml +70 -0
  38. data/config/locales/pl.yml +100 -0
  39. data/config/locales/pt-BR.yml +68 -0
  40. data/config/locales/rs.yml +72 -0
  41. data/config/locales/ru.yml +97 -0
  42. data/config/locales/sl.yml +61 -0
  43. data/config/locales/sv.yml +64 -0
  44. data/config/locales/vi.yml +72 -0
  45. data/config/locales/zh-CN.yml +72 -0
  46. data/config/locales/zh-TW.yml +72 -0
  47. data/config/routes.rb +31 -0
  48. data/db/migrate/20100913234705_create_refinerycms_authentication_schema.rb +43 -0
  49. data/db/migrate/20100929035252_add_missing_indexes_to_roles_users.rb +11 -0
  50. data/db/migrate/20101206013505_change_to_devise_users_table.rb +27 -0
  51. data/db/migrate/20110106184757_add_remember_created_at_to_users.rb +9 -0
  52. data/features/lost_password.feature +49 -0
  53. data/features/manage_users.feature +61 -0
  54. data/features/step_definitions/lost_password.rb +8 -0
  55. data/features/step_definitions/user_steps.rb +36 -0
  56. data/features/support/factories.rb +18 -0
  57. data/features/support/paths.rb +24 -0
  58. data/lib/authenticated_system.rb +29 -0
  59. data/lib/gemspec.rb +34 -0
  60. data/lib/generators/refinerycms_authentication_generator.rb +8 -0
  61. data/lib/refinerycms-authentication.rb +47 -0
  62. data/license.md +21 -0
  63. data/readme.md +17 -0
  64. data/refinerycms-authentication.gemspec +112 -0
  65. data/spec/models/user_spec.rb +159 -0
  66. metadata +144 -0
@@ -0,0 +1,43 @@
1
+ class CreateRefinerycmsAuthenticationSchema < ActiveRecord::Migration
2
+ def self.up
3
+ # Postgres apparently requires the roles_users table to exist before creating the roles table.
4
+ create_table ::RolesUsers.table_name, :id => false, :force => true do |t|
5
+ t.integer "user_id"
6
+ t.integer "role_id"
7
+ end
8
+
9
+ create_table ::Role.table_name, :force => true do |t|
10
+ t.string "title"
11
+ end
12
+
13
+ create_table ::UserPlugin.table_name, :force => true do |t|
14
+ t.integer "user_id"
15
+ t.string "name"
16
+ t.integer "position"
17
+ end
18
+
19
+ add_index ::UserPlugin.table_name, ["name"], :name => "index_#{::UserPlugin.table_name}_on_title"
20
+ add_index ::UserPlugin.table_name, ["user_id", "name"], :name => "index_unique_#{::UserPlugin.table_name}", :unique => true
21
+
22
+ create_table ::User.table_name, :force => true do |t|
23
+ t.string "login", :null => false
24
+ t.string "email", :null => false
25
+ t.string "crypted_password", :null => false
26
+ t.string "password_salt", :null => false
27
+ t.string "persistence_token"
28
+ t.datetime "created_at"
29
+ t.datetime "updated_at"
30
+ t.string "perishable_token"
31
+ end
32
+
33
+ add_index ::User.table_name, ["id"], :name => "index_#{::User.table_name}_on_id"
34
+ end
35
+
36
+ def self.down
37
+ [::User].reject{|m|
38
+ !(defined?(m) and m.respond_to?(:table_name))
39
+ }.each do |model|
40
+ drop_table model.table_name
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,11 @@
1
+ class AddMissingIndexesToRolesUsers < ActiveRecord::Migration
2
+ def self.up
3
+ add_index ::RolesUsers.table_name, [:role_id, :user_id]
4
+ add_index ::RolesUsers.table_name, [:user_id, :role_id]
5
+ end
6
+
7
+ def self.down
8
+ remove_index ::RolesUsers.table_name, :column => [:role_id, :user_id]
9
+ remove_index ::RolesUsers.table_name, :column => [:user_id, :role_id]
10
+ end
11
+ end
@@ -0,0 +1,27 @@
1
+ class ChangeToDeviseUsersTable < ActiveRecord::Migration
2
+ def self.up
3
+ add_column ::User.table_name, :current_sign_in_at, :datetime
4
+ add_column ::User.table_name, :last_sign_in_at, :datetime
5
+ add_column ::User.table_name, :current_sign_in_ip, :string
6
+ add_column ::User.table_name, :last_sign_in_ip, :string
7
+ add_column ::User.table_name, :sign_in_count, :integer
8
+ add_column ::User.table_name, :remember_token, :string
9
+ add_column ::User.table_name, :reset_password_token, :string
10
+
11
+ rename_column ::User.table_name, :crypted_password, :encrypted_password
12
+ rename_column ::User.table_name, :login, :username
13
+ end
14
+
15
+ def self.down
16
+ remove_column ::User.table_name, :current_sign_in_at
17
+ remove_column ::User.table_name, :last_sign_in_at
18
+ remove_column ::User.table_name, :current_sign_in_ip
19
+ remove_column ::User.table_name, :last_sign_in_ip
20
+ remove_column ::User.table_name, :sign_in_count
21
+ remove_column ::User.table_name, :remember_token
22
+ remove_column ::User.table_name, :reset_password_token
23
+
24
+ rename_column ::User.table_name, :encrypted_password, :crypted_password
25
+ rename_column ::User.table_name, :username, :login
26
+ end
27
+ end
@@ -0,0 +1,9 @@
1
+ class AddRememberCreatedAtToUsers < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :users, :remember_created_at, :datetime
4
+ end
5
+
6
+ def self.down
7
+ remove_column :users, :remember_created_at
8
+ end
9
+ end
@@ -0,0 +1,49 @@
1
+ @refinerycms @users @users-password
2
+ Feature: Lost Password
3
+ In order to restore my password
4
+ As a lost soul
5
+ I want to reset my password
6
+
7
+ Background:
8
+ Given A Refinery user exists
9
+
10
+ @users-password-forgot
11
+ Scenario: Forgot Password page (no email entered)
12
+ And I am on the forgot password page
13
+ When I press "Reset password"
14
+ Then I should see "You did not enter an email address."
15
+
16
+ @users-password-forgot
17
+ Scenario: Forgot Password page (non existing email entered)
18
+ Given I am on the forgot password page
19
+ And I have a user with email "green@cukes.com"
20
+ When I fill in "user_email" with "none@cukes.com"
21
+ And I press "Reset password"
22
+ Then I should see "Sorry, 'none@cukes.com' isn't associated with any accounts."
23
+ And I should see "Are you sure you typed the correct email address?"
24
+
25
+ @users-password-forgot
26
+ Scenario: Forgot Password page (existing email entered)
27
+ Given I am on the forgot password page
28
+ And I have a user with email "green@cukes.com"
29
+ When I fill in "user_email" with "green@cukes.com"
30
+ And I press "Reset password"
31
+ Then I should see "An email has been sent to you with a link to reset your password."
32
+
33
+ @users-password-reset
34
+ Scenario: Reset password page (invalid reset_code)
35
+ Given I am not requesting password reset
36
+ When I go to the reset password page
37
+ Then I should be on the forgot password page
38
+ And I should see "We're sorry, but this reset code has expired or is invalid."
39
+ And I should see "If you are having issues try copying and pasting the URL from your email into your browser or restarting the reset password process."
40
+
41
+ @users-password-reset
42
+ Scenario: Reset password page (valid reset_code)
43
+ Given I am requesting password reset
44
+ When I go to the reset password page
45
+ And I fill in "Password" with "cukes"
46
+ And I fill in "Password confirmation" with "cukes"
47
+ And I press "Reset password"
48
+ Then I should be on the admin root
49
+ And I should see "Password reset successfully for"
@@ -0,0 +1,61 @@
1
+ @refinerycms @users @users-manage
2
+ Feature: Manage Users
3
+ In order to control who can access my website's backend
4
+ As an administrator
5
+ I want to create and manage users
6
+
7
+ Background:
8
+ Given I have no users
9
+
10
+ Scenario: When there are no users, you are invited to create a user
11
+ When I go to the home page
12
+ Then I should see "There are no users yet, so we'll set you up first."
13
+
14
+ @users-add @add
15
+ Scenario: When there are no users, you can create a user
16
+ When I go to the home page
17
+ And I follow "Continue..."
18
+ And I should see "Fill out your details below so that we can get you started."
19
+ And I fill in "Username" with "cucumber"
20
+ And I fill in "Email" with "green@cucumber.com"
21
+ And I fill in "Password" with "greenandjuicy"
22
+ And I fill in "Password confirmation" with "greenandjuicy"
23
+ And I press "Sign up"
24
+ Then I should see "Welcome to Refinery, cucumber."
25
+ And I should see "Latest Activity"
26
+ And I should have 1 user
27
+
28
+ @users-list @list
29
+ Scenario: User List
30
+ Given I have a user named "steven"
31
+ And I am a logged in refinery user
32
+ When I go to the list of users
33
+ Then I should see "steven"
34
+
35
+ @users-add @add
36
+ Scenario: Create User
37
+ Given I have a user named "steven"
38
+ And I am a logged in refinery user
39
+ When I go to the list of users
40
+ And I follow "Add new user"
41
+ And I fill in "Username" with "cucumber"
42
+ And I fill in "Email" with "green@cucumber.com"
43
+ And I fill in "Password" with "greenandjuicy"
44
+ And I fill in "Password confirmation" with "greenandjuicy"
45
+ And I press "Save"
46
+ Then I should be on the list of users
47
+ And I should see "cucumber was successfully added."
48
+ And I should see "cucumber (green@cucumber.com)"
49
+
50
+ @users-edit @edit
51
+ Scenario: Edit User
52
+ Given I have a user named "steven"
53
+ And I am a logged in refinery user
54
+ When I go to the list of users
55
+ And I follow "Edit this user"
56
+ And I fill in "Username" with "cucumber"
57
+ And I fill in "Email" with "green@cucumber.com"
58
+ And I press "Save"
59
+ Then I should be on the list of users
60
+ And I should see "cucumber was successfully updated."
61
+ And I should see "cucumber (green@cucumber.com)"
@@ -0,0 +1,8 @@
1
+ Given /^I have a user with email "(.*)"$/ do |email|
2
+ Factory(:refinery_user, :email => email)
3
+ end
4
+
5
+ Given /^I am (not )?requesting password reset$/ do |action|
6
+ @user = Factory(:refinery_user, :updated_at => 11.minutes.ago)
7
+ @user.send(:generate_reset_password_token!) if action.nil?
8
+ end
@@ -0,0 +1,36 @@
1
+ def login
2
+ visit new_user_session_path
3
+ fill_in("user_login", :with => @user.email)
4
+ fill_in("user_password", :with => 'greenandjuicy')
5
+ click_button("submit_button")
6
+ end
7
+
8
+ Given /^I am a logged in refinery user$/ do
9
+ @user ||= Factory(:refinery_user)
10
+ login
11
+ end
12
+
13
+ Given /^I am a logged in customer$/ do
14
+ @user ||= Factory(:user)
15
+ login
16
+ end
17
+
18
+ Given /^A Refinery user exists$/ do
19
+ @refinery_user ||= Factory(:refinery_user)
20
+ end
21
+
22
+ Given /^I have a user named "(.*)"$/ do |name|
23
+ Factory(:user, :username => name)
24
+ end
25
+
26
+ Given /^I have a R|refinery user named "(.*)"$/ do |name|
27
+ Factory(:refinery_user, :username => name)
28
+ end
29
+
30
+ Given /^I have no users$/ do
31
+ User.delete_all
32
+ end
33
+
34
+ Then /^I should have ([0-9]+) users?$/ do |count|
35
+ User.count.should == count.to_i
36
+ end
@@ -0,0 +1,18 @@
1
+ require 'factory_girl'
2
+
3
+ Factory.define :user do |u|
4
+ u.sequence(:username) { |n| "person#{n}" }
5
+ u.sequence(:email) { |n| "person#{n}@cucumber.com" }
6
+ u.password "greenandjuicy"
7
+ u.password_confirmation "greenandjuicy"
8
+ end
9
+
10
+ Factory.define :refinery_user, :parent => :user do |u|
11
+ u.roles { [ Role[:refinery] ] }
12
+
13
+ u.after_create do |user|
14
+ Refinery::Plugins.registered.each_with_index do |plugin, index|
15
+ user.plugins.create(:name => plugin.name, :position => index)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ module NavigationHelpers
2
+ module Refinery
3
+ module Authentication
4
+ def path_to(page_name)
5
+ case page_name
6
+
7
+ when /the list of users/
8
+ admin_users_path
9
+
10
+ when /the login page/
11
+ new_user_session_path
12
+
13
+ when /the forgot password page/
14
+ new_user_password_path
15
+
16
+ when /the reset password page/
17
+ edit_user_password_path(:reset_password_token => @user.reset_password_token)
18
+ else
19
+ nil
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ module AuthenticatedSystem
2
+ protected
3
+ # Store the URI of the current request in the session.
4
+ #
5
+ # We can return to this location by calling #redirect_back_or_default.
6
+ def store_location
7
+ session[:return_to] = request.fullpath
8
+ end
9
+
10
+ # Redirect to the URI stored by the most recent store_location call or
11
+ # to the passed default.
12
+ def redirect_back_or_default(default)
13
+ redirect_to(session[:return_to] || default)
14
+ session[:return_to] = nil
15
+ end
16
+
17
+ #def current_user
18
+ #current_user
19
+ #end
20
+
21
+ def refinery_user?
22
+ user_signed_in? && current_user.has_role?(:refinery)
23
+ end
24
+
25
+ def self.included(base)
26
+ base.send :helper_method, :current_user, :current_user_session, :user_signed_in?, :refinery_user? if base.respond_to? :helper_method
27
+ end
28
+
29
+ end
data/lib/gemspec.rb ADDED
@@ -0,0 +1,34 @@
1
+ require 'pathname'
2
+ gempath = Pathname.new(File.expand_path('../../', __FILE__))
3
+ require gempath.join('..', 'base', 'lib', 'base', 'refinery')
4
+
5
+ gemspec = <<EOF
6
+ # DO NOT EDIT THIS FILE DIRECTLY! Instead, use lib/gemspec.rb to generate it.
7
+
8
+ Gem::Specification.new do |s|
9
+ s.name = %q{#{gemname = 'refinerycms-authentication'}}
10
+ s.version = %q{#{::Refinery.version}}
11
+ s.summary = %q{Authentication engine for Refinery CMS}
12
+ s.description = %q{The default authentication engine for Refinery CMS}
13
+ s.date = %q{#{Time.now.strftime('%Y-%m-%d')}}
14
+ s.email = %q{info@refinerycms.com}
15
+ s.homepage = %q{http://refinerycms.com}
16
+ s.rubyforge_project = %q{refinerycms}
17
+ s.authors = ['Resolve Digital', 'Philip Arndt', 'David Jones', 'Steven Heidel']
18
+ s.license = %q{MIT}
19
+ s.require_paths = %w(lib)
20
+ s.executables = %w(#{Pathname.glob(gempath.join('bin/*')).map{|d| d.relative_path_from(gempath)}.sort.join(" ")})
21
+
22
+ s.add_dependency 'refinerycms-core', '~> #{::Refinery::Version}'
23
+ s.add_dependency 'devise', '~> 1.1'
24
+
25
+ s.files = [
26
+ '#{%w( **/{*,.rspec,.gitignore,.yardopts} ).map { |file| Pathname.glob(gempath.join(file)) }.flatten.reject{|f|
27
+ !f.exist? or f.to_s =~ /\.gem$/ or (f.directory? and f.children.empty?)
28
+ }.map{|d| d.relative_path_from(gempath)}.uniq.sort.join("',\n '")}'
29
+ ]
30
+ end
31
+ EOF
32
+
33
+ (gemfile = gempath.join("#{gemname}.gemspec")).open('w') {|f| f.puts(gemspec)}
34
+ puts `cd #{gempath} && gem build #{gemfile}` if ARGV.any?{|a| a == "BUILD=true"}
@@ -0,0 +1,8 @@
1
+ require 'refinery/generators'
2
+
3
+ class RefinerycmsAuthentication < ::Refinery::Generators::EngineInstaller
4
+
5
+ source_root File.expand_path('../../../', __FILE__)
6
+ engine_name "authentication"
7
+
8
+ end
@@ -0,0 +1,47 @@
1
+ require 'devise'
2
+ require 'refinerycms-core'
3
+ # Attach authenticated system methods to the ::Refinery::ApplicationController
4
+ require File.expand_path('../authenticated_system', __FILE__)
5
+ [::Refinery::ApplicationController, ::Refinery::ApplicationHelper].each do |c|
6
+ c.class_eval {
7
+ include AuthenticatedSystem
8
+ }
9
+ end
10
+
11
+ module Refinery
12
+ module Authentication
13
+
14
+ class Engine < ::Rails::Engine
15
+ config.autoload_paths += %W( #{config.root}/lib )
16
+
17
+ config.after_initialize do
18
+ ::Refinery::Plugin.register do |plugin|
19
+ plugin.name = "refinery_users"
20
+ plugin.version = %q{0.9.9}
21
+ plugin.menu_match = /(refinery|admin)\/users$/
22
+ plugin.activity = {
23
+ :class => User,
24
+ :title => 'login'
25
+ }
26
+ plugin.url = {:controller => "/admin/users"}
27
+ end
28
+ end
29
+ end
30
+
31
+ class << self
32
+ attr_accessor :root
33
+ def root
34
+ @root ||= Pathname.new(File.expand_path('../../', __FILE__))
35
+ end
36
+ end
37
+ end
38
+
39
+ class << self
40
+ attr_accessor :authentication_login_field
41
+ def authentication_login_field
42
+ @authentication_login_field ||= 'login'
43
+ end
44
+ end
45
+ end
46
+
47
+ ::Refinery.engines << 'authentication'
data/license.md ADDED
@@ -0,0 +1,21 @@
1
+ # MIT License
2
+
3
+ Copyright (c) 2005-2010 [Resolve Digital](http://www.resolvedigital.com)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.