Complete implementation of ActiveSync user device management.
authorMichael J. Rubinsky <mrubinsk@horde.org>
Sat, 1 May 2010 14:04:54 +0000 (10:04 -0400)
committerMichael J. Rubinsky <mrubinsk@horde.org>
Sat, 1 May 2010 14:06:15 +0000 (10:06 -0400)
Users can view device status, request a remote wipe of provisioned devices,
remove partnerships, or reset all activesync data...

framework/ActiveSync/lib/Horde/ActiveSync/State/History.php
horde/js/activesyncprefs.js [new file with mode: 0644]
horde/lib/Prefs/Ui.php
horde/templates/prefs/activesync.html

index 324eb02..373390f 100644 (file)
@@ -745,9 +745,18 @@ class Horde_ActiveSync_State_History extends Horde_ActiveSync_State_Base
             $this->getDeviceInfo($devId);
         }
 
-        $query = 'UPDATE ' . $this->_syncDeviceTable . ' SET device_rwstatus = ? WHERE device_id = ?';
+        $query = 'UPDATE ' . $this->_syncDeviceTable . ' SET device_rwstatus = ?';
+        $values = array($status);
+
+        if ($status == Horde_ActiveSync::RWSTATUS_PENDING) {
+            /* Need to clear the policykey to force a provision */
+            $query .= ',device_policykey = ?';
+            $values[] = 0;
+        }
+        $query .= ' WHERE device_id = ?';
+        $values[] = $devId;
         try {
-            $this->_db->update($query, array($status, $devId));
+            $this->_db->update($query, $values);
         } catch (Horde_Db_Exception $e) {
             throw new Horde_ActiveSync_Exception($e);
         }
@@ -781,7 +790,7 @@ class Horde_ActiveSync_State_History extends Horde_ActiveSync_State_Base
         try {
             $this->_db->delete($state_query, $values);
             $this->_db->delete($map_query, $values);
-            if ($device_query) {
+            if (!empty($device_query)) {
                 $this->_db->delete($device_query, $values);
             }
         } catch (Horde_Db_Exception $e) {
diff --git a/horde/js/activesyncprefs.js b/horde/js/activesyncprefs.js
new file mode 100644 (file)
index 0000000..0b06328
--- /dev/null
@@ -0,0 +1,26 @@
+/**
+ * Provides the javascript for managing activesync partner devices.
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ */
+var HordeActiveSyncPrefs = {
+
+    requestRemoteWipe: function(device) {
+        $('wipeid').setValue(device);
+        document.forms.prefs.actionID = 'update_special';
+        document.forms.prefs.submit();
+    },
+
+    cancelRemoteWipe: function(device) {
+        $('cancelwipe').setValue(device);
+        document.forms.prefs.actionID = 'update_special';
+        document.forms.prefs.submit();
+    },
+
+    removeDevice: function(device) {
+        $('removedevice').setValue(device);
+        document.forms.prefs.actionID = 'update_special';
+        document.forms.prefs.submit();
+    }
+}
\ No newline at end of file
index c02a5a4..33fc976 100644 (file)
@@ -401,10 +401,11 @@ class Horde_Prefs_Ui
         } else {
             return _("ActiveSync not activated.");
         }
-
+        Horde::addScriptFile('activesyncprefs.js', 'horde');
         $t = $GLOBALS['injector']->createInstance('Horde_Template');
         $t->setOption('gettext', true);
-        $t->set('reset', $ui->selfUrl()->add('reset', 1));
+        $selfurl = $ui->selfUrl();
+        $t->set('reset', $selfurl->copy()->add('reset', 1));
         $devices = $stateMachine->listDevices(Horde_Auth::getAuth());
         $devs = array();
         $i = 1;
@@ -415,6 +416,7 @@ class Horde_Prefs_Ui
             switch ($device['device_rwstatus']) {
             case Horde_ActiveSync::RWSTATUS_PENDING:
                 $status = '<span class="notice">' . _("Wipe is pending") . '</span>';
+                $device['ispending'] = true;
                 break;
             case Horde_ActiveSync::RWSTATUS_WIPED:
                 $status = '<span class="notice">' . _("Device is wiped") . '</span>';
@@ -422,6 +424,8 @@ class Horde_Prefs_Ui
             default:
                 $status = $device['device_policykey'] ?_("Provisioned") : _("Not Provisioned");
             }
+            $device['wipe'] = $selfurl->copy()->add(array('wipe' => $device['device_id']));
+            $device['remove'] = $selfurl->copy()->add(array('remove' => $device['device_id']));
             $device['status'] = $status . '<br />' . _("Device id:") . $device['device_id'] . '<br />' . _("Policy Key:") . $device['device_policykey'] . '<br />' . _("User Agent:") . $device['device_agent'];
             $devs[] = $device;
         }
