initial commit

This commit is contained in:
Jelle van der Waa
2016-05-11 10:40:44 +02:00
commit ecaa6e3a35
19 changed files with 1047 additions and 0 deletions

0
js/ABOUT.js Executable file
View File

50
js/MDM.js Executable file
View File

@ -0,0 +1,50 @@
Ext.namespace('Zarafa.plugins.mdm');
/**
* @class Zarafa.plugins.mdm.MDM
* @extends Zarafa.core.Plugin
*
* Plugin which lists all devices connected to a Kopano account with Z-Push.
* The user can wipe, resync, remove a device using buttons in the WebApp.
*/
Zarafa.plugins.mdm.MDM = Ext.extend(Zarafa.core.Plugin, {
/**
* Constructor
* @param {Object} config
* @protected
*/
constructor : function(config) {
config = config || {};
Zarafa.plugins.mdm.MDM.superclass.constructor.call(this, config);
},
/**
* Called after constructor.
* Registers insertion points.
* @protected
*/
initPlugin : function()
{
this.registerInsertionPoint('context.settings.categories', this.createSettingCategory, this);
Zarafa.plugins.mdm.MDM.superclass.initPlugin.apply(this, arguments);
},
/**
* Creates a category in settings for Z-Push
* @return {mdmsettingscategory}
*/
createSettingCategory: function() {
return [{
xtype : 'Zarafa.plugins.mdm.mdmsettingscategory'
}];
}
});
Zarafa.onReady(function() {
container.registerPlugin(new Zarafa.core.PluginMetaData({
name : 'mdm',
displayName : _('Mobile device management'),
pluginConstructor : Zarafa.plugins.mdm.MDM
}));
});

View File

@ -0,0 +1,32 @@
Ext.namespace('Zarafa.plugins.mdm.data');
/**
* @class Zarafa.plugins.mdm.data.JsonCertificateReader
* @extends Zarafa.core.data.JsonReader
*/
Zarafa.plugins.mdm.data.JsonCertificateReader = Ext.extend(Zarafa.core.data.JsonReader, {
/**
* @cfg {Zarafa.core.data.RecordCustomObjectType} customObjectType The custom object type
* which represents the {@link Ext.data.Record records} which should be created using
* {@link Zarafa.core.data.RecordFactory#createRecordObjectByCustomType}.
*/
customObjectType : Zarafa.core.data.RecordCustomObjectType.ZARAFA_MDM,
/**
* @constructor
* @param {Object} meta Metadata configuration options.
* @param {Object} recordType (optional) Optional Record type matches the type
* which must be read from response. If no type is given, it will use the
* record type for the {@link Zarafa.core.data.RecordCustomObjectType#ZARAFA_MDM}.
*/
constructor : function(meta, recordType)
{
meta = Ext.applyIf(meta || {}, {
dynamicRecord : false
});
recordType = Zarafa.core.data.RecordFactory.getRecordClassByCustomType(Zarafa.core.data.RecordCustomObjectType.ZARAFA_MDM);
Zarafa.plugins.mdm.data.JsonCertificateReader.superclass.constructor.call(this, meta, recordType);
}
});

View File

@ -0,0 +1,33 @@
Ext.namespace('Zarafa.plugins.mdm');
Zarafa.plugins.mdm.data.MDMDeviceRecordFields = [
{name: 'entryid', type: 'string'},
{name: 'changed', type: 'boolean'},
{name: 'deviceos', type: 'string'},
{name: 'devicefriendlyname', type: 'string'},
{name: 'deviceinfo', type: 'string'},
{name: 'devicetype', type: 'string'},
{name: 'devicemodel', type: 'string'},
{name: 'domain', type: 'string'},
{name: 'hierarchyuuid', type: 'string'},
// ignoredmessages
{name: 'firstsynctime', type: 'date', dateFormat: 'timestamp'},
{name: 'lastupdatetime', type: 'date', dateFormat: 'timestamp'},
{name: 'wipestatus', type: 'string'},
{name: 'useragent', type: 'string'}
];
/**
*
*/
Zarafa.plugins.mdm.data.MDMDeviceRecord = Ext.extend(Zarafa.core.data.IPMRecord, {});
Zarafa.core.data.RecordCustomObjectType.addProperty('ZARAFA_MDM');
Zarafa.core.data.RecordFactory.addFieldToCustomType(Zarafa.core.data.RecordCustomObjectType.ZARAFA_MDM, Zarafa.plugins.mdm.data.MDMDeviceRecordFields);
Zarafa.core.data.RecordFactory.addListenerToCustomType(Zarafa.core.data.RecordCustomObjectType.ZARAFA_MDM, 'createphantom', function(record)
{
// Phantom records must always be marked as opened (they contain the full set of data)
record.afterOpen();
});
Zarafa.core.data.RecordFactory.setBaseClassToCustomType(Zarafa.core.data.RecordCustomObjectType.ZARAFA_MDM, Zarafa.plugins.mdm.data.MDMDeviceRecord);

