dm-devise 0.1.0
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.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/Gemfile +20 -0
- data/Gemfile.lock +252 -0
- data/LICENSE +20 -0
- data/README.rdoc +96 -0
- data/Rakefile +73 -0
- data/dm-devise.gemspec +105 -0
- data/lib/devise/orm/data_mapper.rb +23 -0
- data/lib/devise/orm/data_mapper/compatibility.rb +69 -0
- data/lib/devise/orm/data_mapper/date_time.rb +6 -0
- data/lib/devise/orm/data_mapper/dm-validations.rb +55 -0
- data/lib/devise/orm/data_mapper/schema.rb +31 -0
- data/lib/devise/orm/data_mapper_active_model.rb +41 -0
- data/lib/dm-devise/version.rb +5 -0
- data/lib/generators/data_mapper/devise_generator.rb +17 -0
- data/test/orm/data_mapper.rb +31 -0
- data/test/orm/data_mapper_active_model.rb +10 -0
- data/test/overrides/data_mapper_test.rb +50 -0
- data/test/overrides/dm_validations_test.rb +43 -0
- data/test/rails_app/app/data_mapper/admin.rb +12 -0
- data/test/rails_app/app/data_mapper/shim.rb +2 -0
- data/test/rails_app/app/data_mapper/user.rb +20 -0
- data/test/rails_app/app/data_mapper_active_model/admin.rb +12 -0
- data/test/rails_app/app/data_mapper_active_model/shim.rb +2 -0
- data/test/rails_app/app/data_mapper_active_model/user.rb +20 -0
- data/test/rails_app/config/application.rb +37 -0
- data/test/rails_app/config/environment.rb +5 -0
- data/test/test_helper.rb +21 -0
- metadata +235 -0
data/dm-devise.gemspec
ADDED
@@ -0,0 +1,105 @@
|
|
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{dm-devise}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Jared Morgan"]
|
12
|
+
s.date = %q{2010-07-06}
|
13
|
+
s.description = %q{dm-devise adds DataMapper support to devise (http://github.com/plataformatec/devise) for authentication support for Rails}
|
14
|
+
s.email = %q{jmorgan@morgancreative.net}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"Gemfile",
|
23
|
+
"Gemfile.lock",
|
24
|
+
"LICENSE",
|
25
|
+
"README.rdoc",
|
26
|
+
"Rakefile",
|
27
|
+
"dm-devise.gemspec",
|
28
|
+
"lib/devise/orm/data_mapper.rb",
|
29
|
+
"lib/devise/orm/data_mapper/compatibility.rb",
|
30
|
+
"lib/devise/orm/data_mapper/date_time.rb",
|
31
|
+
"lib/devise/orm/data_mapper/dm-validations.rb",
|
32
|
+
"lib/devise/orm/data_mapper/schema.rb",
|
33
|
+
"lib/devise/orm/data_mapper_active_model.rb",
|
34
|
+
"lib/dm-devise/version.rb",
|
35
|
+
"lib/generators/data_mapper/devise_generator.rb",
|
36
|
+
"test/orm/data_mapper.rb",
|
37
|
+
"test/orm/data_mapper_active_model.rb",
|
38
|
+
"test/overrides/data_mapper_test.rb",
|
39
|
+
"test/overrides/dm_validations_test.rb",
|
40
|
+
"test/rails_app/app/data_mapper/admin.rb",
|
41
|
+
"test/rails_app/app/data_mapper/shim.rb",
|
42
|
+
"test/rails_app/app/data_mapper/user.rb",
|
43
|
+
"test/rails_app/app/data_mapper_active_model/admin.rb",
|
44
|
+
"test/rails_app/app/data_mapper_active_model/shim.rb",
|
45
|
+
"test/rails_app/app/data_mapper_active_model/user.rb",
|
46
|
+
"test/rails_app/config/application.rb",
|
47
|
+
"test/rails_app/config/environment.rb",
|
48
|
+
"test/test_helper.rb"
|
49
|
+
]
|
50
|
+
s.homepage = %q{http://github.com/jm81/dm-devise}
|
51
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
52
|
+
s.require_paths = ["lib"]
|
53
|
+
s.rubygems_version = %q{1.3.7}
|
54
|
+
s.summary = %q{Support for using DataMapper ORM with devise}
|
55
|
+
s.test_files = [
|
56
|
+
"test/test_helper.rb",
|
57
|
+
"test/rails_app/config/environment.rb",
|
58
|
+
"test/rails_app/config/application.rb",
|
59
|
+
"test/rails_app/app/data_mapper/admin.rb",
|
60
|
+
"test/rails_app/app/data_mapper/shim.rb",
|
61
|
+
"test/rails_app/app/data_mapper/user.rb",
|
62
|
+
"test/rails_app/app/data_mapper_active_model/admin.rb",
|
63
|
+
"test/rails_app/app/data_mapper_active_model/shim.rb",
|
64
|
+
"test/rails_app/app/data_mapper_active_model/user.rb",
|
65
|
+
"test/overrides/data_mapper_test.rb",
|
66
|
+
"test/overrides/dm_validations_test.rb",
|
67
|
+
"test/orm/data_mapper.rb",
|
68
|
+
"test/orm/data_mapper_active_model.rb"
|
69
|
+
]
|
70
|
+
|
71
|
+
if s.respond_to? :specification_version then
|
72
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
73
|
+
s.specification_version = 3
|
74
|
+
|
75
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
76
|
+
s.add_runtime_dependency(%q<dm-core>, ["~> 1.0.0"])
|
77
|
+
s.add_runtime_dependency(%q<dm-migrations>, ["~> 1.0.0"])
|
78
|
+
s.add_runtime_dependency(%q<dm-validations>, ["~> 1.0.0"])
|
79
|
+
s.add_runtime_dependency(%q<dm-serializer>, ["~> 1.0.0"])
|
80
|
+
s.add_runtime_dependency(%q<dm-timestamps>, ["~> 1.0.0"])
|
81
|
+
s.add_runtime_dependency(%q<dm-rails>, ["~> 1.0.0"])
|
82
|
+
s.add_runtime_dependency(%q<warden>, ["~> 0.10.7"])
|
83
|
+
s.add_runtime_dependency(%q<bcrypt-ruby>, ["~> 2.1.2"])
|
84
|
+
else
|
85
|
+
s.add_dependency(%q<dm-core>, ["~> 1.0.0"])
|
86
|
+
s.add_dependency(%q<dm-migrations>, ["~> 1.0.0"])
|
87
|
+
s.add_dependency(%q<dm-validations>, ["~> 1.0.0"])
|
88
|
+
s.add_dependency(%q<dm-serializer>, ["~> 1.0.0"])
|
89
|
+
s.add_dependency(%q<dm-timestamps>, ["~> 1.0.0"])
|
90
|
+
s.add_dependency(%q<dm-rails>, ["~> 1.0.0"])
|
91
|
+
s.add_dependency(%q<warden>, ["~> 0.10.7"])
|
92
|
+
s.add_dependency(%q<bcrypt-ruby>, ["~> 2.1.2"])
|
93
|
+
end
|
94
|
+
else
|
95
|
+
s.add_dependency(%q<dm-core>, ["~> 1.0.0"])
|
96
|
+
s.add_dependency(%q<dm-migrations>, ["~> 1.0.0"])
|
97
|
+
s.add_dependency(%q<dm-validations>, ["~> 1.0.0"])
|
98
|
+
s.add_dependency(%q<dm-serializer>, ["~> 1.0.0"])
|
99
|
+
s.add_dependency(%q<dm-timestamps>, ["~> 1.0.0"])
|
100
|
+
s.add_dependency(%q<dm-rails>, ["~> 1.0.0"])
|
101
|
+
s.add_dependency(%q<warden>, ["~> 0.10.7"])
|
102
|
+
s.add_dependency(%q<bcrypt-ruby>, ["~> 2.1.2"])
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'devise/orm/data_mapper/compatibility'
|
2
|
+
require 'devise/orm/data_mapper/schema'
|
3
|
+
require 'devise/orm/data_mapper/date_time'
|
4
|
+
require 'devise/orm/data_mapper/dm-validations'
|
5
|
+
|
6
|
+
module Devise
|
7
|
+
module Orm
|
8
|
+
module DataMapper
|
9
|
+
module Hook
|
10
|
+
def devise_modules_hook!
|
11
|
+
extend Schema
|
12
|
+
include Compatibility
|
13
|
+
yield
|
14
|
+
return unless Devise.apply_schema
|
15
|
+
devise_modules.each { |m| send(m) if respond_to?(m, true) }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
DataMapper::Model.append_extensions(Devise::Models)
|
23
|
+
DataMapper::Model.append_extensions(Devise::Orm::DataMapper::Hook)
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Devise
|
2
|
+
module Orm
|
3
|
+
module DataMapper
|
4
|
+
module Compatibility
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
# Hooks for confirmable
|
9
|
+
def before_create(*args)
|
10
|
+
wrap_hook(:before, :create, *args)
|
11
|
+
end
|
12
|
+
|
13
|
+
def after_create(*args)
|
14
|
+
wrap_hook(:after, :create, *args)
|
15
|
+
end
|
16
|
+
|
17
|
+
def before_save(*args)
|
18
|
+
wrap_hook(:before, :save, *args)
|
19
|
+
end
|
20
|
+
|
21
|
+
def wrap_hook(action, method, *args)
|
22
|
+
options = args.extract_options!
|
23
|
+
|
24
|
+
args.each do |callback|
|
25
|
+
callback_method = :"#{callback}_callback_wrap"
|
26
|
+
send action, method, callback_method
|
27
|
+
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
28
|
+
def #{callback_method}
|
29
|
+
#{callback} if #{options[:if] || true}
|
30
|
+
end
|
31
|
+
METHOD
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Add ActiveRecord like finder
|
36
|
+
def find(*args)
|
37
|
+
case args.first
|
38
|
+
when :first, :all
|
39
|
+
send(args.shift, *args)
|
40
|
+
else
|
41
|
+
get(*args)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def changed?
|
47
|
+
dirty?
|
48
|
+
end
|
49
|
+
|
50
|
+
def save(options=nil)
|
51
|
+
if options.is_a?(Hash) && options[:validate] == false
|
52
|
+
save!
|
53
|
+
else
|
54
|
+
# valid? checking isn't added automatically with ActiveModel
|
55
|
+
valid? && super()
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def update_attributes(*args)
|
60
|
+
update(*args)
|
61
|
+
end
|
62
|
+
|
63
|
+
def invalid?
|
64
|
+
!valid?
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Validate
|
3
|
+
|
4
|
+
# Monkey-patch ValidationErrors to support generation of error message from
|
5
|
+
# a Symbol. This does not translate, consistent with normal DataMapper
|
6
|
+
# operation. Set DataMapper::Validate::ValidationErrors.default_error_messages
|
7
|
+
# if alternate messages are needed (after devise has been initialized).
|
8
|
+
class ValidationErrors
|
9
|
+
alias_method :original_add, :add
|
10
|
+
|
11
|
+
# If the message is a Symbol, allow +default_error_message+ to generate
|
12
|
+
# the message, including translation.
|
13
|
+
def add(field_name, message)
|
14
|
+
if message.kind_of?(Symbol)
|
15
|
+
message = self.class.default_error_message(message, field_name)
|
16
|
+
end
|
17
|
+
original_add(field_name, message) unless errors[field_name].include?(message)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Default error messages consistent with ActiveModel messages and devise
|
24
|
+
# expectations.
|
25
|
+
DataMapper::Validate::ValidationErrors.default_error_messages = {
|
26
|
+
:absent => '%s must be absent',
|
27
|
+
:inclusion => '%s is not included in the list',
|
28
|
+
:exclusion => '%s is reserved',
|
29
|
+
:invalid => '%s is invalid',
|
30
|
+
:confirmation => "%s doesn't match confirmation",
|
31
|
+
:accepted => '%s must be accepted',
|
32
|
+
:nil => '%s must not be nil',
|
33
|
+
:empty => "%s can't be empty",
|
34
|
+
:blank => "%s can't be blank",
|
35
|
+
:length_between => '%s must be between %s and %s characters long',
|
36
|
+
:too_long => '%s is too long (maximum is %s characters)',
|
37
|
+
:too_short => '%s is too short (minimum is %s characters)',
|
38
|
+
:wrong_length => '%s "is the wrong length (should be %s characters)"',
|
39
|
+
:taken => '%s has already been taken',
|
40
|
+
:not_a_number => '%s is not a number',
|
41
|
+
:not_an_integer => '%s must be an integer',
|
42
|
+
:greater_than => '%s must be greater than %s',
|
43
|
+
:greater_than_or_equal_to => '%s must be greater than or equal to %s',
|
44
|
+
:equal_to => '%s must be equal to %s',
|
45
|
+
:not_equal_to => '%s must not be equal to %s',
|
46
|
+
:less_than => '%s must be less than %s',
|
47
|
+
:less_than_or_equal_to => '%s must be less than or equal to %s',
|
48
|
+
:value_between => '%s must be between %s and %s',
|
49
|
+
:odd => 'must be odd',
|
50
|
+
:even => 'must be even',
|
51
|
+
:primitive => '%s must be of type %s',
|
52
|
+
:not_found => '%s not found',
|
53
|
+
:already_confirmed => '%s was already confirmed',
|
54
|
+
:not_locked => '%s was not locked'
|
55
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Devise
|
2
|
+
module Orm
|
3
|
+
module DataMapper
|
4
|
+
module Schema
|
5
|
+
include Devise::Schema
|
6
|
+
|
7
|
+
SCHEMA_OPTIONS = {
|
8
|
+
:null => :required,
|
9
|
+
:limit => :length
|
10
|
+
}
|
11
|
+
|
12
|
+
# Tell how to apply schema methods. This automatically maps :limit to
|
13
|
+
# :length and :null to :required.
|
14
|
+
def apply_devise_schema(name, type, options={})
|
15
|
+
SCHEMA_OPTIONS.each do |old_key, new_key|
|
16
|
+
next unless options.key?(old_key)
|
17
|
+
if :null == old_key
|
18
|
+
# :required is opposite of :null
|
19
|
+
options[new_key] = !options.delete(old_key)
|
20
|
+
else
|
21
|
+
options[new_key] = options.delete(old_key)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
options.delete(:default) if options[:default].nil?
|
26
|
+
property name, type, options
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'devise/orm/data_mapper/compatibility'
|
2
|
+
require 'devise/orm/data_mapper/schema'
|
3
|
+
require 'devise/orm/data_mapper/date_time'
|
4
|
+
|
5
|
+
module Devise
|
6
|
+
module Orm
|
7
|
+
module DataMapper
|
8
|
+
module Hook
|
9
|
+
def devise_modules_hook!
|
10
|
+
extend Schema
|
11
|
+
include Compatibility
|
12
|
+
include ActiveModel::Validations
|
13
|
+
class << self; attr_reader :descendants; end;
|
14
|
+
|
15
|
+
def self.validates_uniqueness_of(*fields)
|
16
|
+
validates_with UniquenessValidator, _merge_attributes(fields)
|
17
|
+
end
|
18
|
+
|
19
|
+
yield
|
20
|
+
return unless Devise.apply_schema
|
21
|
+
devise_modules.each { |m| send(m) if respond_to?(m, true) }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class UniquenessValidator < ActiveModel::EachValidator
|
26
|
+
def validate_each(target, attribute, value)
|
27
|
+
resource = ::DataMapper.repository(target.repository.name) { target.model.first(attribute => value) }
|
28
|
+
if resource.nil? || (target.saved? && resource.key == target.key)
|
29
|
+
return true
|
30
|
+
else
|
31
|
+
target.errors.add(attribute, :taken)
|
32
|
+
return false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
DataMapper::Model.append_extensions(Devise::Models)
|
41
|
+
DataMapper::Model.append_extensions(Devise::Orm::DataMapper::Hook)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'generators/devise/orm_helpers'
|
2
|
+
|
3
|
+
module DataMapper
|
4
|
+
module Generators
|
5
|
+
class DeviseGenerator < Rails::Generators::NamedBase
|
6
|
+
include Devise::Generators::OrmHelpers
|
7
|
+
|
8
|
+
def generate_model
|
9
|
+
invoke "data_mapper:model", [name] unless model_exists?
|
10
|
+
end
|
11
|
+
|
12
|
+
def inject_devise_content
|
13
|
+
inject_into_file model_path, model_contents, :after => "include DataMapper::Resource\n"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rails/test_help'
|
2
|
+
|
3
|
+
DataMapper.auto_migrate!
|
4
|
+
|
5
|
+
class ActiveSupport::TestCase
|
6
|
+
setup do
|
7
|
+
User.all.destroy!
|
8
|
+
Admin.all.destroy!
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module DataMapper
|
13
|
+
module Validate
|
14
|
+
class ValidationErrors
|
15
|
+
|
16
|
+
# ActiveModel prepends field names in +#full_messages+, and so the
|
17
|
+
# expected result of calling errors[field_name] will not include the
|
18
|
+
# field name in the message. However, DM expects the field name to be
|
19
|
+
# included in the original message. Assuming that the field name will
|
20
|
+
# begin the message, just strip it out (plus the following space) for
|
21
|
+
# testing purposes. This has no effect on #full_messages.
|
22
|
+
def [](property_name)
|
23
|
+
if property_errors = errors[property_name.to_sym]
|
24
|
+
property_errors.collect do |message|
|
25
|
+
message[(property_name.to_s.length + 1)..-1]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# This file contains test cases that override devise tests, in the cases that
|
4
|
+
# the difference is values from DM versus those expected by devise is not
|
5
|
+
# particularly important and getting DM to pass the original devise tests would
|
6
|
+
# be difficult.
|
7
|
+
#
|
8
|
+
# This file contains tests shared by both data_mapper and
|
9
|
+
# data_mapper_active_model ORM setups.
|
10
|
+
# Tests specific to the data_mapper orm which uses dm-validations are in dm_validations_test.rb
|
11
|
+
# Tests specific to the data_mapper_active_model orm which uses ActiveModel
|
12
|
+
# validations would be in active_model_test.rb, but there aren't any (I would
|
13
|
+
# be rather surprised if there ever were any).
|
14
|
+
#
|
15
|
+
# For each test, an explanation is given as to why I chose to override the test,
|
16
|
+
# and the original assertion is commented above the DM-specific assertion.
|
17
|
+
|
18
|
+
class TrackableHooksTest < ActionController::IntegrationTest
|
19
|
+
|
20
|
+
undef test_current_and_last_sign_in_timestamps_are_updated_on_each_sign_in
|
21
|
+
|
22
|
+
# DataMapper uses a DateTime type where ActiveRecord uses Time. The test is
|
23
|
+
# that the tested properties are being set, so just check for kind_of?(DateTime)
|
24
|
+
# instead of kind_of?(Time)
|
25
|
+
test "current and last sign in timestamps are updated on each sign in" do
|
26
|
+
user = create_user
|
27
|
+
assert_nil user.current_sign_in_at
|
28
|
+
assert_nil user.last_sign_in_at
|
29
|
+
|
30
|
+
sign_in_as_user
|
31
|
+
user.reload
|
32
|
+
|
33
|
+
# assert_kind_of Time, user.current_sign_in_at
|
34
|
+
# assert_kind_of Time, user.last_sign_in_at
|
35
|
+
assert_kind_of DateTime, user.current_sign_in_at
|
36
|
+
assert_kind_of DateTime, user.last_sign_in_at
|
37
|
+
|
38
|
+
assert_equal user.current_sign_in_at, user.last_sign_in_at
|
39
|
+
assert user.current_sign_in_at >= user.created_at
|
40
|
+
|
41
|
+
visit destroy_user_session_path
|
42
|
+
new_time = 2.seconds.from_now
|
43
|
+
Time.stubs(:now).returns(new_time)
|
44
|
+
|
45
|
+
sign_in_as_user
|
46
|
+
user.reload
|
47
|
+
assert user.current_sign_in_at > user.last_sign_in_at
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|