Browse Source

Added browser tests for password change.

Martin Edenhofer 10 years ago
parent
commit
67b32a0bca

+ 44 - 27
app/assets/javascripts/app/controllers/_profile/password.js.coffee

@@ -13,8 +13,8 @@ class Index extends App.Controller
     html = $( App.view('profile/password')() )
 
     configure_attributes = [
-      { name: 'password_old', display: 'Current Password', tag: 'input', type: 'password', limit: 100, null: false, class: 'input span4', single: true  },
-      { name: 'password_new', display: 'New Password',     tag: 'input', type: 'password', limit: 100, null: false, class: 'input span4',  },
+      { name: 'password_old', display: 'Current Password', tag: 'input', type: 'password', limit: 100, null: false, class: 'input', single: true  },
+      { name: 'password_new', display: 'New Password',     tag: 'input', type: 'password', limit: 100, null: false, class: 'input',  },
     ]
 
     @form = new App.ControllerForm(
@@ -27,38 +27,55 @@ class Index extends App.Controller
   update: (e) =>
     e.preventDefault()
     params = @formParam(e.target)
-    error = @form.validate(params)
-    if error
-      @formValidate( form: e.target, errors: error )
-      return false
-
     @formDisable(e)
 
+    # validate
+    if params['password_new_confirm'] isnt params['password_new']
+      @formEnable(e)
+      @$('[name=password_new]').val('')
+      @$('[name=password_new_confirm]').val('')
+      @notify
+        type:      'error'
+        msg:       'Can\'t update password, your new passwords do not match. Please try again!'
+        removeAll: true
+      return
+    if !params['password_new']
+      @formEnable(e)
+      @notify
+        type:      'error'
+        msg:       'Please supply your new password!'
+        removeAll: true
+      return
+
     # get data
     @ajax(
-      id:   'password_reset'
-      type: 'POST'
-      url:  @apiPath + '/users/password_change'
-      data: JSON.stringify(params)
+      id:          'password_reset'
+      type:        'POST'
+      url:         @apiPath + '/users/password_change'
+      data:        JSON.stringify(params)
       processData: true
-      success: @success
-      error:   @error
+      success:     @success
     )
 
-  success: (data, status, xhr) =>
-    @render()
-    @notify(
-      type: 'success'
-      msg:  App.i18n.translateContent( 'Password changed successfully!' )
-    )
-
-  error: (xhr, status, error) =>
-    @render()
-    data = JSON.parse( xhr.responseText )
-    @notify(
-      type: 'error'
-      msg:  App.i18n.translateContent( data.message )
-    )
+  success: (data) =>
+    if data.message is 'ok'
+      @render()
+      @notify(
+        type: 'success'
+        msg:  App.i18n.translateContent( 'Password changed successfully!' )
+      )
+    else
+      if data.notice
+        @notify
+          type:      'error'
+          msg:       App.i18n.translateContent( data.notice[0], data.notice[1] )
+          removeAll: true
+      else
+        @notify
+          type:      'error'
+          msg:       'Unable to set password. Please contact your administrator.'
+          removeAll: true
+      @formEnable( @$('form') )
 
 App.Config.set( 'Password', { prio: 2000, name: 'Password', parent: '#profile', target: '#profile/password', controller: Index }, 'NavBarProfile' )
 

+ 35 - 5
app/controllers/users_controller.rb

@@ -383,7 +383,7 @@ POST /api/v1/users/password_reset_verify
 Payload:
 {
   "token": "SoMeToKeN",
-  "password" "new_password"
+  "password": "new_password"
 }
 
 Response:
@@ -398,6 +398,15 @@ curl http://localhost/api/v1/users/password_reset_verify.json -v -u #{login}:#{p
 
   def password_reset_verify
     if params[:password]
+
+      # check password policy
+      result = password_policy(params[:password])
+      if result != true
+        render :json => { :message => 'failed', :notice => result }, :status => :ok
+        return
+      end
+
+      # set new password with token
       user = User.password_reset_via_token( params[:token], params[:password] )
     else
       user = User.password_reset_check( params[:token] )
@@ -405,7 +414,7 @@ curl http://localhost/api/v1/users/password_reset_verify.json -v -u #{login}:#{p
     if user
       render :json => { :message => 'ok', :user_login => user.login }, :status => :ok
     else
-      render :json => { :message => 'failed' }, :status => :unprocessable_entity
+      render :json => { :message => 'failed' }, :status => :ok
     end
   end
 
@@ -434,20 +443,28 @@ curl http://localhost/api/v1/users/password_change.json -v -u #{login}:#{passwor
 
     # check old password
     if !params[:password_old]
-      render :json => { :message => 'Old password needed!' }, :status => :unprocessable_entity
+      render :json => { :message => 'failed', :notice => ['Old password needed!'] }, :status => :ok
       return
     end
     user = User.authenticate( current_user.login, params[:password_old] )
     if !user
-      render :json => { :message => 'Old password is wrong!' }, :status => :unprocessable_entity
+      render :json => { :message => 'failed', :notice => ['Old password is wrong!'] }, :status => :ok
       return
     end
 
     # set new password
     if !params[:password_new]
-      render :json => { :message => 'New password needed!' }, :status => :unprocessable_entity
+      render :json => { :message => 'failed', :notice => ['Please supply your new password!'] }, :status => :ok
+      return
+    end
+
+    # check password policy
+    result = password_policy(params[:password_new])
+    if result != true
+      render :json => { :message => 'failed', :notice => result }, :status => :ok
       return
     end
+
     user.update_attributes( :password => params[:password_new] )
     render :json => { :message => 'ok', :user_login => user.login }, :status => :ok
   end
@@ -674,6 +691,19 @@ curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content
 
   private
 
+  def password_policy(password)
+    if Setting.get('password_min_size') > password.length
+      return ["Can\'t update password, it must be at least %s characters long!", Setting.get('password_min_size')]
+    end
+    if Setting.get('password_need_digit').to_i == 1 && password !~ /\d/
+      return ["Can't update password, it must contain at least 1 digit!"]
+    end
+    if Setting.get('password_min_2_lower_2_upper_characters').to_i == 1 && ( password !~ /[A-Z].*[A-Z]/ || password !~ /[a-z].*[a-z]/ )
+      return ["Can't update password, it must contain at least 2 lowercase and 2 uppercase characters!"]
+    end
+    true
+  end
+
   def permission_check_by_role
     return true if is_role('Admin')
     return true if is_role('Agent')

+ 5 - 7
app/models/user.rb

@@ -203,7 +203,7 @@ returns
     end
 
     # auth ok
-    return user_auth
+    user_auth
   end
 
 =begin
@@ -224,7 +224,7 @@ returns
     user_auth = Sso.check( params )
     return if !user_auth
 
-    return user_auth
+    user_auth
   end
 
 =begin
@@ -257,7 +257,6 @@ returns
       :updated_by_id => 1,
       :created_by_id => 1,
     )
