devise 2.0.0.rc → 2.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of devise might be problematic. Click here for more details.

Files changed (75) hide show
  1. data/CHANGELOG.rdoc +94 -74
  2. data/README.rdoc +2 -2
  3. data/app/controllers/devise/confirmations_controller.rb +3 -6
  4. data/app/controllers/devise/omniauth_callbacks_controller.rb +1 -3
  5. data/app/controllers/devise/passwords_controller.rb +3 -6
  6. data/app/controllers/devise/registrations_controller.rb +34 -41
  7. data/app/controllers/devise/sessions_controller.rb +2 -3
  8. data/app/controllers/devise/unlocks_controller.rb +3 -5
  9. data/app/controllers/devise_controller.rb +169 -0
  10. data/app/views/devise/_links.erb +25 -0
  11. data/app/views/devise/confirmations/new.html.erb +1 -1
  12. data/app/views/devise/passwords/edit.html.erb +1 -1
  13. data/app/views/devise/passwords/new.html.erb +1 -1
  14. data/app/views/devise/registrations/new.html.erb +1 -1
  15. data/app/views/devise/sessions/new.html.erb +1 -1
  16. data/app/views/devise/shared/_links.erb +3 -25
  17. data/app/views/devise/unlocks/new.html.erb +1 -1
  18. data/config/locales/en.yml +4 -6
  19. data/lib/devise.rb +15 -11
  20. data/lib/devise/controllers/helpers.rb +8 -2
  21. data/lib/devise/controllers/scoped_views.rb +0 -16
  22. data/lib/devise/controllers/url_helpers.rb +16 -2
  23. data/lib/devise/failure_app.rb +43 -8
  24. data/lib/devise/models.rb +1 -1
  25. data/lib/devise/models/confirmable.rb +12 -9
  26. data/lib/devise/models/lockable.rb +1 -1
  27. data/lib/devise/models/serializable.rb +5 -2
  28. data/lib/devise/modules.rb +2 -2
  29. data/lib/devise/param_filter.rb +1 -1
  30. data/lib/devise/path_checker.rb +5 -1
  31. data/lib/devise/rails.rb +21 -0
  32. data/lib/devise/rails/routes.rb +16 -10
  33. data/lib/devise/rails/warden_compat.rb +0 -83
  34. data/lib/devise/strategies/authenticatable.rb +2 -2
  35. data/lib/devise/version.rb +1 -1
  36. data/lib/generators/active_record/devise_generator.rb +1 -1
  37. data/lib/generators/active_record/templates/migration.rb +0 -10
  38. data/lib/generators/devise/views_generator.rb +6 -14
  39. data/lib/generators/templates/devise.rb +11 -3
  40. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +1 -1
  41. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +1 -1
  42. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +1 -1
  43. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +1 -1
  44. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +1 -1
  45. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +1 -1
  46. data/test/controllers/internal_helpers_test.rb +1 -2
  47. data/test/failure_app_test.rb +24 -20
  48. data/test/generators/active_record_generator_test.rb +3 -13
  49. data/test/generators/views_generator_test.rb +1 -1
  50. data/test/integration/authenticatable_test.rb +4 -7
  51. data/test/integration/http_authenticatable_test.rb +4 -4
  52. data/test/integration/lockable_test.rb +24 -12
  53. data/test/integration/registerable_test.rb +1 -1
  54. data/test/integration/timeoutable_test.rb +18 -4
  55. data/test/integration/token_authenticatable_test.rb +3 -3
  56. data/test/integration/trackable_test.rb +5 -5
  57. data/test/models/confirmable_test.rb +15 -0
  58. data/test/models/database_authenticatable_test.rb +6 -0
  59. data/test/models/lockable_test.rb +13 -0
  60. data/test/rails_app/app/mongoid/user.rb +1 -1
  61. data/test/rails_app/config/routes.rb +3 -5
  62. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +1 -1
  63. data/test/rails_app/lib/shared_admin.rb +1 -0
  64. data/test/rails_app/log/development.log +13 -0
  65. data/test/rails_app/log/test.log +290988 -0
  66. data/test/support/helpers.rb +0 -17
  67. metadata +105 -57
  68. data/.gitignore +0 -10
  69. data/.travis.yml +0 -13
  70. data/Gemfile +0 -35
  71. data/Gemfile.lock +0 -168
  72. data/Rakefile +0 -34
  73. data/devise.gemspec +0 -25
  74. data/lib/devise/controllers/internal_helpers.rb +0 -161
  75. data/lib/devise/controllers/shared_helpers.rb +0 -26