33
js/data/MDMDeviceStore.js Normal file
View File

@ -0,0 +1,33 @@
Ext.namespace('Zarafa.plugins.mdm.data');
/**
* @class Zarafa.plugins.mdm.data.MDMDeviceStore
* @extends Zarafa.core.data.ListModuleStore
* @xtype mdm.devicestore
* Store specific for MDM Plugin which creates {@link Zarafa.plugins.mdm.MDMDeviceRecord record}.
*/
Zarafa.plugins.mdm.data.MDMDeviceStore = Ext.extend(Zarafa.core.data.ListModuleStore, {
/**
* @constructor
* @param config Configuration object
*/
constructor : function(config)
{
config = config || {};
Ext.applyIf(config, {
autoLoad : true,
remoteSort: false,
reader : new Zarafa.plugins.mdm.data.JsonCertificateReader(),
writer : new Zarafa.core.data.JsonWriter(),
proxy : new Zarafa.core.data.IPMProxy({
listModuleName: 'pluginmdmmodule',
itemModuleName: 'pluginmdmmodule'
})
});
Zarafa.plugins.mdm.data.MDMDeviceStore.superclass.constructor.call(this, config);
}
});
Ext.reg('mdm.devicestore', Zarafa.plugins.mdm.data.MDMDeviceStore);

0
js/data/MDMRecord.js Normal file
View File

View File

@ -0,0 +1,74 @@
Ext.namespace('Zarafa.plugins.mdm.data');
/**
* @class Zarafa.plugins.mdm.data.MDMResponseHandler
* @extends Zarafa.core.data.AbstractResponseHandler
*
* MDM specific response handler.
*/
Zarafa.plugins.mdm.data.MDMResponseHandler = Ext.extend(Zarafa.core.data.AbstractResponseHandler, {
/**
* @cfg {Function} successCallback The function which
* will be called after success request.
*/
successCallback : Ext.emptyFn,
/**
* @cfg {Function} failureCallback The function which
* will be called after a failed request.
* This callback is optional and currently unused.
*/
failureCallback : Ext.emptyFn,
/**
* Device information from Z-Push's soap call,
* @param {Object} response Object contained the response data.
*/
doInfo : function(response) {
this.successCallback(response);
/*
if(response.status != true && this.failureCallback != null) {
this.failureCallback(response);
} else {
this.successCallback(response);
}*/
},
/**
* Call the successCallback callback function if device was successfully removed from
* z-push server.
* @param {Object} response Object contained the response data.
*/
doRemove : function(response)
{
if(response.remove){
this.successCallback();
}
},
/**
* If wipe request response was successful, show informative message.
* @param {Object} response Object contained the response data.
*/
doWipe : function(response) {
if (response.wipe === true) {
container.getNotifier().notify('info.mdm', _('Mobile Device Manager'), _('Wiping device'));
} else {
container.getNotifier().notify('info.mdm', _('Mobile Device Manager'), _('Password incorrect'));
}
},
/**
* If resync request response was successful, show informative message.
* @param {Object} response Object contained the response data.
*/
doResync : function(response) {
if (response.resync === true) {
container.getNotifier().notify('info.mdm', _('Mobile Device Manager'), _('Full resync in progress'));
}
}
});
Ext.reg('mdm.responsehandler', Zarafa.plugins.mdm.data.MDMResponseHandler);

View File

