diff --git a/management/univention-directory-manager-modules/modules/univention/admin/__init__.py b/management/univention-directory-manager-modules/modules/univention/admin/__init__.py index ed1239d..5707fa2 100644 --- a/management/univention-directory-manager-modules/modules/univention/admin/__init__.py +++ b/management/univention-directory-manager-modules/modules/univention/admin/__init__.py @@ -198,7 +198,8 @@ def __init__( include_in_default_search=False, nonempty_is_default=False, readonly_when_synced=False, - size=None): + size=None, + copyable=False): self.short_description = short_description self.long_description = long_description @@ -228,6 +229,7 @@ def __init__( self.nonempty_is_default = nonempty_is_default self.readonly_when_synced = readonly_when_synced self.size = size + self.copyable = copyable def new(self): if self.multivalue: diff --git a/management/univention-directory-manager-modules/modules/univention/admin/handlers/users/user.py b/management/univention-directory-manager-modules/modules/univention/admin/handlers/users/user.py index 442eda9..da6b793 100644 --- a/management/univention-directory-manager-modules/modules/univention/admin/handlers/users/user.py +++ b/management/univention-directory-manager-modules/modules/univention/admin/handlers/users/user.py @@ -73,7 +73,7 @@ class vacationResendDays(univention.admin.syntax.select): module = 'users/user' -operations = ['add', 'edit', 'remove', 'search', 'move'] +operations = ['add', 'edit', 'remove', 'search', 'move', 'copy'] template = 'settings/usertemplate' uid_umlauts_mixedcase = 0 @@ -168,6 +168,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'lastname': univention.admin.property( short_description=_('Last name'), @@ -179,6 +180,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'gecos': univention.admin.property( short_description=_('GECOS'), @@ -190,7 +192,8 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, default=' <:umlauts,strip>', identifies=False, - dontsearch=True + dontsearch=True, + copyable=True, ), 'displayName': univention.admin.property( short_description=_('Display name'), @@ -203,6 +206,7 @@ class vacationResendDays(univention.admin.syntax.select): default=' <:strip>', identifies=False, readonly_when_synced=True, + copyable=True, ), 'title': univention.admin.property( short_description=_('Title'), @@ -214,6 +218,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'sambaPrivileges': univention.admin.property( short_description=_('Samba privilege'), @@ -226,6 +231,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'description': univention.admin.property( short_description=_('Description'), @@ -237,6 +243,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'organisation': univention.admin.property( short_description=_('Organisation'), @@ -248,6 +255,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'userexpiry': univention.admin.property( short_description=_('Account expiry date'), @@ -259,6 +267,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, dontsearch=True, identifies=False, + copyable=True, ), 'passwordexpiry': univention.admin.property( short_description=_('Password expiry date'), @@ -272,6 +281,7 @@ class vacationResendDays(univention.admin.syntax.select): dontsearch=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'pwdChangeNextLogin': univention.admin.property( short_description=_('Change password on next login'), @@ -294,7 +304,8 @@ class vacationResendDays(univention.admin.syntax.select): required=False, may_change=True, identifies=False, - show_in_lists=True + show_in_lists=True, + copyable=True, ), 'locked': univention.admin.property( short_description=_('Locked login methods'), @@ -329,6 +340,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'e-mail': univention.admin.property( short_description=_('E-mail address'), @@ -339,7 +351,8 @@ class vacationResendDays(univention.admin.syntax.select): required=False, may_change=True, identifies=False, - default=[''] + default=[''], + copyable=True, ), 'postcode': univention.admin.property( short_description=_('Postal code'), @@ -351,6 +364,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'city': univention.admin.property( short_description=_('City'), @@ -362,6 +376,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'country': univention.admin.property( short_description=_('Country'), @@ -373,6 +388,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'phone': univention.admin.property( short_description=_('Telephone number'), @@ -384,6 +400,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'employeeNumber': univention.admin.property( short_description=_('Employee number'), @@ -395,6 +412,7 @@ class vacationResendDays(univention.admin.syntax.select): required=False, may_change=True, identifies=False, + copyable=True, ), 'roomNumber': univention.admin.property( short_description=_('Room number'), @@ -405,6 +423,7 @@ class vacationResendDays(univention.admin.syntax.select): required=False, may_change=True, identifies=False, + copyable=True, ), 'secretary': univention.admin.property( short_description=_('Superior'), @@ -415,6 +434,7 @@ class vacationResendDays(univention.admin.syntax.select): required=False, may_change=True, identifies=False, + copyable=True, ), 'departmentNumber': univention.admin.property( short_description=_('Department number'), @@ -425,6 +445,7 @@ class vacationResendDays(univention.admin.syntax.select): required=False, may_change=True, identifies=False, + copyable=True, ), 'employeeType': univention.admin.property( short_description=_('Employee type'), @@ -435,6 +456,7 @@ class vacationResendDays(univention.admin.syntax.select): required=False, may_change=True, identifies=False, + copyable=True, ), 'homePostalAddress': univention.admin.property( short_description=_('Private postal address'), @@ -445,6 +467,7 @@ class vacationResendDays(univention.admin.syntax.select): required=False, may_change=True, identifies=False, + copyable=True, ), 'homeTelephoneNumber': univention.admin.property( short_description=_('Private telephone number'), @@ -456,6 +479,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'mobileTelephoneNumber': univention.admin.property( short_description=_('Mobile phone number'), @@ -467,6 +491,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'pagerTelephoneNumber': univention.admin.property( short_description=_('Pager telephone number'), @@ -478,6 +503,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'birthday': univention.admin.property( short_description=_('Birthdate'), @@ -488,6 +514,7 @@ class vacationResendDays(univention.admin.syntax.select): required=False, may_change=True, identifies=False, + copyable=True, ), 'unixhome': univention.admin.property( short_description=_('Unix home directory'), @@ -510,7 +537,8 @@ class vacationResendDays(univention.admin.syntax.select): required=False, may_change=True, identifies=False, - default='/bin/bash' + default='/bin/bash', + copyable=True, ), 'sambahome': univention.admin.property( short_description=_('Windows home path'), @@ -522,6 +550,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'scriptpath': univention.admin.property( short_description=_('Windows logon script'), @@ -533,6 +562,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'profilepath': univention.admin.property( short_description=_('Windows profile directory'), @@ -544,6 +574,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'homedrive': univention.admin.property( short_description=_('Windows home drive'), @@ -555,6 +586,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'sambaRID': univention.admin.property( short_description=_('Relative ID'), @@ -579,6 +611,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'primaryGroup': univention.admin.property( short_description=_('Primary group'), @@ -591,6 +624,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'mailHomeServer': univention.admin.property( short_description=_('Mail home server'), @@ -603,6 +637,7 @@ class vacationResendDays(univention.admin.syntax.select): dontsearch=False, may_change=True, identifies=False, + copyable=True, ), 'mailPrimaryAddress': univention.admin.property( short_description=_('Primary e-mail address'), @@ -628,6 +663,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=False, + copyable=True, ), 'externalMailAlias': univention.admin.property( short_description=_('External e-mail address'), @@ -640,6 +676,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=False, + copyable=True, ), 'externalMailAliasCopyToSelf': univention.admin.property( short_description=_('Copy to the primary e-mail address'), @@ -652,6 +689,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=False, + copyable=True, ), 'overridePWHistory': univention.admin.property( short_description=_('Override password history'), @@ -664,6 +702,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'overridePWLength': univention.admin.property( short_description=_('Override password check'), @@ -676,6 +715,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'homeShare': univention.admin.property( short_description=_('Home share'), @@ -687,6 +727,7 @@ class vacationResendDays(univention.admin.syntax.select): dontsearch=True, may_change=True, identifies=False, + copyable=True, ), 'homeSharePath': univention.admin.property( short_description=_('Home share path'), @@ -711,6 +752,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'sambaLogonHours': univention.admin.property( short_description=_('Permitted times for Windows logins'), @@ -723,6 +765,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, identifies=False, readonly_when_synced=True, + copyable=True, ), 'jpegPhoto': univention.admin.property( short_description=_("Picture of the user (JPEG format)"), @@ -734,6 +777,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, options=['person'], identifies=False, + copyable=True, ), 'userCertificate': univention.admin.property( short_description=_("PKI user certificate (DER format)"), @@ -745,6 +789,7 @@ class vacationResendDays(univention.admin.syntax.select): may_change=True, options=['pki'], identifies=False, + copyable=True, ), 'certificateIssuerCountry': univention.admin.property( short_description=_('Issuer Country'), @@ -756,6 +801,7 @@ class vacationResendDays(univention.admin.syntax.select): editable=False, options=['pki'], identifies=False, + copyable=True, ), 'certificateIssuerState': univention.admin.property( short_description=_('Issuer State'), @@ -767,6 +813,7 @@ class vacationResendDays(univention.admin.syntax.select): editable=False, options=['pki'], identifies=False, + copyable=True, ), 'certificateIssuerLocation': univention.admin.property( short_description=_('Issuer Location'), @@ -778,6 +825,7 @@ class vacationResendDays(univention.admin.syntax.select): editable=False, options=['pki'], identifies=False, + copyable=True, ), 'certificateIssuerOrganisation': univention.admin.property( short_description=_('Issuer Organisation'), @@ -789,6 +837,7 @@ class vacationResendDays(univention.admin.syntax.select): editable=False, options=['pki'], identifies=False, + copyable=True, ), 'certificateIssuerOrganisationalUnit': univention.admin.property( short_description=_('Issuer Organisational Unit'), @@ -800,6 +849,7 @@ class vacationResendDays(univention.admin.syntax.select): editable=False, options=['pki'], identifies=False, + copyable=True, ), 'certificateIssuerCommonName': univention.admin.property( short_description=_('Issuer Common Name'), @@ -811,6 +861,7 @@ class vacationResendDays(univention.admin.syntax.select): editable=False, options=['pki'], identifies=False, + copyable=True, ), 'certificateIssuerMail': univention.admin.property( short_description=_('Issuer Mail'), @@ -822,6 +873,7 @@ class vacationResendDays(univention.admin.syntax.select): editable=False, options=['pki'], identifies=False, + copyable=True, ), 'certificateSubjectCountry': univention.admin.property( short_description=_('Subject Country'), @@ -833,6 +885,7 @@ class vacationResendDays(univention.admin.syntax.select): editable=False, options=['pki'], identifies=False, + copyable=True, ), 'certificateSubjectState': univention.admin.property( short_description=_('Subject State'), @@ -844,6 +897,7 @@ class vacationResendDays(univention.admin.syntax.select): editable=False, options=['pki'], identifies=False, + copyable=True, ), 'certificateSubjectLocation': univention.admin.property( short_description=_('Subject Location'), @@ -855,6 +909,7 @@ class vacationResendDays(univention.admin.syntax.select): editable=False, options=['pki'], identifies=False, + copyable=True, ), 'certificateSubjectOrganisation': univention.admin.property( short_description=_('Subject Organisation'), @@ -866,6 +921,7 @@ class vacationResendDays(univention.admin.syntax.select): editable=False, options=['pki'], identifies=False, + copyable=True, ), 'certificateSubjectOrganisationalUnit': univention.admin.property( short_description=_('Subject Organisational Unit'), @@ -877,6 +933,7 @@ class vacationResendDays(univention.admin.syntax.select): editable=False, options=['pki'], identifies=False, + copyable=True, ), 'certificateSubjectCommonName': univention.admin.property( short_description=_('Subject Common Name'), @@ -888,6 +945,7 @@ class vacationResendDays(univention.admin.syntax.select): editable=False, options=['pki'], identifies=False, + copyable=True, ), 'certificateSubjectMail': univention.admin.property( short_description=_('Subject Mail'), @@ -899,6 +957,7 @@ class vacationResendDays(univention.admin.syntax.select): editable=False, options=['pki'], identifies=False, + copyable=True, ), 'certificateDateNotBefore': univention.admin.property( short_description=_('Valid from'), @@ -910,6 +969,7 @@ class vacationResendDays(univention.admin.syntax.select): editable=False, options=['pki'], identifies=False, + copyable=True, ), 'certificateDateNotAfter': univention.admin.property( short_description=_('Valid until'), @@ -921,6 +981,7 @@ class vacationResendDays(univention.admin.syntax.select): editable=False, options=['pki'], identifies=False, + copyable=True, ), 'certificateVersion': univention.admin.property( short_description=_('Version'), @@ -932,6 +993,7 @@ class vacationResendDays(univention.admin.syntax.select): editable=False, options=['pki'], identifies=False, + copyable=True, ), 'certificateSerial': univention.admin.property( short_description=_('Serial'), @@ -943,6 +1005,7 @@ class vacationResendDays(univention.admin.syntax.select): editable=False, options=['pki'], identifies=False, + copyable=True, ), 'umcProperty': univention.admin.property( short_description=_('UMC user preferences'), @@ -953,6 +1016,7 @@ class vacationResendDays(univention.admin.syntax.select): required=False, may_change=True, identifies=False, + copyable=True, ), } diff --git a/management/univention-management-console-module-udm/umc/js/udm.js b/management/univention-management-console-module-udm/umc/js/udm.js index da8a781..5238d08 100644 --- a/management/univention-management-console-module-udm/umc/js/udm.js +++ b/management/univention-management-console-module-udm/umc/js/udm.js @@ -277,13 +277,13 @@ define([ // check whether we need to open directly the detail page of a given or a new object if (this.openObject) { - this._loadUCRVariables().then(lang.hitch(this, 'createDetailPage', + this._loadUCRVariables().then(lang.hitch(this, 'createDetailPage', 'edit', this.openObject.objectType, this.openObject.objectDN, undefined, true, this.openObject.note) ); return; // do not render the search page } if (this.newObject) { - this._loadUCRVariables().then(lang.hitch(this, 'createDetailPage', + this._loadUCRVariables().then(lang.hitch(this, 'createDetailPage', 'add', this.newObject.objectType, undefined, this.newObject, true, this.newObject.note) ); return; // do not render the search page @@ -366,7 +366,7 @@ define([ var objType = state.shift(); var ldapName = state.length > 1 ? state : state[0]; this._loadUCRVariables().then(lang.hitch(this, function() { - this.createDetailPage(objType, ldapName); + this.createDetailPage('edit', objType, ldapName); })); } this._set('moduleState', _state); @@ -684,7 +684,7 @@ define([ canExecute: lang.hitch(this, '_canEdit'), callback: lang.hitch(this, function(ids, items) { if (items.length == 1 && items[0].objectType) { - this.createDetailPage(items[0].objectType, ids[0]); + this.createDetailPage('edit', items[0].objectType, ids[0]); } else if (items.length >= 1 && items[0].objectType) { // make sure that all objects do have the same type var sameType = true; @@ -698,7 +698,7 @@ define([ } // everything ok, load detail page - this.createDetailPage(items[0].objectType, ids); + this.createDetailPage('edit', items[0].objectType, ids); } }) }, { @@ -742,6 +742,20 @@ define([ callback: lang.hitch(this, function(ids, objects) { this.moveObjects(objects); }) + }, { + name: 'copy', + label: _('Copy'), + description: _('Create a copy of the LDAP object.'), + isMultiAction: false, + canExecute: lang.hitch(this, '_canCopy'), + callback: lang.hitch(this, function(ids, items) { + // FIXME: show a dialog which selects the container/position + this.createDetailPage('copy', items[0].objectType, ids[0], { + objectType: items[0].objectType, + superordinates: null, + container: ids[0].substring(tools.explodeDn(ids[0])[0].length + 1) + }); + }) }]; if ('navigation' !== this.moduleFlavor && this._reports.length) { @@ -1145,7 +1159,7 @@ define([ label: _('Edit'), iconClass: 'umcIconEdit', onClick: lang.hitch(this, function() { - this.createDetailPage(this._navContextItem.objectType, this._navContextItem.id); + this.createDetailPage('edit', this._navContextItem.objectType, this._navContextItem.id); }) })); menu.addChild(this._menuDelete = new MenuItem({ @@ -1207,6 +1221,10 @@ define([ return item.$operations$.indexOf('move') !== -1; }, + _canCopy: function(item) { + return item.$operations$.indexOf('copy') !== -1; + }, + _canDelete: function(item) { if (tools.isTrue(this._ucr['ad/member'])) { return -1 === array.indexOf(item.$flags$, 'synced'); @@ -1833,7 +1851,7 @@ define([ defaultObjectType: this._ucr['directory/manager/web/modules/' + this.moduleFlavor + '/add/default'] || null }); this._newObjectDialog.on('FirstPageFinished', lang.hitch(this, function(options) { - this.createDetailPage(options.objectType, undefined, options); + this.createDetailPage('add', options.objectType, undefined, options); })); this._newObjectDialog.on('Done', lang.hitch(this, function() { if (this._newObjectDialog) { @@ -1880,6 +1898,7 @@ define([ } this._setDetailPage( + 'edit', this._preloadedObjectType, this._ldapNameDeferred, /*newObjectOptions*/ null, @@ -1888,7 +1907,7 @@ define([ ); }, - _setDetailPage: function(objectType, ldapName, newObjOptions, /*Boolean*/ isClosable, /*String*/ note) { + _setDetailPage: function(operation, objectType, ldapName, newObjOptions, /*Boolean*/ isClosable, /*String*/ note) { this._destroyDetailPage(); var cssClass = this.moduleFlavor == 'users/user' ? 'umcUDMUsersModule' : ''; this._detailPage = new DetailPage({ @@ -1899,6 +1918,7 @@ define([ moduleStore: this.moduleStore, moduleFlavor: this.moduleFlavor, objectType: objectType, + operation: operation, ldapBase: this._ucr['ldap/base'], ldapName: ldapName, newObjectOptions: newObjOptions, @@ -1913,17 +1933,20 @@ define([ } }, - createDetailPage: function(objectType, ldapName, newObjOptions, /*Boolean?*/ isClosable, /*String?*/ note) { + createDetailPage: function(operation, objectType, ldapName, newObjOptions, /*Boolean?*/ isClosable, /*String?*/ note) { // summary: // Creates and views the detail page for editing LDAP objects if it doesn't exists. Afterwards it opens the detailpage. if (!this._ldapNameDeferred) { - this._preloadDetailPage(); + this._preloadDetailPage(operation); } - if (this._detailPage && this._preloadedObjectType == this.moduleFlavor && ldapName && !(ldapName instanceof Array)) { + if (operation === 'copy') { + this._setDetailPage(operation, objectType, ldapName, newObjOptions, isClosable, note); + this._ldapNameDeferred.resolve(ldapName); + } else if (this._detailPage && this._preloadedObjectType == this.moduleFlavor && ldapName && !(ldapName instanceof Array)) { // use pre-rendered detail page when loading a (single) object this._ldapNameDeferred.resolve(ldapName); } else { - this._setDetailPage(objectType, ldapName, newObjOptions, isClosable, note); + this._setDetailPage(operation, objectType, ldapName, newObjOptions, isClosable, note); this._ldapNameDeferred.resolve(null); } diff --git a/management/univention-management-console-module-udm/umc/js/udm/DetailPage.js b/management/univention-management-console-module-udm/umc/js/udm/DetailPage.js index 3caf4ca..4f6a412 100644 --- a/management/univention-management-console-module-udm/umc/js/udm/DetailPage.js +++ b/management/univention-management-console-module-udm/umc/js/udm/DetailPage.js @@ -26,7 +26,7 @@ * /usr/share/common-licenses/AGPL-3; if not, see * . */ -/*global require,define,setTimeout,dijit,window,console*/ +/*global require,define,setTimeout,window,console*/ define([ "dojo/_base/declare", @@ -101,6 +101,10 @@ define([ // Flavor of the module moduleFlavor: this.moduleFlavor, + // operation: String + // One of 'add', 'edit', 'copy' + operation: null, + // objectType: String // The object type of the LDAP object that is edited. objectType: null, @@ -268,7 +272,7 @@ define([ domClass.toggle(this._headerButtons.help.domNode, 'dijitDisplayNone', !helpLink); }, - _loadObject: function(formBuiltDeferred, policyDeferred) { + _loadObject: function(formBuiltDeferred, policyDeferred, properties) { if (!this.ldapName || this._multiEdit) { // no DN given or multi edit mode return all({ @@ -278,11 +282,14 @@ define([ } return all({ - object: this.moduleStore.get(this.ldapName), + object: this.getObject(this.ldapName), formBuilt: formBuiltDeferred }).then(lang.hitch(this, function(result) { // save the original data we received from the server var vals = result.object; +// if (this.operation === 'copy') { +// vals = this.modifyValuesForCopy(vals, properties); +// } this._receivedObjOrigData = vals; this._form.setFormValues(vals); this._getInitialFormValues(); @@ -304,20 +311,42 @@ define([ }, this); })); - // var objecttype = vals.$labelObjectType$; - var path = tools.ldapDn2Path( this.ldapName, this.ldapBase); - var objecttype = _('Type: %(type)s', { type: vals.$labelObjectType$ }); - var position = _('Position: %(path)s', { path: path }); - var position_text = lang.replace('{0}
{1}', [objecttype, position]); - array.forEach(this._tabs.getChildren(), lang.hitch(this, function(child) { - if (child.position_text) { - child.position_text.set('content', position_text); - } - })); + if (this.operation === 'add') { // don't show when copying objects + // var objecttype = vals.$labelObjectType$; + var path = tools.ldapDn2Path( this.ldapName, this.ldapBase); + var objecttype = _('Type: %(type)s', { type: vals.$labelObjectType$ }); + var position = _('Position: %(path)s', { path: path }); + var position_text = lang.replace('{0}
{1}', [objecttype, position]); + array.forEach(this._tabs.getChildren(), lang.hitch(this, function(child) { + if (child.position_text) { + child.position_text.set('content', position_text); + } + })); + } return this._form.ready(); })); }, + getObject: function(dn) { + if (this.operation === 'copy') { + return this.umcpCommand('udm/copy', [dn], undefined, this.moduleFlavor).then(function(response) { + return response.result[0]; + }); + } + return this.moduleStore.get(dn); + }, + +// modifyValuesForCopy: function(values, properties) { +// values = lang.clone(values); +// delete values.$dn$; +// array.forEach(properties, function(property) { +// if (property.identifies) { +// delete values[property.id]; +// } +// }, this); +// return values; +// }, + ready: function() { return this._pageRenderedDeferred; }, @@ -364,7 +393,7 @@ define([ }, _notifyAboutAutomaticChanges: function() { - if (!this.ldapName || this._multiEdit) { + if (this.operation === 'add' || this.operation === 'copy' || this._multiEdit) { // ignore creation of a new object as well as the multi edit mode return; } @@ -658,7 +687,7 @@ define([ iprop.disabled = true; } else { if (iprop.disabled !== true) { - iprop.disabled = this.ldapName === undefined ? false : ! iprop.editable; + iprop.disabled = this.operation === 'add' ? false : ! iprop.editable; } } if (this._multiEdit && iprop.identifies) { @@ -821,7 +850,7 @@ define([ return text; }); - if (!this.active_directory_enabled() || !this.ldapName || !this.isSyncedObject) { + if (!this.active_directory_enabled() || this.operation === 'add' || !this.isSyncedObject) { return; } var value = ''; @@ -852,7 +881,7 @@ define([ }, _prepareOptions: function(properties, layout, template, formBuiltDeferred) { - var isNewObject = !this.ldapName; + var isNewObject = this.operation === 'add'; var _getOptionProperty = function(properties) { var result = array.filter(properties, function(item) { @@ -1094,7 +1123,7 @@ define([ this._policyDeferred = new Deferred(); var loadedDeferred = when(this.ldapName, lang.hitch(this, function(ldapName) { this.ldapName = ldapName; - return this._loadObject(formBuiltDeferred, this._policyDeferred); + return this._loadObject(formBuiltDeferred, this._policyDeferred, properties); })); loadedDeferred.then(lang.hitch(this, 'addActiveDirectoryWarning')); loadedDeferred.then(lang.hitch(this, 'set', 'helpLink', metaInfo.help_link)); @@ -1142,7 +1171,7 @@ define([ }, buildTemplate: function(_template, properties, widgets) { - if (this.ldapName || this._multiEdit) { + if (this.operation !== 'add' || this._multiEdit) { return; } @@ -1214,7 +1243,7 @@ define([ }); var createLabel = ''; - if (this.newObjectOptions) { + if (this.operation === 'add' || this.operation === 'copy') { createLabel = _createLabelText(); } else { createLabel = _('Save'); @@ -1731,7 +1760,7 @@ define([ this.moduleStore.put(ivals); }, this); deferred = transaction.commit(); - } else if (this.newObjectOptions) { + } else if (this.operation === 'add' || this.operation === 'copy') { deferred = this.moduleStore.add(vals, this.newObjectOptions); } else { deferred = this.moduleStore.put(vals); @@ -1885,7 +1914,7 @@ define([ newVals[iname] = iwidget.get('value'); } })); - } else if (this.newObjectOptions) { + } else if (this.operation === 'add' || this.operation === 'copy') { // get only non-empty values or values of type 'boolean' tools.forIn(vals, lang.hitch(this, function(iname, ival) { if (typeof(ival) == 'boolean' || (!(ival instanceof Array && !ival.length) && ival)) { @@ -1919,7 +1948,7 @@ define([ confirmClose: function() { topic.publish('/umc/actions', 'udm', this._parentModule.moduleFlavor, 'edit', 'cancel'); - if (!this.newObjectOptions && this.haveVisibleValuesChanged()) { + if (this.operation === 'edit' && this.haveVisibleValuesChanged()) { return dialog.confirm(_('There are unsaved changes. Are you sure to cancel?'), [{ label: _('Continue editing'), name: 'cancel' diff --git a/management/univention-management-console-module-udm/umc/python/udm/__init__.py b/management/univention-management-console-module-udm/umc/python/udm/__init__.py index ac404af..31df3d3 100644 --- a/management/univention-management-console-module-udm/umc/python/udm/__init__.py +++ b/management/univention-management-console-module-udm/umc/python/udm/__init__.py @@ -454,47 +454,56 @@ def get(self, request): return: [ { '$dn$' : , }, ... ] """ - def _thread(request): - result = [] - for ldap_dn in request.options: - if request.flavor == 'users/self': - ldap_dn = self._user_dn - module = get_module(request.flavor, ldap_dn) - if module is None: - raise ObjectDoesNotExist(ldap_dn) - else: - obj = module.get(ldap_dn) - if obj: - obj.set_defaults = True - for name, p in obj.descriptions.items(): - if obj.has_key(name) and obj.descriptions[name].default(obj): # noqa: W601 - obj[name] # __getitem__ sets default value - props = obj.info - for passwd in module.password_properties: - if passwd in props: - del props[passwd] - props['$dn$'] = obj.dn - props['$options$'] = {} - for opt in module.get_options(udm_object=obj): - props['$options$'][opt['id']] = opt['value'] - props['$policies$'] = {} - for policy in obj.policies: - pol_mod = get_module(None, policy) - if pol_mod and pol_mod.name: - props['$policies$'].setdefault(pol_mod.name, []).append(policy) - props['$labelObjectType$'] = module.title - props['$flags$'] = obj.oldattr.get('univentionObjectFlag', []) - props['$operations$'] = module.operations - props['$references$'] = module.get_references(ldap_dn) - result.append(props) - else: - MODULE.process('The LDAP object for the LDAP DN %s could not be found' % ldap_dn) - return result - MODULE.info('Starting thread for udm/get request') - thread = notifier.threads.Simple('Get', notifier.Callback(_thread, request), notifier.Callback(self.thread_finished_callback, request)) + thread = notifier.threads.Simple('Get', notifier.Callback(self._get, request), notifier.Callback(self.thread_finished_callback, request)) thread.run() + def copy(self, request): + thread = notifier.threads.Simple('Copy', notifier.Callback(self._get, request, True), notifier.Callback(self.thread_finished_callback, request)) + thread.run() + + def _get(self, request, copy=False): + result = [] + for ldap_dn in request.options: + if request.flavor == 'users/self': + ldap_dn = self._user_dn + module = get_module(request.flavor, ldap_dn) + if module is None: + raise ObjectDoesNotExist(ldap_dn) + else: + obj = module.get(ldap_dn) + if obj: + if copy: + for name, p in obj.descriptions.items(): + if not p.copyable: + obj.info.pop(name, None) + obj.set_defaults = True + for name, p in obj.descriptions.items(): + if obj.has_key(name) and obj.descriptions[name].default(obj): # noqa: W601 + obj[name] # __getitem__ sets default value + props = obj.info + for passwd in module.password_properties: + if passwd in props: + del props[passwd] + if not copy: + props['$dn$'] = obj.dn + props['$options$'] = {} + for opt in module.get_options(udm_object=obj): + props['$options$'][opt['id']] = opt['value'] + props['$policies$'] = {} + for policy in obj.policies: + pol_mod = get_module(None, policy) + if pol_mod and pol_mod.name: + props['$policies$'].setdefault(pol_mod.name, []).append(policy) + props['$labelObjectType$'] = module.title + props['$flags$'] = obj.oldattr.get('univentionObjectFlag', []) + props['$operations$'] = module.operations + props['$references$'] = module.get_references(ldap_dn) + result.append(props) + else: + MODULE.process('The LDAP object for the LDAP DN %s could not be found' % ldap_dn) + return result + @sanitize( objectPropertyValue=LDAPSearchSanitizer( add_asterisks=ADD_ASTERISKS, diff --git a/management/univention-management-console-module-udm/umc/udm.xml b/management/univention-management-console-module-udm/umc/udm.xml index cc63ff7..00a8740 100644 --- a/management/univention-management-console-module-udm/umc/udm.xml +++ b/management/univention-management-console-module-udm/umc/udm.xml @@ -116,6 +116,7 @@ +