@@ -34,87 +34,4 @@ class Warden::SessionSerializer
34
34
  end
35
35
  end
36
36
  end
37
- end
38
-
39
- unless Devise.rack_session?
40
- # We cannot use Rails Indifferent Hash because it messes up the flash object.
41
- class Devise::IndifferentHash < Hash
42
- alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
43
- alias_method :regular_update, :update unless method_defined?(:regular_update)
44
-
45
- def [](key)
46
- super(convert_key(key))
47
- end
48
-
49
- def []=(key, value)
50
- regular_writer(convert_key(key), value)
51
- end
52
-
53
- alias_method :store, :[]=
54
-
55
- def update(other_hash)
56
- other_hash.each_pair { |key, value| regular_writer(convert_key(key), value) }
57
- self
58
- end
59
-
60
- alias_method :merge!, :update
61
-
62
- def key?(key)
63
- super(convert_key(key))
64
- end
65
-
66
- alias_method :include?, :key?
67
- alias_method :has_key?, :key?
68
- alias_method :member?, :key?
69
-
70
- def fetch(key, *extras)
71
- super(convert_key(key), *extras)
72
- end
73
-
74
- def values_at(*indices)
75
- indices.collect {|key| self[convert_key(key)]}
76
- end
77
-
78
- def merge(hash)
79
- self.dup.update(hash)
80
- end
81
-
82
- def delete(key)
83
- super(convert_key(key))
84
- end
85
-
86
- def stringify_keys!; self end
87
- def stringify_keys; dup end
88
-
89
- undef :symbolize_keys!
90
- def symbolize_keys; to_hash.symbolize_keys end
91
-
92
- def to_options!; self end
93
- def to_hash; Hash.new.update(self) end
94
-
95
- protected
96
-
97
- def convert_key(key)
98
- key.kind_of?(Symbol) ? key.to_s : key
99
- end
100
- end
101
-
102
- class ActionDispatch::Request
103
- def reset_session
104
- session.destroy if session && session.respond_to?(:destroy)
105
- self.session = {}
106
- @env['action_dispatch.request.flash_hash'] = nil
107
- end
108
- end
109
-
110
- Warden::Manager.after_set_user :event => [:set_user, :authentication] do |record, warden, options|
111
- if options[:scope] && warden.authenticated?(options[:scope])
112
- request, flash = warden.request, warden.env['action_dispatch.request.flash_hash']
113
- backup = request.session.to_hash
114
- backup.delete("session_id")
115
- request.reset_session
116
- warden.env['action_dispatch.request.flash_hash'] = flash
117
- request.session = Devise::IndifferentHash.new.update(backup)
118
- end
119
- end
120
37
  end
@@ -105,7 +105,7 @@ module Devise
105
105
  # Helper to decode credentials from HTTP.
106
106
  def decode_credentials
107
107
  return [] unless request.authorization && request.authorization =~ /^Basic (.*)/m
108
- ActiveSupport::Base64.decode64($1).split(/:/, 2)
108
+ Base64.decode64($1).split(/:/, 2)
109
109
  end
110
110
 
111
111
  # Sets the authentication hash and the password from params_auth_hash or http_auth_hash.
@@ -156,4 +156,4 @@ module Devise
156
156
  end
157
157
  end
158
158
  end
159
- end
159
+ end
@@ -1,3 +1,3 @@
1
1
  module Devise
