0013320: allow admin to reset pin for accounts
authorPhilipp Schüle <p.schuele@metaways.de>
Mon, 10 Jul 2017 08:12:13 +0000 (10:12 +0200)
committersstamer <s.stamer@metaways.de>
Mon, 10 Jul 2017 13:11:20 +0000 (15:11 +0200)
https://forge.tine20.org/view.php?id=13320

Change-Id: Ib7c687e8398b20efcd8831bb3f376a54ab6bb654
Reviewed-on: http://gerrit.tine20.com/customers/5063
Tested-by: Philipp Schüle <p.schuele@metaways.de>
Reviewed-by: sstamer <s.stamer@metaways.de>
Tested-by: sstamer <s.stamer@metaways.de>
tests/tine20/Admin/JsonTest.php
tine20/Admin/Controller/User.php
tine20/Admin/Frontend/Json.php
tine20/Admin/js/user/GridPanel.js

index c2a587b..8b4c56c 100644 (file)
@@ -390,7 +390,26 @@ class Admin_JsonTest extends TestCase
         $authResult = Tinebase_Auth::getInstance()->authenticate($this->objects['user']->accountLoginName, $pw);
         $this->assertTrue($authResult->isValid());
     }
-    
+
+    /**
+     * try to reset pin
+     *
+     * @see 0013320: allow admin to reset pin for accounts
+     */
+    public function testResetPin()
+    {
+        $userArray = $this->testSaveAccount();
+
+        $pw = '1234';
+        $this->_json->resetPin($userArray, $pw);
+
+        $result = Tinebase_Auth::validateSecondFactor($userArray['accountLoginName'], '1234', array(
+            'active' => true,
+            'provider' => 'Tine20',
+        ));
+        $this->assertEquals(Tinebase_Auth::SUCCESS, $result);
+    }
+
     /**
      * testAccountContactModlog
      * 
index 5ef942e..5a5168a 100644 (file)
@@ -167,7 +167,25 @@ class Admin_Controller_User extends Tinebase_Controller_Abstract
             ' Set new password for user ' . $_account->accountLoginName . '. Must change:' . $_mustChange
         );
     }
-    
+
+    /**
+     * set the pin for a given account
+     *
+     * @param  Tinebase_Model_FullUser  $_account the account
+     * @param  string                   $_password the new password
+     * @return void
+     */
+    public function setAccountPin(Tinebase_Model_FullUser $_account, $_password)
+    {
+        $this->checkRight('MANAGE_ACCOUNTS');
+
+        $this->_userBackend->setPin($_account, $_password);
+
+        Tinebase_Core::getLogger()->info(
+            __METHOD__ . '::' . __LINE__ .
+            ' Set new pin for user ' . $_account->accountLoginName);
+    }
+
     /**
      * update user
      *
index 32a42bd..121cb8a 100644 (file)
@@ -467,7 +467,31 @@ class Admin_Frontend_Json extends Tinebase_Frontend_Json_Abstract
         );
         return $result;
     }
-    
+
+    /**
+     * reset password for given account
+     *
+     * @param array|string $account Tinebase_Model_FullUser data or account id
+     * @param string $password the new password
+     * @return array
+     */
+    public function resetPin($account, $password)
+    {
+        if (is_array($account)) {
+            $account = new Tinebase_Model_FullUser($account);
+        } else {
+            $account = Tinebase_User::factory(Tinebase_User::getConfiguredBackend())->getFullUserById($account);
+        }
+
+        $controller = Admin_Controller_User::getInstance();
+        $controller->setAccountPin($account, $password);
+
+        $result = array(
+            'success' => TRUE
+        );
+        return $result;
+    }
+
     /**
      * adds the name of the account to each item in the name property
      * 
index 2a13e85..c72c635 100644 (file)
@@ -73,11 +73,22 @@ Tine.Admin.user.GridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
             iconCls: 'action_password',
             scope: this
         });
-        
+
+        this.actionResetPin = new Ext.Action({
+            requiredGrant: 'readGrant',
+            text: this.app.i18n._('Reset Pin'),
+            disabled: true,
+            handler: this.resetPinHandler,
+            iconCls: 'action_password',
+            hidden: ! Tine.Tinebase.registry.get('secondFactorPinChangeAllowed'),
+            scope: this
+        });
+
         this.actionUpdater.addActions([
             this.actionEnable,
             this.actionDisable,
-            this.actionResetPassword
+            this.actionResetPassword,
+            this.actionResetPin
         ]);
         
         Tine.Admin.user.GridPanel.superclass.initActions.call(this);
@@ -123,6 +134,11 @@ Tine.Admin.user.GridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
                 scale: 'medium',
                 rowspan: 2,
                 iconAlign: 'top'
+            }),
+            Ext.apply(new Ext.Button(this.actionResetPin), {
+                scale: 'medium',
+                rowspan: 2,
+                iconAlign: 'top'
             })
         ];
     },
@@ -138,7 +154,8 @@ Tine.Admin.user.GridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
             this.actionEnable,
             this.actionDisable,
             '-',
-            this.actionResetPassword
+            this.actionResetPassword,
+            this.actionResetPin
         ];
         
         return items;
@@ -264,6 +281,33 @@ Tine.Admin.user.GridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
             }
         }, this);
     },
+
+    resetPinHandler: function(_button, _event) {
+        Ext.MessageBox.prompt(this.app.i18n._('Set new pin'), this.app.i18n._('Please enter the new pin:'), function(_button, _text) {
+            if(_button == 'ok') {
+                var accountObject = this.grid.getSelectionModel().getSelected().data;
+
+                Ext.Ajax.request( {
+                    params: {
+                        method    : 'Admin.resetPin',
+                        account   : accountObject,
+                        password  : _text
+                    },
+                    scope: this,
+                    callback : function(_options, _success, _response) {
+                        if(_success === true) {
+                            var result = Ext.util.JSON.decode(_response.responseText);
+                            if(result.success === true) {
+                                this.grid.getStore().reload();
+                            }
+                        } else {
+                            Tine.Tinebase.ExceptionHandler.handleRequestException(_response);
+                        }
+                    }
+                });
+            }
+        }, this);
+    },
     
     statusRenderer: function (_value, _cellObject, _record, _rowIndex, _colIndex, _dataStore) {
         var gridValue;