@@ -564,21 +568,27 @@ class Horde_Prefs_Ui
      *
      * @param Horde_Core_Prefs_Ui $ui  The UI object.
      */
-     protected function _updateActiveSyncManagement($ui)
-     {
+    protected function _updateActiveSyncManagement($ui)
+    {
         $state_params = $GLOBALS['conf']['activesync']['state']['params'];
         $state_params['db'] = $GLOBALS['injector']->getInstance('Horde_Db_Adapter_Base');
         $stateMachine = new Horde_ActiveSync_State_History($state_params);
         $stateMachine->setLogger($GLOBALS['injector']->getInstance('Horde_Log_Logger'));
-        if ($ui->vars->wipe) {
-            $stateMachine->setDeviceRWStatus($ui->vars->wipe, Horde_ActiveSync::RWSTATUS_PENDING);
+        if ($ui->vars->wipeid) {
+            $stateMachine->setDeviceRWStatus($ui->vars->wipeid, Horde_ActiveSync::RWSTATUS_PENDING);
             $GLOBALS['notification']->push(sprintf(_("A Remote Wipe for device id %s has been initiated. The device will be wiped during the next SYNC request."), $ui->vars->wipe));
+        } elseif ($ui->vars->cancelwipe) {
+            $stateMachine->setDeviceRWStatus($ui->vars->cancelwipe, Horde_ActiveSync::RWSTATUS_OK);
+            $GLOBALS['notification']->push(sprintf(_("The Remote Wipe for device id %s has been cancelled."), $ui->vars->wipe));
         } elseif ($ui->vars->reset) {
             $devices = $stateMachine->listDevices(Horde_Auth::getAuth());
             foreach ($devices as $device) {
                 $stateMachine->removeState(null, $device['device_id']);
             }
             $GLOBALS['notification']->push(_("All state removed for your devices. They will resynchronize next time they connect to the server."));
+        } elseif ($ui->vars->removedevice) {
+            $stateMachine->removeState(null, $ui->vars->removedevice);
         }
-     }
+    }
+
 }
index e6fc2c2..364475c 100644 (file)
@@ -6,21 +6,26 @@
  <gettext>Device Management</gettext>
 </div>
 <if:devices>
+<input type="hidden" id="removedevice" name="removedevice" />
+<input type="hidden" name="wipeid" id="wipeid" />
 <table class="horde-table striped">
  <tr>
-     <th><gettext>Select for wipe</gettext></th>
+     <th><gettext></gettext></th>
      <th><gettext>Device</gettext></th>
      <th><gettext>Last Sync Time</gettext></th>
      <th><gettext>Status</gettext></th>
  </tr>
 <loop:devices>
  <tr class="<tag:devices.class />">
- <if:devices.device_policykey>
-    <td><input type="radio" name="wipe" value="<tag:devices.device_id />" /></td>
- <else:devices.device_policykey>
-    <td><gettext>Not Provisioned</gettext></td>
- </else:devices.device_policykey>
- </if:devices.device_policykey>
+  <td>
+   <if:devices.device_policykey>
+    <input class="button" type="button" value="<gettext>Wipe</gettext>" onclick="HordeActiveSyncPrefs.requestRemoteWipe('<tag:devices.device_id />');" />
+   </if:devices.device_policykey>
+   <if:devices.ispending>
+    <input class="button" type="button" value="<gettext>Cancel Wipe</gettext>" onclick="HordeActiveSyncPrefs.cancelRemoteWipe('<tag:devices.device_id />');" />
+   </if:devices.ispending>
+   <input class="button" type="button" value="<gettext>Remove</gettext>" onclick="HordeActiveSyncPrefs.removeDevice('<tag:devices.device_id />');" />
+  </td>
   <td><tag:devices.device_type /></td>
   <td><tag:devices.ts /></td>
   <td><tag:devices.status /></td>