2
- VERSION = "2.0.0.rc".freeze
2
+ VERSION = "2.0.0.rc2".freeze
3
3
  end
@@ -62,7 +62,7 @@ CONTENT
62
62
  # t.string :unlock_token # Only if unlock strategy is :email or :both
63
63
  # t.datetime :locked_at
64
64
 
65
- # Token authenticatable
65
+ ## Token authenticatable
66
66
  # t.string :authentication_token
67
67
  RUBY
68
68
  end
@@ -1,9 +1,5 @@
1
1
  class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration
2
- <% if ::Rails::VERSION::MAJOR == 3 && ::Rails::VERSION::MINOR >= 1 -%>
3
2
  def change
4
- <% else -%>
5
- def self.up
6
- <% end -%>
7
3
  create_table(:<%= table_name %>) do |t|
8
4
  <%= migration_data -%>
9
5
 
@@ -20,10 +16,4 @@ class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration
20
16
  # add_index :<%= table_name %>, :unlock_token, :unique => true
21
17
  # add_index :<%= table_name %>, :authentication_token, :unique => true
22
18
  end
23
-
24
- <% unless ::Rails::VERSION::MAJOR == 3 && ::Rails::VERSION::MINOR >= 1 -%>
25
- def self.down
26
- drop_table :<%= table_name %>
27
- end
28
- <% end -%>
29
19
  end
@@ -32,17 +32,6 @@ module Devise
32
32
  end
33
33
  end
34
34
 
35
- class SharedViewsGenerator < Rails::Generators::Base #:nodoc:
36
- include ViewPathTemplates
37
- source_root File.expand_path("../../../../app/views/devise", __FILE__)
38
- desc "Copies shared Devise views to your application."
39
-
40
- # Override copy_views to just copy mailer and shared.
41
- def copy_views
42
- view_directory :shared
43
- end
44
- end
45
-
46
35
  class FormForGenerator < Rails::Generators::Base #:nodoc:
47
36
  include ViewPathTemplates
48
37
  source_root File.expand_path("../../../../app/views/devise", __FILE__)
@@ -80,12 +69,15 @@ module Devise
80
69
  end
81
70
 
82
71
  class ViewsGenerator < Rails::Generators::Base
72
+ include ViewPathTemplates
73
+
74
+ source_root File.expand_path("../../../../app/views/devise", __FILE__)
83
75
  desc "Copies Devise views to your application."
84
76
 
85
- argument :scope, :required => false, :default => nil,
86
- :desc => "The scope to copy views to"
77
+ def copy_views
78
+ copy_file "_links.erb", "#{target_path}/_links.erb"
79
+ end
87
80
 
88
- invoke SharedViewsGenerator
89
81
  hook_for :form_builder, :aliases => "-b",
90
82
  :desc => "Form builder to be used",
91
83
  :default => defined?(SimpleForm) ? "simple_form_for" : "form_for"
@@ -46,9 +46,15 @@ Devise.setup do |config|
46
46
  config.strip_whitespace_keys = [ :email ]
47
47
 
48
48
  # Tell if authentication through request.params is enabled. True by default.
49
+ # It can be set to an array that will enable params authentication only for the
50
+ # given strategies, for example, `config.params_authenticatable = [:database]` will
51
+ # enable it only for database (email + password) authentication.
49
52
  # config.params_authenticatable = true
50
53
 
51
54
  # Tell if authentication through HTTP Basic Auth is enabled. False by default.
55
+ # It can be set to an array that will enable http authentication only for the
56
+ # given strategies, for example, `config.http_authenticatable = [:token]` will
57
+ # enable it only for token authentication.
52
58
  # config.http_authenticatable = false
53
59
 
54
60
  # If http headers should be returned for AJAX requests. True by default.
@@ -64,6 +70,9 @@ Devise.setup do |config|
64
70
 
65
71
  # By default Devise will store the user in session. You can skip storage for
66
72
  # :http_auth and :token_auth by adding those symbols to the array below.