-
   end
 
 =begin
@@ -326,7 +325,7 @@ returns
       :subject   => data[:subject],
       :body      => data[:body]
     )
-    return true
+    true
   end
 
 =begin
@@ -349,7 +348,7 @@ returns
       user.login_failed = 0
       user.save
     end
-    return user
+    user
   end
 
 =begin
@@ -375,7 +374,7 @@ returns
 
     # delete token
     Token.where( :action => 'PasswordReset', :name => token ).first.destroy
-    return user
+    user
   end
 
 =begin
@@ -431,7 +430,6 @@ returns
         self.firstname = scan[0][0].capitalize
         self.lastname  = scan[0][1].capitalize
       end
-
     end
   end
 

+ 1 - 1
db/seeds.rb

@@ -607,7 +607,7 @@ Setting.create_if_not_exists(
       },
     ],
   },
-  :state    => 0,
+  :state    => 1,
   :frontend => true
 )
 Setting.create_if_not_exists(

+ 129 - 2
test/browser/signup_test.rb

@@ -57,8 +57,6 @@ class SignupTest < TestCase
             :execute => 'wait',
             :value   => 5,
           },
-
-          # check action
           {
             :execute => 'check',
             :css     => '.signup',
@@ -73,6 +71,135 @@ class SignupTest < TestCase
           },
         ],
       },
+      {
+        :name     => 'set password',
+        :action   => [
+          {
+            :execute => 'click',
+            :css     => '.navbar-items-personal .user a',
+          },
+          {
+            :execute => 'wait',
+            :value   => 1,
+          },
+          {
+            :execute => 'click',
+            :css     => 'a[href="#profile"]',
+          },
+          {
+            :execute => 'click',
+            :css     => 'a[href="#profile/password"]',
+          },
+          {
+            :execute => 'set',
+            :css     => 'input[name="password_old"]',
+            :value   => 'nonexisiting',
+          },
+          {
+            :execute => 'set',
+            :css     => 'input[name="password_new"]',
+            :value   => 'some',
+          },
+          {
+            :execute => 'set',
+            :css     => 'input[name="password_new_confirm"]',
+            :value   => 'some',
+          },
+          {
+            :execute => 'click',
+            :css     => '.content .btn--primary',
+          },
+          {
+            :execute => 'watch_for',
+            :area    => 'body',
+            :value   => 'old password is wrong',
+          },
+          {
+            :execute => 'set',
+            :css     => 'input[name="password_old"]',
+            :value   => 'some-pass',
+          },
+          {
+            :execute => 'set',
+            :css     => 'input[name="password_new_confirm"]',
+            :value   => 'some2',
+          },
+          {
+            :execute => 'click',
+            :css     => '.content .btn--primary',
+          },
+          {
+            :execute => 'watch_for',
+            :area    => 'body',
+            :value   => 'passwords do not match',
+          },
+          {
+            :execute => 'set',
+            :css     => 'input[name="password_new"]',
+            :value   => 'some',
+          },
+          {
+            :execute => 'set',
+            :css     => 'input[name="password_new_confirm"]',
+            :value   => 'some',
+          },
+          {
+            :execute => 'click',
+            :css     => '.content .btn--primary',
+          },
+          {
+            :execute => 'watch_for',
+            :area    => 'body',
+            :value   => 'it must be at least',
+          },
+          {
+            :execute => 'set',
+            :css     => 'input[name="password_new"]',
+            :value   => 'some-pass-new',
+          },
+          {
+            :execute => 'set',
+            :css     => 'input[name="password_new_confirm"]',
+            :value   => 'some-pass-new',
+          },
+          {
+            :execute => 'click',
+            :css     => '.content .btn--primary',
+          },
+          {
+            :execute => 'watch_for',
+            :area    => 'body',
+            :value   => 'must contain at least 1 digit',
+          },
+          {
+            :execute => 'set',
+            :css     => 'input[name="password_new"]',
+            :value   => 'some-pass-new2',
+          },
+          {
+            :execute => 'set',
+            :css     => 'input[name="password_new_confirm"]',
+            :value   => 'some-pass-new2',
+          },
+          {
+            :execute => 'click',
+            :css     => '.content .btn--primary',
+          },
+          {
+            :execute => 'watch_for',
+            :area    => 'body',
+            :value   => 'Password changed successfully',
+          },
+          {
+            :execute  => 'logout',
+          },
+          {
+            :execute  => 'login',
+            :username => signup_user_email,
+            :password => 'some-pass-new2',
+          },
+        ],
+      },
     ]
     browser_single_test(tests)
   end