@ -0,0 +1,67 @@
Ext.namespace('Zarafa.plugins.mdm.data');
/**
* @class Zarafa.plugins.mdm.data.ProvisioningStatus
* @extends Zarafa.core.Enum
*
* @singleton
*/
Zarafa.plugins.mdm.data.ProvisioningStatus = Zarafa.core.Enum.create({
/**
* Denotes that the wipe is not applicable.
* @property
* @type Number
*/
'NOT_APPLICABLE' : 0,
/**
* Denotes that the wipe is ok.
* @property
* @type Number
*/
'OK' : 1,
/**
* Denotes that the wipe is pending.
* @property
* @type Number
*/
'WIPE_PENDING' : 2,
/**
* Denotes that the Wipe is requested.
* @property
* @type Number
*/
'WIPE_REQUESTED' : 4,
/**
* Denotes that the Wipe is executed.
* @property
* @type Number
*/
'WIPE_EXECUTED' : 8,
/**
* Return the display name for the given provisioning Status
* @param {Zarafa.plugins.mdm.js.data.ProvisioningStatus} provisioningStatus The given provisioning status
* @return {String} The display name for the provisioning status
*/
getDisplayName : function(provisioningStatus)
{
switch (provisioningStatus) {
case Zarafa.plugins.mdm.data.ProvisioningStatus.NOT_APPLICABLE:
return _('Not Applicable');
case Zarafa.plugins.mdm.data.ProvisioningStatus.OK:
return _('Ok');
case Zarafa.plugins.mdm.data.ProvisioningStatus.WIPE_PENDING:
return _('Wipe Pending');
case Zarafa.plugins.mdm.data.ProvisioningStatus.WIPE_REQUESTED:
return _('Wipe Requested');
case Zarafa.plugins.mdm.data.ProvisioningStatus.WIPE_EXECUTED:
return _('Wipe Executed');
}
return '';
}
});

View File

@ -0,0 +1,35 @@
Ext.namespace('Zarafa.plugins.mdm.settings');
/*
* Settings category entry for MDM
* @extends
*/
/**
* @class Zarafa.plugins.mdm.settings.MDMSettingsCategory
* @extends Zarafa.settings.ui.SettingsCategory
* @xtype Zarafa.plugins.mdmsettingscategory
*
* The mdm settings category entry.
*/
Zarafa.plugins.mdm.settings.MDMSettingsCategory = Ext.extend(Zarafa.settings.ui.SettingsCategory, {
/**
* @constructor
* @param {Object} config Configuration object
*/
constructor : function(config) {
config = config || {};
Ext.applyIf(config, {
title : _('MDM'),
iconCls : 'icon_mdm_settings',
items : [{
xtype : 'Zarafa.plugins.mdm.mdmsettingswidget'
}]
});
Zarafa.plugins.mdm.settings.MDMSettingsCategory.superclass.constructor.call(this, config);
}
});
Ext.reg('Zarafa.plugins.mdm.mdmsettingscategory', Zarafa.plugins.mdm.settings.MDMSettingsCategory);

View File