73
+ # Notice that if you are skipping storage for all authentication paths, you
74
+ # may want to disable generating routes to Devise's sessions controller by
75
+ # passing :skip => :sessions to `devise_for` in your config/routes.rb
67
76
  config.skip_session_storage = [:http_auth]
68
77
 
69
78
  # ==> Configuration for :database_authenticatable
@@ -192,9 +201,8 @@ Devise.setup do |config|
192
201
  # If you have any extra navigational formats, like :iphone or :mobile, you
193
202
  # should add them to the navigational formats lists.
194
203
  #
195
- # The :"*/*" and "*/*" formats below is required to match Internet
196
- # Explorer requests.
197
- # config.navigational_formats = [:"*/*", "*/*", :html]
204
+ # The "*/*" below is required to match Internet Explorer requests.
205
+ # config.navigational_formats = ["*/*", :html]
198
206
 
199
207
  # The default HTTP method used to sign out a resource. Default is :delete.
200
208
  config.sign_out_via = :delete
@@ -12,4 +12,4 @@
12
12
  </div>
13
13
  <% end %>
14
14
 
15
- <%= render :partial => "devise/shared/links" %>
15
+ <%= render "links" %>
@@ -16,4 +16,4 @@
16
16
  </div>
17
17
  <% end %>
18
18
 
19
- <%= render :partial => "devise/shared/links" %>
19
+ <%= render "links" %>
@@ -12,4 +12,4 @@
12
12
  </div>
13
13
  <% end %>
14
14
 
15
- <%= render :partial => "devise/shared/links" %>
15
+ <%= render "links" %>
@@ -14,4 +14,4 @@
14
14
  </div>
15
15
  <% end %>
16
16
 
17
- <%= render :partial => "devise/shared/links" %>
17
+ <%= render "links" %>
@@ -12,4 +12,4 @@
12
12
  </div>
13
13
  <% end %>
14
14
 
15
- <%= render :partial => "devise/shared/links" %>
15
+ <%= render "links" %>
@@ -12,4 +12,4 @@
12
12
  </div>
13
13
  <% end %>
14
14
 
15
- <%= render :partial => "devise/shared/links" %>
15
+ <%= render "links" %>
@@ -1,7 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class MyController < ApplicationController
4
- include Devise::Controllers::InternalHelpers
3
+ class MyController < DeviseController
5
4
  end
6
5
 
7
6
  class HelpersTest < ActionController::TestCase
@@ -3,7 +3,9 @@ require 'ostruct'
3
3
 
4
4
  class FailureTest < ActiveSupport::TestCase
5
5
  class RootFailureApp < Devise::FailureApp
6
- undef_method :new_user_session_path
6
+ def fake_app
7
+ Object.new
8
+ end
7
9
  end
8
10
 
9
11
  def self.context(name, &block)
@@ -41,15 +43,17 @@ class FailureTest < ActiveSupport::TestCase
41
43
  end
42
44
 
43
45
  test 'return to the root path if no session path is available' do
44
- call_failure :app => RootFailureApp
45
- assert_equal 302, @response.first
46
- assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
47
- assert_equal 'http://test.host/', @response.second['Location']
46
+ swap Devise, :router_name => :fake_app do
47
+ call_failure :app => RootFailureApp
48
+ assert_equal 302, @response.first
49
+ assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
50
+ assert_equal 'http://test.host/', @response.second['Location']
51
+ end
48
52
  end
49
53
 
50
54
  test 'uses the proxy failure message as symbol' do
51
- call_failure('warden' => OpenStruct.new(:message => :test))
52
- assert_equal 'test', @request.flash[:alert]
55
+ call_failure('warden' => OpenStruct.new(:message => :invalid))
56
+ assert_equal 'Invalid email or password.', @request.flash[:alert]
53
57
  assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
54
58
  end
55
59
 
@@ -73,14 +77,14 @@ class FailureTest < ActiveSupport::TestCase
73
77
 
