mm-devise 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ coverage/*
2
+ .bundle
3
+ rdoc/*
4
+ pkg
5
+ log
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source :rubygems
2
+
3
+ gem "rails", :git => "git://github.com/rails/rails.git"
4
+
5
+ gem "warden", "0.10.7"
6
+ gem "webrat", "0.7.0"
7
+ gem "mocha", :require => false
8
+ gem "bcrypt-ruby", :require => "bcrypt"
9
+ gem "oauth2"
10
+
11
+ gem 'mongo_mapper', '>= 0.8.2'
12
+ gem 'rails3-generators', '>= 0.12.1'
13
+ gem 'jnunemaker-validatable', '>= 1.8.4'
14
+ gem 'bson_ext', '>= 1.0.4'
15
+
data/Gemfile.lock ADDED
@@ -0,0 +1,116 @@
1
+ GIT
2
+ remote: git://github.com/rails/rails.git
3
+ revision: 4952a80
4
+ specs:
5
+ actionmailer (3.0.0.rc)
6
+ actionpack (= 3.0.0.rc)
7
+ mail (~> 2.2.5)
8
+ actionpack (3.0.0.rc)
9
+ activemodel (= 3.0.0.rc)
10
+ activesupport (= 3.0.0.rc)
11
+ builder (~> 2.1.2)
12
+ erubis (~> 2.6.6)
13
+ i18n (~> 0.4.1)
14
+ rack (~> 1.2.1)
15
+ rack-mount (~> 0.6.9)
16
+ rack-test (~> 0.5.4)
17
+ tzinfo (~> 0.3.22)
18
+ activemodel (3.0.0.rc)
19
+ activesupport (= 3.0.0.rc)
20
+ builder (~> 2.1.2)
21
+ i18n (~> 0.4.1)
22
+ activerecord (3.0.0.rc)
23
+ activemodel (= 3.0.0.rc)
24
+ activesupport (= 3.0.0.rc)
25
+ arel (~> 0.4.0)
26
+ tzinfo (~> 0.3.22)
27
+ activeresource (3.0.0.rc)
28
+ activemodel (= 3.0.0.rc)
29
+ activesupport (= 3.0.0.rc)
30
+ activesupport (3.0.0.rc)
31
+ rails (3.0.0.rc)
32
+ actionmailer (= 3.0.0.rc)
33
+ actionpack (= 3.0.0.rc)
34
+ activerecord (= 3.0.0.rc)
35
+ activeresource (= 3.0.0.rc)
36
+ activesupport (= 3.0.0.rc)
37
+ bundler (>= 1.0.0.rc.1)
38
+ railties (= 3.0.0.rc)
39
+ railties (3.0.0.rc)
40
+ actionpack (= 3.0.0.rc)
41
+ activesupport (= 3.0.0.rc)
42
+ rake (>= 0.8.3)
43
+ thor (~> 0.14.0)
44
+
45
+ GEM
46
+ remote: http://rubygems.org/
47
+ specs:
48
+ abstract (1.0.0)
49
+ addressable (2.1.2)
50
+ arel (0.4.0)
51
+ activesupport (>= 3.0.0.beta)
52
+ bcrypt-ruby (2.1.2)
53
+ bson (1.0.4)
54
+ bson_ext (1.0.4)
55
+ builder (2.1.2)
56
+ erubis (2.6.6)
57
+ abstract (>= 1.0.0)
58
+ faraday (0.4.6)
59
+ addressable (>= 2.1.1)
60
+ rack (>= 1.0.1)
61
+ i18n (0.4.1)
62
+ jnunemaker-validatable (1.8.4)
63
+ activesupport (>= 2.3.4)
64
+ mail (2.2.5)
65
+ activesupport (>= 2.3.6)
66
+ mime-types
67
+ treetop (>= 1.4.5)
68
+ mime-types (1.16)
69
+ mocha (0.9.8)
70
+ rake
71
+ mongo (1.0.7)
72
+ bson (>= 1.0.4)
73
+ mongo_mapper (0.8.2)
74
+ activesupport (>= 2.3.4)
75
+ jnunemaker-validatable (~> 1.8.4)
76
+ plucky (~> 0.3.1)
77
+ multi_json (0.0.4)
78
+ nokogiri (1.4.2)
79
+ oauth2 (0.0.10)
80
+ faraday (~> 0.4.1)
81
+ multi_json (>= 0.0.4)
82
+ plucky (0.3.2)
83
+ mongo (~> 1.0.1)
84
+ polyglot (0.3.1)
85
+ rack (1.2.1)
86
+ rack-mount (0.6.9)
87
+ rack (>= 1.0.0)
88
+ rack-test (0.5.4)
89
+ rack (>= 1.0)
90
+ rails3-generators (0.12.1)
91
+ rake (0.8.7)
92
+ thor (0.14.0)
93
+ treetop (1.4.8)
94
+ polyglot (>= 0.3.1)
95
+ tzinfo (0.3.22)
96
+ warden (0.10.7)
97
+ rack (>= 1.0.0)
98
+ webrat (0.7.0)
99
+ nokogiri (>= 1.2.0)
100
+ rack (>= 1.0)
101
+ rack-test (>= 0.5.3)
102
+
103
+ PLATFORMS
104
+ ruby
105
+
106
+ DEPENDENCIES
107
+ bcrypt-ruby
108
+ bson_ext (>= 1.0.4)
109
+ jnunemaker-validatable (>= 1.8.4)
110
+ mocha
111
+ mongo_mapper (>= 0.8.2)
112
+ oauth2
113
+ rails!
114
+ rails3-generators (>= 0.12.1)
115
+ warden (= 0.10.7)
116
+ webrat (= 0.7.0)
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Kristian Mandrup
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.rdoc ADDED
@@ -0,0 +1,108 @@
1
+ = mm-devise
2
+
3
+ mm-devise will let you use devise (http://github.com/plataformatec/devise) with MongoMapper.
4
+
5
+ The gem gives you the options of 2 ORM setups depending on what library you wish to use for validations:
6
+
7
+ :mongo_mapper::
8
+ Uses Mongo Mapper validations.
9
+ :mongo_mapper_active_model::
10
+ Uses ActiveModel::Validations.
11
+
12
+ The advantage to this is ActiveModel's I18n support for error messages, and
13
+ it uses the same validations lib as devise does by default.
14
+
15
+ Currently only the mongo_mapper option has been tested. Note if you run $ rake test, you will still get a few error and failures.
16
+ This is not due to any error in mm-devise, but rather to a few "issues" with the devise tests themselves IMO.
17
+
18
+ There should be full ActiveModel support in a future version of MongoMapper, after Rails 3 is released.
19
+ ActiveModel support will likely be part of MongoMapper 1.0 (as mentioned by jnunemaker in a post).
20
+
21
+ mm-devise is intended for use with Rails 3 and devise 1.1. It may work with earlier versions, but it's not been tested
22
+
23
+ This README only covers mm-devise specifics.
24
+ Make sure to read the devise README http://github.com/plataformatec/devise/blob/master/README.rdoc
25
+
26
+ == Installation
27
+
28
+ Add devise, mm-devise and Mongo Mapper gems to your Gemfile. The following gems are required
29
+
30
+ gem 'mongo_mapper', '>= 0.8.2'
31
+ gem 'jnunemaker-validatable', '>= 1.8.4'
32
+ gem 'bson_ext', '>= 1.0.4'
33
+ gem 'devise', '~> 1.1.1'
34
+ gem 'mm-devise', '>= 1.1.0'
35
+ gem 'rails3-generators', '>= 0.12.1'
36
+
37
+ You can install http://github.com/indirect/rails3-generators which includes mongo_mapper Model generator
38
+
39
+ gem install rails3-generators
40
+
41
+ Alternatively use bundler to install all required gems in your rails app
42
+
43
+ bundle install
44
+
45
+ Run the generator:
46
+
47
+ rails generate devise:install
48
+
49
+ The generator will install an initializer which describes ALL Devise's
50
+ configuration options and you MUST take a look at it. Make sure to specify
51
+ either mongo_mapper or mongo_mapper_active_model (ActiveModel::Validations) as the orm in the configuration file.
52
+
53
+ To add Devise to any of your models using the generator:
54
+
55
+ rails generate mongo_mapper:devise MODEL
56
+
57
+ Read the README for devise at http://github.com/plataformatec/devise/blob/master/README.rdoc
58
+
59
+ == Test Driven Development - extending this project
60
+
61
+ To develop on this project using TDD, requires the following setup.
62
+ Clone this project into a container folder, fx /projects, so you have fx /projects/mm-devise
63
+ In the same container folder clone devise from github
64
+
65
+ Example:
66
+
67
+ projects $ git clone [repo]\mm-devise.git
68
+ projects $ git clone [repo]\devise.git
69
+ projects $ cd mm-devise
70
+ projects $ bundle install
71
+ projects $ rake test
72
+
73
+ == TODO
74
+
75
+ * Example app
76
+ * Rails templates
77
+
78
+ == Note on Patches/Pull Requests
79
+
80
+ * Fork the project.
81
+ * Make your feature addition or bug fix.
82
+ * Add tests for it. This is important so I don't break it in a
83
+ future version unintentionally.
84
+ * Commit, do not mess with rakefile, version, or history.
85
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
86
+ * Send me a pull request. Bonus points for topic branches.
87
+
88
+ == Maintainers
89
+
90
+ Kristian Mandrup
91
+
92
+ == Contributors
93
+
94
+ Jared Morgan:
95
+ Created the dm-devise gem which was used as a template for the development of this gem
96
+ Also came with suggestions for a few critical fixes and improvements in the code. Thanks :)
97
+
98
+ == Bugs and Feedback
99
+
100
+ For mm-devise specific issues, please create an issue on GitHub at:
101
+
102
+ http://github.com/kristianmandrup/mm-devise/issues
103
+
104
+ == Copyright
105
+
106
+ Copyright (c) 2010 Kristian Mandrup. See LICENSE for details.
107
+
108
+
data/Rakefile ADDED
@@ -0,0 +1,68 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'rake'
4
+ require 'rake/testtask'
5
+ require 'rake/rdoctask'
6
+ require File.join(File.dirname(__FILE__), 'lib', 'mm-devise', 'version')
7
+
8
+ desc 'Default: run tests for all MongoMapper ORM setups.'
9
+ task :default => :pre_commit
10
+
11
+ desc 'Run Devise tests for all MongoMapper ORM setups.'
12
+ task :pre_commit do
13
+ Dir[File.join(File.dirname(__FILE__), 'test', 'orm', '*.rb')].each do |file|
14
+ orm = File.basename(file).split(".").first
15
+ ENV['DEVISE_PATH'] ||= File.expand_path('../devise')
16
+ system "rake test DEVISE_ORM=#{orm} DEVISE_PATH=#{ENV['DEVISE_PATH']}"
17
+ end
18
+ end
19
+
20
+ desc 'Run Devise tests using MongoMapper. Specify path to devise with DEVISE_PATH'
21
+ Rake::TestTask.new(:test) do |test|
22
+ ENV['DEVISE_ORM'] ||= 'mongo_mapper'
23
+ ENV['DEVISE_PATH'] ||= File.expand_path('../devise')
24
+ unless File.exist?(ENV['DEVISE_PATH'])
25
+ puts "Specify the path to devise (e.g. rake DEVISE_PATH=/path/to/devise). Not found at #{ENV['DEVISE_PATH']}"
26
+ exit
27
+ end
28
+ test.libs << 'lib' << 'test'
29
+ test.libs << "#{ENV['DEVISE_PATH']}/lib"
30
+ test.libs << "#{ENV['DEVISE_PATH']}/test"
31
+ test.test_files = FileList["#{ENV['DEVISE_PATH']}/test/**/*_test.rb"] + FileList['test/**/*_test.rb']
32
+ test.verbose = true
33
+ end
34
+
35
+ task :test => :check_dependencies
36
+
37
+ desc 'Generate documentation for dm-devise.'
38
+ Rake::RDocTask.new(:rdoc) do |rdoc|
39
+ rdoc.rdoc_dir = 'rdoc'
40
+ rdoc.title = 'mm-devise #{version}'
41
+ rdoc.options << '--line-numbers' << '--inline-source'
42
+ rdoc.rdoc_files.include('README.rdoc')
43
+ rdoc.rdoc_files.include('lib/**/*.rb')
44
+ end
45
+
46
+ begin
47
+ require 'jeweler'
48
+ Jeweler::Tasks.new do |gem|
49
+ gem.name = "mm-devise"
50
+ gem.version = MongoMapper::Devise::VERSION.dup
51
+ gem.summary = %Q{Support for using MongoMapper ORM with devise}
52
+ gem.description = %Q{dm-devise adds MongoMapper support to devise (http://github.com/plataformatec/devise) for authentication support for Rails}
53
+ gem.email = "jmorgan@morgancreative.net"
54
+ gem.homepage = "http://github.com/kristianmandrup/mm-devise"
55
+ gem.authors = ["Kristian Mandrup"]
56
+ gem.add_dependency 'mongo_mapper', '>= 0.8.2'
57
+ gem.add_dependency 'rails3-generators', '>= 0.12.1'
58
+ gem.add_dependency 'jnunemaker-validatable', '>= 1.8.4'
59
+ gem.add_dependency 'bson_ext', '>= 1.0.4'
60
+ gem.add_dependency 'devise', '>= 1.1.1'
61
+ gem.add_dependency 'warden', '~> 0.10.7'
62
+ gem.add_dependency 'bcrypt-ruby', '~> 2.1.2'
63
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
64
+ end
65
+ Jeweler::GemcutterTasks.new
66
+ rescue LoadError
67
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
68
+ end
@@ -0,0 +1,25 @@
1
+ require 'devise/orm/mongo_mapper/compatibility'
2
+ require 'devise/orm/mongo_mapper/schema'
3
+ require 'devise/orm/mongo_mapper/date_time'
4
+ require 'devise/orm/mongo_mapper/mm-validations'
5
+
6
+ module Devise
7
+ module Orm
8
+ module MongoMapper
9
+ module Hook
10
+ def devise_modules_hook!
11
+ extend Schema
12
+ include Compatibility
13
+ include Validatable
14
+ yield
15
+ return unless Devise.apply_schema
16
+ devise_modules.each { |m| send(m) if respond_to?(m, true) }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ MongoMapper::Document.append_extensions(Devise::Models)
24
+ MongoMapper::Document.append_extensions(Devise::Orm::MongoMapper::Hook)
25
+
@@ -0,0 +1,89 @@
1
+ module Devise
2
+ module Orm
3
+ module MongoMapper
4
+ module Compatibility
5
+ extend ActiveSupport::Concern
6
+
7
+ extend ActiveSupport::Concern
8
+ extend ActiveModel::Naming
9
+
10
+ include ActiveModel::Serializers::Xml
11
+ include ActiveModel::Serializers::JSON
12
+
13
+ def to_xml(options = {}, &block)
14
+ options[:except] ||= []
15
+ options[:except] << :_id
16
+
17
+ super options do |b|
18
+ b.id self.id
19
+ block.call(b) if block_given?
20
+ end
21
+ end
22
+
23
+
24
+ module ClassMethods
25
+ # Hooks for confirmable
26
+ def before_create(*args)
27
+ wrap_hook(:before, :create, *args)
28
+ end
29
+
30
+ def after_create(*args)
31
+ wrap_hook(:after, :create, *args)
32
+ end
33
+
34
+ def before_save(*args)
35
+ wrap_hook(:before, :save, *args)
36
+ end
37
+
38
+ def wrap_hook(action, method, *args)
39
+ options = args.extract_options!
40
+
41
+ args.each do |callback|
42
+ callback_method = :"#{callback}_callback_wrap"
43
+ send action, method, callback_method
44
+ class_eval <<-METHOD, __FILE__, __LINE__ + 1
45
+ def #{callback_method}
46
+ #{callback} if #{options[:if] || true}
47
+ end
48
+ METHOD
49
+ end
50
+ end
51
+
52
+ # Add ActiveRecord like finder
53
+ def find(*args)
54
+ case args.first
55
+ when :first, :all
56
+ send(args.shift, *args)
57
+ else
58
+ where(:'_id' => args.first).first
59
+ end
60
+ end
61
+ end
62
+
63
+ # def changed?
64
+ # dirty?
65
+ # end
66
+
67
+ def save(options=nil)
68
+ if options.is_a?(Hash) && options[:validate] == false
69
+ save!
70
+ else
71
+ super()
72
+ end
73
+ end
74
+
75
+ def update_attribute(name, value)
76
+ update_attributes(name => value)
77
+ end
78
+ #
79
+ # def update_attributes(*args)
80
+ # update(*args)
81
+ # end
82
+
83
+ def invalid?
84
+ !valid?
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,14 @@
1
+ class Date
2
+ unless method_defined?(:gmtime)
3
+ delegate :gmtime, :to => :to_time
4
+ end
5
+
6
+ def utc
7
+ Time.zone.parse("#{hour.to_i - zone.to_i}:#{min}:#{sec}")
8
+ # self.to_datetime.new_offset(0)
9
+ end
10
+
11
+ def to_i
12
+ to_time.utc.to_i
13
+ end
14
+ end
@@ -0,0 +1,89 @@
1
+ module Validatable
2
+ # Monkey-patch Validatable::Errors to support generation of error message from
3
+ # a Symbol.
4
+ class Errors
5
+ @@default_error_messages = {}
6
+
7
+ # Holds a hash with all the default error messages that can be replaced by your own copy or localizations.
8
+ def self.default_error_messages=(default_error_messages)
9
+ @@default_error_messages = default_error_messages
10
+ end
11
+
12
+ def self.default_error_message(key, field, *values)
13
+ field = field.to_s.humanize
14
+ @@default_error_messages[key] % [field, *values].flatten
15
+ end
16
+
17
+ # original add before monkey-patch
18
+ # def add(attribute, message) #:nodoc:
19
+ # errors[attribute.to_sym] = [] if errors[attribute.to_sym].nil?
20
+ # errors[attribute.to_sym] << message
21
+ # end
22
+
23
+ alias_method :original_add, :add
24
+
25
+ # If the message is a Symbol, allow +default_error_message+ to generate
26
+ # the message, including translation.
27
+ def add(field_name, message)
28
+ if message.kind_of?(Symbol)
29
+ message = self.class.default_error_message(message, field_name)
30
+ end
31
+ fld_name = field_name.to_sym
32
+ errors[fld_name] = [] if errors[fld_name].nil?
33
+ original_add(fld_name, message) unless errors[fld_name].include?(message)
34
+ end
35
+ end
36
+ end
37
+
38
+ module Validatable
39
+ class ValidatesPresenceOf < ValidationBase #:nodoc:
40
+ def message(instance)
41
+ super || "can't be blank"
42
+ end
43
+ end
44
+ end
45
+
46
+ module Validatable
47
+ class ValidatesLengthOf < ValidationBase #:nodoc:
48
+ def message(instance)
49
+ min = !within.nil? ? within.first : minimum
50
+ max = !within.nil? ? within.last : maximum
51
+ super || "must be between #{min} and #{max} characters long"
52
+ end
53
+ end
54
+ end
55
+
56
+
57
+ # Default error messages consistent with ActiveModel messages and devise
58
+ # expectations.
59
+ Validatable::Errors.default_error_messages = {
60
+ :absent => 'must be absent',
61
+ :inclusion => 'is not included in the list',
62
+ :exclusion => 'is reserved',
63
+ :invalid => 'is invalid',
64
+ :confirmation => " doesn't match confirmation",
65
+ :accepted => 'must be accepted',
66
+ :nil => 'must not be nil',
67
+ :empty => "can't be empty",
68
+ :blank => "can't be blank",
69
+ :length_between => 'must be between %s and %s characters long',
70
+ :too_long => 'is too long (maximum is %s characters)',
71
+ :too_short => 'is too short (minimum is %s characters)',
72
+ :wrong_length => 'is the wrong length (should be %s characters)',
73
+ :taken => 'has already been taken',
74
+ :not_a_number => 'is not a number',
75
+ :not_an_integer => 'must be an integer',
76
+ :greater_than => 'must be greater than %s',
77
+ :greater_than_or_equal_to => 'must be greater than or equal to ',
78
+ :equal_to => 'must be equal to %s',
79
+ :not_equal_to => 'must not be equal to %s',
80
+ :less_than => 'must be less than %s',
81
+ :less_than_or_equal_to => 'must be less than or equal to %s',
82
+ :value_between => 'must be between %s and %s',
83
+ :odd => 'must be odd',
84
+ :even => 'must be even',
85
+ :primitive => 'must be of type %s',
86
+ :not_found => 'not found',
87
+ :already_confirmed => 'was already confirmed',
88
+ :not_locked => 'was not locked'
89
+ }
@@ -0,0 +1,86 @@
1
+ module MongoMapper
2
+ class ValidationUtil
3
+ class << self
4
+ attr_accessor :counter
5
+
6
+ def inc_counter
7
+ @counter ||= 0
8
+ @counter += 1
9
+ end
10
+ end
11
+ end
12
+ end
13
+
14
+ module Devise
15
+ module Orm
16
+ module MongoMapper
17
+ module Schema
18
+ include Devise::Schema
19
+
20
+ SCHEMA_OPTIONS = {
21
+ :null => :required,
22
+ :limit => :length
23
+ }
24
+
25
+ # Tell how to apply schema methods. This automatically maps :limit to
26
+ # :length and :null to :required.
27
+ def apply_devise_schema(name, type, options={})
28
+ SCHEMA_OPTIONS.each do |old_key, new_key|
29
+ next unless options.key?(old_key)
30
+ if :null == old_key
31
+ # :required is opposite of :null
32
+ options[new_key] = !options.delete(old_key)
33
+ else
34
+ options[new_key] = options.delete(old_key)
35
+ end
36
+ end
37
+
38
+ options.delete(:default) if options[:default].nil?
39
+ required_option = options.delete(:required)
40
+ length_option = options.delete(:length)
41
+
42
+ type = Time if type == DateTime
43
+
44
+ key name, type, options
45
+
46
+ counter = ::MongoMapper::ValidationUtil.inc_counter
47
+
48
+ handle_email(name, counter) if name == :email
49
+ handle_length(name, counter, length_option) if length_option
50
+ handle_required(name, counter) if required_option
51
+ end
52
+
53
+ protected
54
+
55
+ def make_key prefix, name, counter
56
+ "#{prefix}_#{name}_#{counter}"
57
+ end
58
+
59
+ def handle_required name, counter
60
+ key = make_key :presence, name, counter
61
+ validates_presence_of name.to_sym, :key => key
62
+ end
63
+
64
+ def handle_email name, counter
65
+ key = make_key :unique, name, counter
66
+ validates_uniqueness_of name.to_sym, :key => key
67
+ end
68
+
69
+ def handle_length name, counter, length_option
70
+ key = make_key :length, name, counter
71
+ options = case length_option
72
+ when Fixnum
73
+ {:maximum => length_option}
74
+ when Hash
75
+ length_option
76
+ else
77
+ raise ArgumentError, "length validation option must be either a Fixnum or Hash"
78
+ end
79
+ options[:key] = key
80
+
81
+ validates_length_of name.to_sym, options
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,67 @@
1
+ require 'devise/orm/mongo_mapper/compatibility'
2
+ require 'devise/orm/mongo_mapper/schema'
3
+ require 'devise/orm/mongo_mapper/date_time'
4
+
5
+ module Devise
6
+ module Orm
7
+ module MongoMapper
8
+ module Hook
9
+ def devise_modules_hook!
10
+ extend Schema
11
+ include ActiveModel::Validations
12
+ include ActiveModelCompatibility
13
+ include Compatibility
14
+ class << self; attr_reader :descendants; end;
15
+
16
+ def self.validates_uniqueness_of(*fields)
17
+ validates_with UniquenessValidator, _merge_attributes(fields)
18
+ end
19
+
20
+ yield
21
+ return unless Devise.apply_schema
22
+ devise_modules.each { |m| send(m) if respond_to?(m, true) }
23
+ end
24
+ end
25
+
26
+ # http://github.com/jkaramon/mongomapper/blob/rails3/lib/mongo_mapper/plugins/validations.rb
27
+ # ==============================================================
28
+ # validates_each in mongo_mapper should work just fine!
29
+ # ==============================================================
30
+
31
+ # class UniquenessValidator < ActiveModel::EachValidator
32
+ # def validate_each(target, attribute, value)
33
+ # resource = ::DataMapper.repository(target.repository.name) { target.model.first(attribute => value) }
34
+ # if resource.nil? || (target.saved? && resource.key == target.key)
35
+ # return true
36
+ # else
37
+ # target.errors.add(attribute, :taken)
38
+ # return false
39
+ # end
40
+ # end
41
+ # end
42
+
43
+ module ActiveModelCompatibility
44
+ # include ActiveModel::Validations does not make save check valid?.
45
+ # This may not be the best solution, but it seems to work. Note that
46
+ # Compatibility is included after this module; its #save method handles
47
+ # the :validate => false option.
48
+ def save(*args)
49
+ retval = valid? && super(*args)
50
+ assert_save_successful(:save, retval)
51
+ retval
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ MongoMapper::Document.append_extensions(Devise::Models)
59
+ MongoMapper::Document.append_extensions(Devise::Orm::MongoMapper::Hook)
60
+
61
+
62
+ # module MongoMapper
63
+ # module Document
64
+ # extend ::Devise::Models
65
+ # extend ::Devise::Orm::MongoMapper::Hook
66
+ # end
67
+ # end
@@ -0,0 +1,17 @@
1
+ require 'generators/devise/orm_helpers'
2
+
3
+ module MongoMapper
4
+ module Generators
5
+ class DeviseGenerator < Rails::Generators::NamedBase
6
+ include Devise::Generators::OrmHelpers
7
+
8
+ def generate_model
9
+ invoke "mongo_mapper:model", [name] unless model_exists?
10
+ end
11
+
12
+ def inject_devise_content
13
+ inject_into_file model_path, model_contents, :after => "include MongoMapper::Document\n"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ module MongoMapper
2
+ module Devise
3
+ VERSION = '1.1.1'.freeze
4
+ end
5
+ end
@@ -0,0 +1,14 @@
1
+ require 'test_helper'
2
+
3
+ class MongoMapperCompatibilityTest < ActiveSupport::TestCase
4
+ test 'save only when valid' do
5
+ user = new_user(:email => nil)
6
+ assert user.invalid?
7
+ user.save
8
+ assert !user.errors.empty?
9
+
10
+ user = new_user
11
+ assert user.valid?
12
+ assert user.save
13
+ end
14
+ end
@@ -0,0 +1,30 @@
1
+ require 'rails/test_help'
2
+
3
+ class ActiveSupport::TestCase
4
+ setup do
5
+ User.destroy_all
6
+ Admin.destroy_all
7
+ end
8
+ end
9
+
10
+ module MongoMapper
11
+ module Validate
12
+ class ValidationErrors
13
+
14
+ # ActiveModel prepends field names in +#full_messages+, and so the
15
+ # expected result of calling errors[field_name] will not include the
16
+ # field name in the message. However, DM expects the field name to be
17
+ # included in the original message. Assuming that the field name will
18
+ # begin the message, just strip it out (plus the following space) for
19
+ # testing purposes. This has no effect on #full_messages.
20
+
21
+ # def [](property_name)
22
+ # if property_errors = errors[property_name.to_sym]
23
+ # property_errors.collect do |message|
24
+ # message[(property_name.to_s.length + 1)..-1]
25
+ # end
26
+ # end
27
+ # end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,8 @@
1
+ require 'rails/test_help'
2
+
3
+ class ActiveSupport::TestCase
4
+ setup do
5
+ User.destroy_all
6
+ Admin.destroy_all
7
+ end
8
+ end
@@ -0,0 +1,46 @@
1
+ require 'test_helper'
2
+
3
+ # See data_mapper_test.rb in this folder for what this file is doing.
4
+ if DEVISE_ORM == :mongo_mapper
5
+
6
+ class ValidatableTest < ActiveSupport::TestCase
7
+ undef test_should_require_a_password_with_minimum_of_6_characters
8
+
9
+ # DataMapper uses a :value_between error message when given a minimum and
10
+ # maximum; ActiveModel shows either the :too_long or :too_short message.
11
+ test 'should require a password with minimum of 6 characters' do
12
+ user = new_user(:password => '12345', :password_confirmation => '12345')
13
+ assert user.invalid?
14
+ # assert_equal 'is too short (minimum is 6 characters)', user.errors[:password].join
15
+ assert_equal 'must be between 6 and 20 characters long', user.errors[:password].join
16
+ end
17
+
18
+ undef test_should_require_a_password_with_maximum_of_20_characters_long
19
+
20
+ # Same issue as previous test
21
+ test 'should require a password with maximum of 20 characters long' do
22
+ user = new_user(:password => 'x'*21, :password_confirmation => 'x'*21)
23
+ assert user.invalid?
24
+ # assert_equal 'is too long (maximum is 20 characters)', user.errors[:password].join
25
+ assert_equal 'must be between 6 and 20 characters long', user.errors[:password].join
26
+ end
27
+
28
+ end
29
+
30
+ class AuthenticationOthersTest < ActionController::IntegrationTest
31
+
32
+ undef test_registration_in_xml_format_works_when_recognizing_path
33
+
34
+ # DM's validates_confirmation_of requires the confirmation field to be present,
35
+ # while ActiveModel by default skips the confirmation test if the confirmation
36
+ # value is nil. This test takes advantage of AM's behavior, so just add the
37
+ # :password_confirmation value.
38
+ test 'registration in xml format works when recognizing path' do
39
+ assert_nothing_raised do
40
+ # post user_registration_path(:format => 'xml', :user => {:email => "test@example.com", :password => "invalid"} )
41
+ post user_registration_path(:format => 'xml', :user => {:email => "test@example.com", :password => "invalid", :password_confirmation => "invalid"} )
42
+ end
43
+ end
44
+ end
45
+
46
+ end
@@ -0,0 +1,48 @@
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
+
36
+ assert_equal user.current_sign_in_at, user.last_sign_in_at
37
+ assert user.current_sign_in_at >= user.created_at
38
+
39
+ visit destroy_user_session_path
40
+ new_time = 2.seconds.from_now
41
+ Time.stubs(:now).returns(new_time)
42
+
43
+ sign_in_as_user
44
+ user.reload
45
+ assert user.current_sign_in_at > user.last_sign_in_at
46
+ end
47
+ end
48
+
@@ -0,0 +1,12 @@
1
+ require 'shared_admin'
2
+
3
+ class Admin
4
+ include MongoMapper::Document
5
+
6
+ key :username, String
7
+
8
+ timestamps!
9
+
10
+ include SharedAdmin
11
+ include Shim
12
+ end
@@ -0,0 +1,21 @@
1
+ # Shim should be included after SharedUser / SharedAdmin
2
+ module Shim
3
+ def self.included(klass)
4
+ klass.extend(ModelMethods)
5
+ end
6
+
7
+ module ModelMethods
8
+ # Override version in SharedUser which uses #find_by_email.
9
+ def find_for_facebook_oauth(access_token, signed_in_resource=nil)
10
+ data = ActiveSupport::JSON.decode(access_token.get('/me'))
11
+ user = signed_in_resource || User.first(:email => data["email"]) || User.new
12
+ user.update_with_facebook_oauth(access_token, data)
13
+ user.save
14
+ user
15
+ end
16
+
17
+ def create!(*args)
18
+ create(*args)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ require 'shared_user'
2
+
3
+ class User
4
+ include MongoMapper::Document
5
+
6
+ key :username, String
7
+ key :facebook_token, String
8
+ timestamps!
9
+
10
+ include SharedUser
11
+ include Shim
12
+
13
+ unless DEVISE_ORM == :mongo_mapper_active_model
14
+ before_validation :update_password_confirmation
15
+
16
+ # DM's validates_confirmation_of requires the confirmation field to be present,
17
+ # while ActiveModel by default skips the confirmation test if the confirmation
18
+ # value is nil. This test takes advantage of AM's behavior, so just add the
19
+ # :password_confirmation value.
20
+ def update_password_confirmation
21
+ if self.password && self.password_confirmation.nil?
22
+ self.password_confirmation = self.password
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,13 @@
1
+ require 'shared_admin'
2
+ require File.join(File.dirname(__FILE__), '../mongo_mapper/shim.rb')
3
+
4
+ class Admin
5
+ include MongoMapper::Document
6
+
7
+ key :username, String
8
+ timestamps!
9
+
10
+ include SharedAdmin
11
+ include Shim
12
+
13
+ end
@@ -0,0 +1,13 @@
1
+ require 'shared_user'
2
+ require File.join(File.dirname(__FILE__), '../mongo_mapper/shim.rb')
3
+
4
+ class User
5
+ include MongoMapper::Document
6
+
7
+ key :username, String
8
+ key :facebook_token, String
9
+ timestamps!
10
+
11
+ include SharedUser
12
+ include Shim
13
+ end
@@ -0,0 +1,37 @@
1
+ APP_ROOT = File.expand_path("#{DEVISE_PATH}/test/rails_app")
2
+ require "#{APP_ROOT}/config/boot"
3
+
4
+ require "action_controller/railtie"
5
+ require "action_mailer/railtie"
6
+ require "active_resource/railtie"
7
+ require "rails/test_unit/railtie"
8
+
9
+ Bundler.require :default, DEVISE_ORM
10
+
11
+ begin
12
+ require "#{DEVISE_ORM}/railtie"
13
+ rescue LoadError
14
+ end
15
+
16
+ require "devise"
17
+
18
+ module RailsApp
19
+ class Application < Rails::Application
20
+ # Add additional load paths for your own custom dirs
21
+ config.root = APP_ROOT
22
+ config.autoload_paths.reject!{ |p| p =~ /\/app\/(\w+)$/ && !%w(controllers helpers views).include?($1) }
23
+ config.autoload_paths += [ File.expand_path("#{File.dirname(__FILE__)}/../app/#{DEVISE_ORM}") ]
24
+
25
+ # Configure generators values. Many other options are available, be sure to check the documentation.
26
+ # config.generators do |g|
27
+ # g.orm :active_record
28
+ # g.template_engine :erb
29
+ # g.test_framework :test_unit, :fixture => true
30
+ # end
31
+
32
+ # Configure sensitive parameters which will be filtered from the log file.
33
+ config.filter_parameters << :password
34
+
35
+ config.action_mailer.default_url_options = { :host => "localhost:3000" }
36
+ end
37
+ end
@@ -0,0 +1,5 @@
1
+ # Load the rails application
2
+ require File.expand_path('../application', __FILE__)
3
+
4
+ # Initialize the rails application
5
+ RailsApp::Application.initialize!
@@ -0,0 +1,26 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+ DEVISE_ORM = (ENV["DEVISE_ORM"] || :mongo_mapper).to_sym
3
+ DEVISE_PATH = ENV['DEVISE_PATH']
4
+
5
+ puts "\n==> Devise.orm = #{DEVISE_ORM.inspect}"
6
+
7
+ require "rails_app/config/environment"
8
+ require "rails/test_help"
9
+ require "orm/#{DEVISE_ORM}"
10
+
11
+ MongoMapper.connection = Mongo::Connection.new('localhost')
12
+ MongoMapper.database = 'mm-devise-db'
13
+
14
+ I18n.load_path << "#{DEVISE_PATH}/test/support/locale/en.yml"
15
+ require 'mocha'
16
+
17
+ Webrat.configure do |config|
18
+ config.mode = :rails
19
+ config.open_error_files = false
20
+ end
21
+
22
+ Devise::Oauth.test_mode!
23
+
24
+ # Add support to load paths so we can overwrite broken webrat setup
25
+ $:.unshift "#{DEVISE_PATH}/test/support"
26
+ Dir["#{DEVISE_PATH}/test/support/**/*.rb"].each { |f| require f }
metadata ADDED
@@ -0,0 +1,208 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mm-devise
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 1
8
+ - 1
9
+ version: 1.1.1
10
+ platform: ruby
11
+ authors:
12
+ - Kristian Mandrup
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-08-07 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: mongo_mapper
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ - 8
31
+ - 2
32
+ version: 0.8.2
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: rails3-generators
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 0
45
+ - 12
46
+ - 1
47
+ version: 0.12.1
48
+ type: :runtime
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: jnunemaker-validatable
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 1
60
+ - 8
61
+ - 4
62
+ version: 1.8.4
63
+ type: :runtime
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: bson_ext
67
+ prerelease: false
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 1
75
+ - 0
76
+ - 4
77
+ version: 1.0.4
78
+ type: :runtime
79
+ version_requirements: *id004
80
+ - !ruby/object:Gem::Dependency
81
+ name: devise
82
+ prerelease: false
83
+ requirement: &id005 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ segments:
89
+ - 1
90
+ - 1
91
+ - 1
92
+ version: 1.1.1
93
+ type: :runtime
94
+ version_requirements: *id005
95
+ - !ruby/object:Gem::Dependency
96
+ name: warden
97
+ prerelease: false
98
+ requirement: &id006 !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ segments:
104
+ - 0
105
+ - 10
106
+ - 7
107
+ version: 0.10.7
108
+ type: :runtime
109
+ version_requirements: *id006
110
+ - !ruby/object:Gem::Dependency
111
+ name: bcrypt-ruby
112
+ prerelease: false
113
+ requirement: &id007 !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ~>
117
+ - !ruby/object:Gem::Version
118
+ segments:
119
+ - 2
120
+ - 1
121
+ - 2
122
+ version: 2.1.2
123
+ type: :runtime
124
+ version_requirements: *id007
125
+ description: dm-devise adds MongoMapper support to devise (http://github.com/plataformatec/devise) for authentication support for Rails
126
+ email: jmorgan@morgancreative.net
127
+ executables: []
128
+
129
+ extensions: []
130
+
131
+ extra_rdoc_files:
132
+ - LICENSE
133
+ - README.rdoc
134
+ files:
135
+ - .document
136
+ - .gitignore
137
+ - Gemfile
138
+ - Gemfile.lock
139
+ - LICENSE
140
+ - README.rdoc
141
+ - Rakefile
142
+ - lib/devise/orm/mongo_mapper.rb
143
+ - lib/devise/orm/mongo_mapper/compatibility.rb
144
+ - lib/devise/orm/mongo_mapper/date_time.rb
145
+ - lib/devise/orm/mongo_mapper/mm-validations.rb
146
+ - lib/devise/orm/mongo_mapper/schema.rb
147
+ - lib/devise/orm/mongo_mapper_active_model.rb
148
+ - lib/generators/mongo_mapper/devise_generator.rb
149
+ - lib/mm-devise/version.rb
150
+ - test/mongo_mapper/compatibility_test.rb
151
+ - test/orm/mongo_mapper.rb
152
+ - test/orm/mongo_mapper_active_model.rb
153
+ - test/overrides/mm_validations_test.rb
154
+ - test/overrides/mongo_mapper_test.rb
155
+ - test/rails_app/app/mongo_mapper/admin.rb
156
+ - test/rails_app/app/mongo_mapper/shim.rb
157
+ - test/rails_app/app/mongo_mapper/user.rb
158
+ - test/rails_app/app/mongo_mapper_active_model/admin.rb
159
+ - test/rails_app/app/mongo_mapper_active_model/user.rb
160
+ - test/rails_app/config/application.rb
161
+ - test/rails_app/config/environment.rb
162
+ - test/test_helper.rb
163
+ has_rdoc: true
164
+ homepage: http://github.com/kristianmandrup/mm-devise
165
+ licenses: []
166
+
167
+ post_install_message:
168
+ rdoc_options:
169
+ - --charset=UTF-8
170
+ require_paths:
171
+ - lib
172
+ required_ruby_version: !ruby/object:Gem::Requirement
173
+ none: false
174
+ requirements:
175
+ - - ">="
176
+ - !ruby/object:Gem::Version
177
+ segments:
178
+ - 0
179
+ version: "0"
180
+ required_rubygems_version: !ruby/object:Gem::Requirement
181
+ none: false
182
+ requirements:
183
+ - - ">="
184
+ - !ruby/object:Gem::Version
185
+ segments:
186
+ - 0
187
+ version: "0"
188
+ requirements: []
189
+
190
+ rubyforge_project:
191
+ rubygems_version: 1.3.7
192
+ signing_key:
193
+ specification_version: 3
194
+ summary: Support for using MongoMapper ORM with devise
195
+ test_files:
196
+ - test/mongo_mapper/compatibility_test.rb
197
+ - test/orm/mongo_mapper.rb
198
+ - test/orm/mongo_mapper_active_model.rb
199
+ - test/overrides/mm_validations_test.rb
200
+ - test/overrides/mongo_mapper_test.rb
201
+ - test/rails_app/app/mongo_mapper/admin.rb
202
+ - test/rails_app/app/mongo_mapper/shim.rb
203
+ - test/rails_app/app/mongo_mapper/user.rb
204
+ - test/rails_app/app/mongo_mapper_active_model/admin.rb
205
+ - test/rails_app/app/mongo_mapper_active_model/user.rb
206
+ - test/rails_app/config/application.rb
207
+ - test/rails_app/config/environment.rb
208
+ - test/test_helper.rb