@ -0,0 +1,198 @@
Ext.namespace('Zarafa.plugins.mdm.settings');
/**
* @class Zarafa.plugins.mdm.settings.MDMSettingsWidget
* @extends Zarafa.settings.ui.SettingsWidget
*/
Zarafa.plugins.mdm.settings.MDMSettingsWidget = Ext.extend(Zarafa.settings.ui.SettingsWidget, {
/**
* @constructor
* @param {Object} config Configuration object
*/
constructor : function(config)
{
config = config || {};
var store = new Zarafa.plugins.mdm.data.MDMDeviceStore();
Ext.applyIf(config, {
title : _('Mobile Devices'),
items : [{
xtype : 'container',
layout : 'column',
items : [{
xtype : 'grid',
name : _('Devices'),
ref : '../deviceGrid',
height : 400,
store : store,
viewConfig : {
forceFit : true,
deferEmptyText: false,
emptyText: '<div class="emptytext">' + _('No devices connected to your account') + '</div>'
},
columns : [{
dataIndex : 'devicetype',
header : _('Device'),
renderer : Ext.util.Format.htmlEncode
},{
dataIndex : 'useragent',
header : _('User Agent'),
renderer : Ext.util.Format.htmlEncode
},{
dataIndex : 'wipestatus',
header : _('Provisioning Status'),
renderer : Zarafa.plugins.mdm.ui.Renderers.provisioningStatus
},{
dataIndex : 'lastupdatetime',
header : _('Last Update'),
renderer : Ext.util.Format.htmlEncode
},{
dataIndex : 'entryid',
header : _('Device ID'),
renderer : Ext.util.Format.htmlEncode
},{
dataIndex : 'deviceos',
header : _('Device OS'),
hidden : true,
renderer : Ext.util.Format.htmlEncode
},{
dataIndex : 'devicefriendlyname',
header : _('Device Info'),
hidden : true,
renderer : Ext.util.Format.htmlEncode
},{
dataIndex : 'firstsynctime',
header : _('First Sync time'),
hidden : true,
renderer : Ext.util.Format.htmlEncode
}],
buttons : [{
text : _('Wipe Device'),
ref : '../../../wipeBtn',
handler : this.onWipeBtn,
scope : this
},{
text : _('Full resync'),
ref : '../../../resyncBtn',
handler : this.onFullResync,
scope : this
},{
text : _('Remove device'),
ref : '../../../removeBtn',
handler : this.onRemoveDevice,
scope : this
},{
text : _('Refresh'),
ref : '../../../refresh',
handler : this.onRefresh,
scope : this
}]
}]
}]
});
Zarafa.plugins.mdm.settings.MDMSettingsWidget.superclass.constructor.call(this, config);
},
/**
* Function which handles the click event on the "Wipe Device" button, displays
* a MessageBox for the user to confirm the wipe action. The wipe action is
* handled by the onWipeDevice function.
*/
onWipeBtn : function()
{
var msgbox = Ext.MessageBox.show({
title: _('Kopano WebApp'),
msg: _('Do you really want to wipe your device?\n Enter your password to confirm.'),
inputType :'password',
icon: Ext.MessageBox.WARNING,
buttons: Ext.MessageBox.YESNO,
fn: this.onWipeDevice,
prompt: true,
scope: this.deviceGrid
});
// ExtJS does not support a password field.
msgbox.getDialog().body.child('input').dom.type = 'password';
},
/**
* Function which handles the confirmation button in the "wipe device" messagebox.
* Sends an wipe request to PHP for the selected device in the grid.
*
* @param {Ext.Button} button button from the messagebox
* @param {String} password user password
*/
onWipeDevice : function(button, password)
{
if (button === 'yes') {
var selectionModel = this.getSelectionModel();
var record = selectionModel.getSelected();
if (record) {
container.getRequest().singleRequest(
'pluginmdmmodule',
'wipe',
{ 'deviceid' : record.get('entryid'), 'password': password },
new Zarafa.plugins.mdm.data.MDMResponseHandler()
);
}
}
},
/**
* Function which handles the click event on the "Full resync" button, sends a
* full resync request to PHP.
*/
onFullResync : function()
{
var selectionModel = this.deviceGrid.getSelectionModel();
var record = selectionModel.getSelected();
if(record) {
container.getRequest().singleRequest(
'pluginmdmmodule',
'resync',
{ 'deviceid' : record.get('entryid') },
new Zarafa.plugins.mdm.data.MDMResponseHandler()
);
}
},
/**
* Remove all state data for a device, essentially resyncing it.
*/
onRemoveDevice : function()
{
var selectionModel = this.deviceGrid.getSelectionModel();
var record = selectionModel.getSelected();
if(record) {
container.getRequest().singleRequest(
'pluginmdmmodule',
'remove',
{ 'deviceid' : record.get('entryid') },
new Zarafa.plugins.mdm.data.MDMResponseHandler({
successCallback : this.removeDone.createDelegate(this, [record], true)
})
);
}
},
/**
* Callback function triggers when device was successfully removed from the z-push server.
* we have to remove that device from {@link Zarafa.plugins.mdm.data.MDMDeviceStore store}.
* @param {Zarafa.plugins.mdm.data.MDMDeviceRecord} record {@link Zarafa.core.data.IPMRecord record} object
*/
removeDone : function(record)
{
record.getStore().remove(record);
},
/**
* Function which refreshes the store records from the server.
*/
onRefresh : function()
{
this.deviceGrid.getStore().load();
}
});
Ext.reg('Zarafa.plugins.mdm.mdmsettingswidget', Zarafa.plugins.mdm.settings.MDMSettingsWidget);

23
js/ui/Renderers.js Normal file
View File

@ -0,0 +1,23 @@
Ext.namespace('Zarafa.plugins.mdm.ui');
/**
* @class Zarafa.plugins.mdm.ui.Renderers
* Methods of this object can be used as renderers for grid panels, to render
* cells in custom format according to data type
* @singleton
*/
Zarafa.plugins.mdm.ui.Renderers = {
/**
* Render the Provisioning Status.
*
* @param {Object} value The data value for the cell.
* @param {Object} p An object with metadata
* @param {Ext.data.record} record The {Ext.data.Record} from which the data was extracted.
* @return {String} The formatted string
*/
provisioningStatus : function(value, p, record)
{
return Zarafa.plugins.mdm.data.ProvisioningStatus.getDisplayName(parseInt(value));
}
}