74
78
  test 'works for any navigational format' do
75
79
  swap Devise, :navigational_formats => [:xml] do
76
- call_failure('formats' => :xml)
80
+ call_failure('formats' => Mime::XML)
77
81
  assert_equal 302, @response.first
78
82
  end
79
83
  end
80
84
 
81
85
  test 'redirects the correct format if it is a non-html format request' do
82
86
  swap Devise, :navigational_formats => [:js] do
83
- call_failure('formats' => :js)
87
+ call_failure('formats' => Mime::JS)
84
88
  assert_equal 'http://test.host/users/sign_in.js', @response.second["Location"]
85
89
  end
86
90
  end
@@ -88,18 +92,18 @@ class FailureTest < ActiveSupport::TestCase
88
92
 
89
93
  context 'For HTTP request' do
90
94
  test 'return 401 status' do
91
- call_failure('formats' => :xml)
95
+ call_failure('formats' => Mime::XML)
92
96
  assert_equal 401, @response.first
93
97
  end
94
98
 
95
99
  test 'return appropriate body for xml' do
96
- call_failure('formats' => :xml)
100
+ call_failure('formats' => Mime::XML)
97
101
  result = %(<?xml version="1.0" encoding="UTF-8"?>\n<errors>\n <error>You need to sign in or sign up before continuing.</error>\n</errors>\n)
98
102
  assert_equal result, @response.last.body
99
103
  end
100
104
 
101
105
  test 'return appropriate body for json' do
102
- call_failure('formats' => :json)
106
+ call_failure('formats' => Mime::JSON)
103
107
  result = %({"error":"You need to sign in or sign up before continuing."})
104
108
  assert_equal result, @response.last.body
105
109
  end
@@ -110,26 +114,26 @@ class FailureTest < ActiveSupport::TestCase
110
114
  end
111
115
 
112
116
  test 'return WWW-authenticate headers if model allows' do
113
- call_failure('formats' => :xml)
117
+ call_failure('formats' => Mime::XML)
114
118
  assert_equal 'Basic realm="Application"', @response.second["WWW-Authenticate"]
115
119
  end
116
120
 
117
121
  test 'does not return WWW-authenticate headers if model does not allow' do
118
122
  swap Devise, :http_authenticatable => false do
119
- call_failure('formats' => :xml)
123
+ call_failure('formats' => Mime::XML)
120
124
  assert_nil @response.second["WWW-Authenticate"]
121
125
  end
122
126
  end
123
127
 
124
128
  test 'works for any non navigational format' do
125
129
  swap Devise, :navigational_formats => [] do
126
- call_failure('formats' => :html)
130
+ call_failure('formats' => Mime::HTML)
127
131
  assert_equal 401, @response.first
128
132
  end
129
133
  end
130
134
 
131
135
  test 'uses the failure message as response body' do
132
- call_failure('formats' => :xml, 'warden' => OpenStruct.new(:message => :invalid))
136
+ call_failure('formats' => Mime::XML, 'warden' => OpenStruct.new(:message => :invalid))
133
137
  assert_match '<error>Invalid email or password.</error>', @response.third.body
134
138
  end
135
139
 
@@ -137,7 +141,7 @@ class FailureTest < ActiveSupport::TestCase
137
141
  context 'when http_authenticatable_on_xhr is false' do
138
142
  test 'dont return 401 with navigational formats' do
139
143
  swap Devise, :http_authenticatable_on_xhr => false do
140
- call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
144
+ call_failure('formats' => Mime::HTML, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
141
145
  assert_equal 302, @response.first
142
146
  assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
143
147
  end
@@ -145,7 +149,7 @@ class FailureTest < ActiveSupport::TestCase
145
149
 
146
150
  test 'dont return 401 with non navigational formats' do
147
151
  swap Devise, :http_authenticatable_on_xhr => false do
148
- call_failure('formats' => :json, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
152
+ call_failure('formats' => Mime::JSON, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
149
153
  assert_equal 302, @response.first
150
154
  assert_equal 'http://test.host/users/sign_in.json', @response.second["Location"]
151
155
  end
@@ -155,14 +159,14 @@ class FailureTest < ActiveSupport::TestCase
155
159
  context 'when http_authenticatable_on_xhr is true' do
156
160
  test 'return 401' do
157
161
  swap Devise, :http_authenticatable_on_xhr => true do
158
- call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
162
+ call_failure('formats' => Mime::HTML, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
159
163
  assert_equal 401, @response.first
160
164
  end
161
165
  end
162
166
 
163
167
  test 'skip WWW-Authenticate header' do
164
168
  swap Devise, :http_authenticatable_on_xhr => true do
165
- call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
169
+ call_failure('formats' => Mime::HTML, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
166
170
  assert_nil @response.second['WWW-Authenticate']
167
171
  end
168
172
  end
@@ -8,20 +8,10 @@ if DEVISE_ORM == :active_record
8
8
  destination File.expand_path("../../tmp", __FILE__)
9
9
  setup :prepare_destination
10
10
 
11
- test "all files are properly created" do
12
- with_rails_version :MAJOR => 3, :MINOR => 0 do
13
- run_generator %w(monster)
14
- assert_file "app/models/monster.rb", /devise/, /attr_accessible (:[a-z_]+(, )?)+/
15
- assert_migration "db/migrate/devise_create_monsters.rb", /def self\.up/
16
- end
17
- end
18
-
19
11
  test "all files are properly created with rails31 migration syntax" do
20
- with_rails_version :MAJOR => 3, :MINOR => 1 do
21
- run_generator %w(monster)
22
- assert_file "app/models/monster.rb", /devise/, /attr_accessible (:[a-z_]+(, )?)+/
23
- assert_migration "db/migrate/devise_create_monsters.rb", /def change/
24
- end
12
+ run_generator %w(monster)
13
+ assert_file "app/models/monster.rb", /devise/, /attr_accessible (:[a-z_]+(, )?)+/
14
+ assert_migration "db/migrate/devise_create_monsters.rb", /def change/
25
15
  end
26
16
 
27
17
  test "update model migration when model exists" do
@@ -46,7 +46,7 @@ class ViewsGeneratorTest < Rails::Generators::TestCase
46
46
  assert_file "app/views/#{scope}/registrations/new.html.erb"
47
47
  assert_file "app/views/#{scope}/registrations/edit.html.erb"
48
48
  assert_file "app/views/#{scope}/sessions/new.html.erb"
49
- assert_file "app/views/#{scope}/shared/_links.erb"
50
49
  assert_file "app/views/#{scope}/unlocks/new.html.erb"
50
+ assert_file "app/views/#{scope}/_links.erb"
51
51
  end
52
52
  end
@@ -407,7 +407,10 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
407
407
 
408
408
  test 'sign in stub in xml format' do
409
409
  get new_user_session_path(:format => 'xml')
410
- assert_equal "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<user>\n <email></email>\n <password nil=\"true\"></password>\n</user>\n", response.body
410
+ assert_match '<?xml version="1.0" encoding="UTF-8"?>', response.body
411
+ assert_match /<user>.*<\/user>/m, response.body
412
+ assert_match '<email></email>', response.body
413
+ assert_match '<password nil="true"></password>', response.body
411
414
  end
412
415
 
413
416
  test 'sign in stub in json format' do
@@ -432,12 +435,6 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
432
435
  assert_not warden.authenticated?(:admin)
433
436
  end
434
437
 
435
- test 'uses the mapping from nested devise_for call' do
436
- sign_in_as_user :visit => "/devise_for/sign_in"
437
- assert warden.authenticated?(:user)
438
- assert_not warden.authenticated?(:admin)
439
- end
440
-
441
438
  test 'sign in with xml format returns xml response' do
442
439
  create_user
443
440
  post user_session_path(:format => 'xml'), :user => {:email => "user@test.com", :password => '123456'}