From d238f97214135036aedddcfe5c04eff3f13b50e1 Mon Sep 17 00:00:00 2001 From: Johannes Goderbauer <j.goderbauer@adito.de> Date: Tue, 5 May 2020 11:26:35 +0000 Subject: [PATCH] [Projekt: Entwicklung - Neon][TicketNr.: 1054152][Sync Kalenderberechtigungen mit EWS] added comments --- .../2020.1.0/PermissionCalendar/changelog.xml | 1 - .../init_PermissionCalendarCategory.xml | 42 -- .../Exchange_devIntern/Exchange_devIntern.aod | 6 + .../KeywordAttribute_entity.aod | 1 + .../grantDeleteProcess.js | 0 .../KeywordEntry_entity.aod | 6 - .../Organisation_entity.aod | 3 + .../PermissionCalendar_entity.aod | 17 +- .../onActionProcess.js | 3 +- .../onActionProcess.js | 3 +- .../containername_param/valueProcess.js | 6 - .../permission/dropDownProcess.js | 12 + .../mandatoryProcess.js | 3 +- .../stateProcess.js | 3 +- .../mandatoryProcess.js | 3 +- .../stateProcess.js | 3 +- .../PermissionCalendar_entity/onValidation.js | 5 +- .../_____LANGUAGE_EXTRA.aod | 39 ++ .../_____LANGUAGE_de/_____LANGUAGE_de.aod | 43 ++ .../_____LANGUAGE_en/_____LANGUAGE_en.aod | 36 ++ process/EwsClient_lib/EwsClient_lib.aod | 9 + process/EwsClient_lib/process.js | 405 ++++++++++++++++++ process/KeywordRegistry_basic/process.js | 5 +- .../PermissionCalendar_lib.aod | 1 + process/PermissionCalendar_lib/process.js | 163 ++++--- ...sSyncCalendarPermissions_serverProcess.aod | 11 + .../process.js | 3 + 27 files changed, 700 insertions(+), 132 deletions(-) delete mode 100644 .liquibase/Data_alias/basic/2020.1.0/PermissionCalendar/init_PermissionCalendarCategory.xml create mode 100644 aliasDefinition/Exchange_devIntern/Exchange_devIntern.aod create mode 100644 entity/KeywordAttribute_entity/grantDeleteProcess.js delete mode 100644 entity/PermissionCalendar_entity/entityfields/keywordpermissioncalendarcategories/children/containername_param/valueProcess.js create mode 100644 entity/PermissionCalendar_entity/entityfields/permission/dropDownProcess.js create mode 100644 process/EwsClient_lib/EwsClient_lib.aod create mode 100644 process/EwsClient_lib/process.js create mode 100644 process/ewsSyncCalendarPermissions_serverProcess/ewsSyncCalendarPermissions_serverProcess.aod create mode 100644 process/ewsSyncCalendarPermissions_serverProcess/process.js diff --git a/.liquibase/Data_alias/basic/2020.1.0/PermissionCalendar/changelog.xml b/.liquibase/Data_alias/basic/2020.1.0/PermissionCalendar/changelog.xml index a540df4133..25028737ab 100644 --- a/.liquibase/Data_alias/basic/2020.1.0/PermissionCalendar/changelog.xml +++ b/.liquibase/Data_alias/basic/2020.1.0/PermissionCalendar/changelog.xml @@ -2,6 +2,5 @@ <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> <include file="create_ab_permissioncalendar.xml" relativeToChangelogFile="true"/> -<include file="init_PermissionCalendarCategory.xml" relativeToChangelogFile="true"/> <include file="init_PermissionCalendarType.xml" relativeToChangelogFile="true"/> </databaseChangeLog> diff --git a/.liquibase/Data_alias/basic/2020.1.0/PermissionCalendar/init_PermissionCalendarCategory.xml b/.liquibase/Data_alias/basic/2020.1.0/PermissionCalendar/init_PermissionCalendarCategory.xml deleted file mode 100644 index dafd18910f..0000000000 --- a/.liquibase/Data_alias/basic/2020.1.0/PermissionCalendar/init_PermissionCalendarCategory.xml +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.1" encoding="UTF-8" standalone="no"?> -<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> - <changeSet author="s.pongratz" id="b2394de0-4a19-4fcb-9412-0a5e91bfec82"> - <insert tableName="AB_KEYWORD_ENTRY"> - <column name="AB_KEYWORD_ENTRYID" value="c5f3cae8-06b3-4db3-8c7e-80f16e6d080e"/> - <column name="KEYID" value="NOTHING"/> - <column name="TITLE" value="NoPermissions"/> - <column name="CONTAINER" value="PermissionCalendarCategory"/> - <column name="SORTING" valueNumeric="0"/> - <column name="ISACTIVE" valueNumeric="1"/> - <column name="ISESSENTIAL" valueNumeric="1"/> - </insert> - <insert tableName="AB_KEYWORD_ENTRY"> - <column name="AB_KEYWORD_ENTRYID" value="c2624c60-cb07-44f2-80b1-fbb86932df72"/> - <column name="KEYID" value="LIMITEDREAD"/> - <column name="TITLE" value="LimitedReadPermission"/> - <column name="CONTAINER" value="PermissionCalendarCategory"/> - <column name="SORTING" valueNumeric="1"/> - <column name="ISACTIVE" valueNumeric="1"/> - <column name="ISESSENTIAL" valueNumeric="1"/> - </insert> - <insert tableName="AB_KEYWORD_ENTRY"> - <column name="AB_KEYWORD_ENTRYID" value="64546657-843b-4cb4-a6b8-4d34548e1c97"/> - <column name="KEYID" value="FULLREAD"/> - <column name="TITLE" value="ReadPermission"/> - <column name="CONTAINER" value="PermissionCalendarCategory"/> - <column name="SORTING" valueNumeric="2"/> - <column name="ISACTIVE" valueNumeric="1"/> - <column name="ISESSENTIAL" valueNumeric="1"/> - </insert> - <insert tableName="AB_KEYWORD_ENTRY"> - <column name="AB_KEYWORD_ENTRYID" value="64546657-843b-4cb4-a6b8-4d34548e1c98"/> - <column name="KEYID" value="READWRITE"/> - <column name="TITLE" value="ReadWritePermission"/> - <column name="CONTAINER" value="PermissionCalendarCategory"/> - <column name="SORTING" valueNumeric="3"/> - <column name="ISACTIVE" valueNumeric="1"/> - <column name="ISESSENTIAL" valueNumeric="1"/> - </insert> - </changeSet> -</databaseChangeLog> diff --git a/aliasDefinition/Exchange_devIntern/Exchange_devIntern.aod b/aliasDefinition/Exchange_devIntern/Exchange_devIntern.aod new file mode 100644 index 0000000000..91b436cae6 --- /dev/null +++ b/aliasDefinition/Exchange_devIntern/Exchange_devIntern.aod @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<aliasDefinition xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.2.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/aliasDefinition/1.2.0"> + <name>Exchange_devIntern</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <datasourceType v="10" /> +</aliasDefinition> diff --git a/entity/KeywordAttribute_entity/KeywordAttribute_entity.aod b/entity/KeywordAttribute_entity/KeywordAttribute_entity.aod index 3c1336f58b..ac1185cf4b 100644 --- a/entity/KeywordAttribute_entity/KeywordAttribute_entity.aod +++ b/entity/KeywordAttribute_entity/KeywordAttribute_entity.aod @@ -4,6 +4,7 @@ <majorModelMode>DISTRIBUTED</majorModelMode> <documentation>%aditoprj%/entity/KeywordAttribute_entity/documentation.adoc</documentation> <title>Keyword Attribute</title> + <grantDeleteProcess>%aditoprj%/entity/KeywordAttribute_entity/grantDeleteProcess.js</grantDeleteProcess> <contentTitleProcess>%aditoprj%/entity/KeywordAttribute_entity/contentTitleProcess.js</contentTitleProcess> <iconId>VAADIN:KEY_O</iconId> <iconIdProcess>%aditoprj%/entity/KeywordAttribute_entity/iconIdProcess.js</iconIdProcess> diff --git a/entity/KeywordAttribute_entity/grantDeleteProcess.js b/entity/KeywordAttribute_entity/grantDeleteProcess.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/entity/KeywordEntry_entity/KeywordEntry_entity.aod b/entity/KeywordEntry_entity/KeywordEntry_entity.aod index 36b66e6474..1d23aa80c1 100644 --- a/entity/KeywordEntry_entity/KeywordEntry_entity.aod +++ b/entity/KeywordEntry_entity/KeywordEntry_entity.aod @@ -553,12 +553,6 @@ <fieldName>ContextDocumentTemplatePlaceOfUse</fieldName> <isConsumer v="false" /> </entityDependency> - <entityDependency> - <name>79bdbc02-19dc-4ecc-a91f-d657bda6f6cd</name> - <entityName>PermissionCalendar_entity</entityName> - <fieldName>KeywordPermissionCalendarCategories</fieldName> - <isConsumer v="false" /> - </entityDependency> <entityDependency> <name>8c5b1d49-f0b5-4a7c-9bff-02165996e11b</name> <entityName>PermissionCalendar_entity</entityName> diff --git a/entity/Organisation_entity/Organisation_entity.aod b/entity/Organisation_entity/Organisation_entity.aod index 46d2089ce3..8ccbb9a42d 100644 --- a/entity/Organisation_entity/Organisation_entity.aod +++ b/entity/Organisation_entity/Organisation_entity.aod @@ -1289,6 +1289,9 @@ <filterConditionProcess>%aditoprj%/entity/Organisation_entity/recordcontainers/db/filterextensions/attribute_filter/filterConditionProcess.js</filterConditionProcess> <filtertype>BASIC</filtertype> </filterExtensionSet> + <filterExtension> + <name>filterExtension</name> + </filterExtension> </filterExtensions> </dbRecordContainer> <indexRecordContainer> diff --git a/entity/PermissionCalendar_entity/PermissionCalendar_entity.aod b/entity/PermissionCalendar_entity/PermissionCalendar_entity.aod index 552e3a6bfe..1561a02279 100644 --- a/entity/PermissionCalendar_entity/PermissionCalendar_entity.aod +++ b/entity/PermissionCalendar_entity/PermissionCalendar_entity.aod @@ -16,9 +16,9 @@ <entityField> <name>PERMISSION</name> <title>permission</title> - <consumer>KeywordPermissionCalendarCategories</consumer> <groupable v="true" /> <mandatory v="true" /> + <dropDownProcess>%aditoprj%/entity/PermissionCalendar_entity/entityfields/permission/dropDownProcess.js</dropDownProcess> <displayValueProcess>%aditoprj%/entity/PermissionCalendar_entity/entityfields/permission/displayValueProcess.js</displayValueProcess> </entityField> <entityField> @@ -26,20 +26,6 @@ <title>ID</title> <mandatory v="false" /> </entityField> - <entityConsumer> - <name>KeywordPermissionCalendarCategories</name> - <dependency> - <name>dependency</name> - <entityName>KeywordEntry_entity</entityName> - <fieldName>SpecificContainerKeywords</fieldName> - </dependency> - <children> - <entityParameter> - <name>ContainerName_param</name> - <valueProcess>%aditoprj%/entity/PermissionCalendar_entity/entityfields/keywordpermissioncalendarcategories/children/containername_param/valueProcess.js</valueProcess> - </entityParameter> - </children> - </entityConsumer> <entityField> <name>USER_NEW</name> <mandatory v="false" /> @@ -142,6 +128,7 @@ </entityProvider> <entityParameter> <name>PermissionProcurer_param</name> + <valueProcess>%aditoprj%/entity/PermissionCalendar_entity/entityfields/permissionprocurer_param/valueProcess.js</valueProcess> <expose v="true" /> </entityParameter> <entityParameter> diff --git a/entity/PermissionCalendar_entity/entityfields/addactions/children/addnewdepartmentpermissiondealteraction/onActionProcess.js b/entity/PermissionCalendar_entity/entityfields/addactions/children/addnewdepartmentpermissiondealteraction/onActionProcess.js index 16ae742310..78b952ce03 100644 --- a/entity/PermissionCalendar_entity/entityfields/addactions/children/addnewdepartmentpermissiondealteraction/onActionProcess.js +++ b/entity/PermissionCalendar_entity/entityfields/addactions/children/addnewdepartmentpermissiondealteraction/onActionProcess.js @@ -1,8 +1,9 @@ +import("KeywordRegistry_basic"); import("PermissionCalendar_lib"); import("system.vars"); import("system.neon"); var params = {}; -params["PermissionDealerType_param"] = PermissionCalendar.objectTypeDepartment(); +params["PermissionDealerType_param"] = $KeywordRegistry.permissionCalendarType$department(); params["PermissionProcurer_param"] = vars.get("$param.PermissionProcurer_param"); neon.openContext("PermissionCalendar", null, null, neon.OPERATINGSTATE_NEW, params); \ No newline at end of file diff --git a/entity/PermissionCalendar_entity/entityfields/addactions/children/addnewuserpermissiondealeraction/onActionProcess.js b/entity/PermissionCalendar_entity/entityfields/addactions/children/addnewuserpermissiondealeraction/onActionProcess.js index d2946f2d5c..0aee6ca71f 100644 --- a/entity/PermissionCalendar_entity/entityfields/addactions/children/addnewuserpermissiondealeraction/onActionProcess.js +++ b/entity/PermissionCalendar_entity/entityfields/addactions/children/addnewuserpermissiondealeraction/onActionProcess.js @@ -1,8 +1,9 @@ +import("KeywordRegistry_basic"); import("PermissionCalendar_lib"); import("system.vars"); import("system.neon"); var params = {}; -params["PermissionDealerType_param"] = PermissionCalendar.objectTypeUser(); +params["PermissionDealerType_param"] = $KeywordRegistry.permissionCalendarType$user(); params["PermissionProcurer_param"] = vars.get("$param.PermissionProcurer_param"); neon.openContext("PermissionCalendar", null, null, neon.OPERATINGSTATE_NEW, params); \ No newline at end of file diff --git a/entity/PermissionCalendar_entity/entityfields/keywordpermissioncalendarcategories/children/containername_param/valueProcess.js b/entity/PermissionCalendar_entity/entityfields/keywordpermissioncalendarcategories/children/containername_param/valueProcess.js deleted file mode 100644 index 7f169e4a01..0000000000 --- a/entity/PermissionCalendar_entity/entityfields/keywordpermissioncalendarcategories/children/containername_param/valueProcess.js +++ /dev/null @@ -1,6 +0,0 @@ -import("system.result"); -import("Keyword_lib"); -import("KeywordRegistry_basic"); -import("PermissionCalendar_lib"); - -result.string($KeywordRegistry.permissionCalendarCategory()); \ No newline at end of file diff --git a/entity/PermissionCalendar_entity/entityfields/permission/dropDownProcess.js b/entity/PermissionCalendar_entity/entityfields/permission/dropDownProcess.js new file mode 100644 index 0000000000..1acac0c3cb --- /dev/null +++ b/entity/PermissionCalendar_entity/entityfields/permission/dropDownProcess.js @@ -0,0 +1,12 @@ +import("system.result"); +import("PermissionCalendar_lib"); + +var setableCategoryIds = PermissionCalendar.getSetableCategories(); +var allCategories = PermissionCalendar.getCategories(); + +var res = setableCategoryIds.map(function (categoryId){ + var title = allCategories[categoryId] ? allCategories[categoryId].getTitle() : categoryId; + return [categoryId, title]; +}); + +result.object(res); \ No newline at end of file diff --git a/entity/PermissionCalendar_entity/entityfields/permissiondealer_department_rowid/mandatoryProcess.js b/entity/PermissionCalendar_entity/entityfields/permissiondealer_department_rowid/mandatoryProcess.js index a31a0c05cc..b0dd49473c 100644 --- a/entity/PermissionCalendar_entity/entityfields/permissiondealer_department_rowid/mandatoryProcess.js +++ b/entity/PermissionCalendar_entity/entityfields/permissiondealer_department_rowid/mandatoryProcess.js @@ -1,8 +1,9 @@ +import("KeywordRegistry_basic"); import("system.vars"); import("system.result"); import("PermissionCalendar_lib"); -if(vars.getString("$field.PERMISSIONDEALER_TYPE") == PermissionCalendar.objectTypeDepartment()) +if(vars.getString("$field.PERMISSIONDEALER_TYPE") == $KeywordRegistry.permissionCalendarType$department()) result.string(true); else result.string(false); \ No newline at end of file diff --git a/entity/PermissionCalendar_entity/entityfields/permissiondealer_department_rowid/stateProcess.js b/entity/PermissionCalendar_entity/entityfields/permissiondealer_department_rowid/stateProcess.js index 88016954f0..9d47dab7c4 100644 --- a/entity/PermissionCalendar_entity/entityfields/permissiondealer_department_rowid/stateProcess.js +++ b/entity/PermissionCalendar_entity/entityfields/permissiondealer_department_rowid/stateProcess.js @@ -1,9 +1,10 @@ +import("KeywordRegistry_basic"); import("system.vars"); import("system.result"); import("PermissionCalendar_lib"); import("system.neon"); -if(vars.getString("$field.PERMISSIONDEALER_TYPE") == PermissionCalendar.objectTypeDepartment()) +if(vars.getString("$field.PERMISSIONDEALER_TYPE") == $KeywordRegistry.permissionCalendarType$department()) if(vars.getString("$sys.recordstate") == neon.OPERATINGSTATE_EDIT) result.string("READONLY") else diff --git a/entity/PermissionCalendar_entity/entityfields/permissiondealer_user_rowid/mandatoryProcess.js b/entity/PermissionCalendar_entity/entityfields/permissiondealer_user_rowid/mandatoryProcess.js index aedb9baf38..20c989da57 100644 --- a/entity/PermissionCalendar_entity/entityfields/permissiondealer_user_rowid/mandatoryProcess.js +++ b/entity/PermissionCalendar_entity/entityfields/permissiondealer_user_rowid/mandatoryProcess.js @@ -1,8 +1,9 @@ +import("KeywordRegistry_basic"); import("system.vars"); import("system.result"); import("PermissionCalendar_lib"); -if(vars.getString("$field.PERMISSIONDEALER_TYPE") == PermissionCalendar.objectTypeUser()) +if(vars.getString("$field.PERMISSIONDEALER_TYPE") == $KeywordRegistry.permissionCalendarType$user()) result.string(true); else result.string(false); \ No newline at end of file diff --git a/entity/PermissionCalendar_entity/entityfields/permissiondealer_user_rowid/stateProcess.js b/entity/PermissionCalendar_entity/entityfields/permissiondealer_user_rowid/stateProcess.js index 3b15f8f615..6176f62e41 100644 --- a/entity/PermissionCalendar_entity/entityfields/permissiondealer_user_rowid/stateProcess.js +++ b/entity/PermissionCalendar_entity/entityfields/permissiondealer_user_rowid/stateProcess.js @@ -1,9 +1,10 @@ +import("KeywordRegistry_basic"); import("system.vars"); import("system.result"); import("PermissionCalendar_lib"); import("system.neon"); -if(vars.getString("$field.PERMISSIONDEALER_TYPE") == PermissionCalendar.objectTypeUser()) +if(vars.getString("$field.PERMISSIONDEALER_TYPE") == $KeywordRegistry.permissionCalendarType$user()) if(vars.getString("$sys.recordstate") == neon.OPERATINGSTATE_EDIT) result.string("READONLY") else diff --git a/entity/PermissionCalendar_entity/onValidation.js b/entity/PermissionCalendar_entity/onValidation.js index 7830911e9f..61a3f0facf 100644 --- a/entity/PermissionCalendar_entity/onValidation.js +++ b/entity/PermissionCalendar_entity/onValidation.js @@ -1,3 +1,4 @@ +import("KeywordRegistry_basic"); import("system.neon"); import("system.translate"); import("system.result"); @@ -7,9 +8,9 @@ import("Employee_lib"); let dealerId; let dealerType = vars.getString("$field.PERMISSIONDEALER_TYPE"); -if(dealerType == PermissionCalendar.objectTypeUser()) +if(dealerType == $KeywordRegistry.permissionCalendarType$user()) dealerId = vars.getString("$field.PERMISSIONDEALER_USER_ROWID"); -else if (dealerType == PermissionCalendar.objectTypeDepartment()) +else if (dealerType == $KeywordRegistry.permissionCalendarType$department()) dealerId = vars.getString("$field.PERMISSIONDEALER_DEPARTMENT_ROWID"); else dealerId = ""; diff --git a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod index 1041f23b11..fc6870e2c1 100644 --- a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod +++ b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod @@ -6701,6 +6701,45 @@ <entry> <key>New Visit Recommendation</key> </entry> + <entry> + <key>Invalid file type; only .html, .eml and .txt are allowed</key> + </entry> + <entry> + <key>ankle of</key> + </entry> + <entry> + <key>New Visit Recommendation</key> + </entry> + <entry> + <key>Limited details</key> + </entry> + <entry> + <key>Free or Busy Permission</key> + </entry> + <entry> + <key>Full Read Permission</key> + </entry> + <entry> + <key>No permissions</key> + </entry> + <entry> + <key>Editor</key> + </entry> + <entry> + <key>Read and Write Permission</key> + </entry> + <entry> + <key>Synchronize calendar permissions from Exchange to ADITO</key> + </entry> + <entry> + <key>Availability only</key> + </entry> + <entry> + <key>Limited Read Permission</key> + </entry> + <entry> + <key>Full details</key> + </entry> </keyValueMap> <font name="Dialog" style="0" size="11" /> <sqlModels> diff --git a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod index e1906b85ea..840ac9df1d 100644 --- a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod +++ b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod @@ -8589,6 +8589,49 @@ Bitte Datumseingabe prüfen</value> <entry> <key>Linked In</key> </entry> + <entry> + <key>Abomodel</key> + </entry> + <entry> + <key>Limited details</key> + <value>Eingeschränkte Details</value> + </entry> + <entry> + <key>Free or Busy Permission</key> + <value>Nur Verfügbarkeit</value> + </entry> + <entry> + <key>Full Read Permission</key> + <value>Volle Leseberechtigung</value> + </entry> + <entry> + <key>No permissions</key> + <value>Keine Zugriffsberechtigung</value> + </entry> + <entry> + <key>Editor</key> + <value>Bearbeiter</value> + </entry> + <entry> + <key>Read and Write Permission</key> + <value>Volle Lese- und Schreibberechtigung</value> + </entry> + <entry> + <key>Synchronize calendar permissions from Exchange to ADITO</key> + <value>Synchronisiere Kalenderberechtigungen von Exchange nach ADITO</value> + </entry> + <entry> + <key>Availability only</key> + <value>Nur Verfügbarkeit</value> + </entry> + <entry> + <key>Limited Read Permission</key> + <value>Eingeschränkte Leseberechtigung</value> + </entry> + <entry> + <key>Full details</key> + <value>Alle Details</value> + </entry> </keyValueMap> <font name="Dialog" style="0" size="11" /> </language> diff --git a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod index 60030d8ecb..73a7ba3dbe 100644 --- a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod +++ b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod @@ -6766,6 +6766,42 @@ <entry> <key>ankle of</key> </entry> + <entry> + <key>Visit Planning</key> + </entry> + <entry> + <key>ankle of</key> + </entry> + <entry> + <key>Limited details</key> + </entry> + <entry> + <key>Free or Busy Permission</key> + </entry> + <entry> + <key>Full Read Permission</key> + </entry> + <entry> + <key>No permissions</key> + </entry> + <entry> + <key>Editor</key> + </entry> + <entry> + <key>Read and Write Permission</key> + </entry> + <entry> + <key>Synchronize calendar permissions from Exchange to ADITO</key> + </entry> + <entry> + <key>Availability only</key> + </entry> + <entry> + <key>Limited Read Permission</key> + </entry> + <entry> + <key>Full details</key> + </entry> </keyValueMap> <font name="Dialog" style="0" size="11" /> </language> diff --git a/process/EwsClient_lib/EwsClient_lib.aod b/process/EwsClient_lib/EwsClient_lib.aod new file mode 100644 index 0000000000..6343b20344 --- /dev/null +++ b/process/EwsClient_lib/EwsClient_lib.aod @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.2.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.2.1"> + <name>EwsClient_lib</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <process>%aditoprj%/process/EwsClient_lib/process.js</process> + <variants> + <element>LIBRARY</element> + </variants> +</process> diff --git a/process/EwsClient_lib/process.js b/process/EwsClient_lib/process.js new file mode 100644 index 0000000000..41e53a9c9a --- /dev/null +++ b/process/EwsClient_lib/process.js @@ -0,0 +1,405 @@ +import("KeywordRegistry_basic"); +import("system.datetime"); +import("Employee_lib"); +import("system.util"); +import("system.vars"); +import("PermissionCalendar_lib"); +import("system.db"); +import("system.logging"); +import("system.tools"); +import("system.project"); +import("system.plugin"); +import("Sql_lib"); + + + +/** + * Provides static methods various actions for the EWS plugin + * + * @class + */ +function EwsClientUtils(){} + + +/** + * performs a plugin call of the EWS client plugin + * + * @param {XML} pPluginInput <p/> + * Plugin Request that determines what the plugin shall do and to which exchange server the plugin shall connect + * @return {XML} <p/> Depending on the pPluginInput, the result of the plugin. Note that not always a error is thrown when there + * are no permissions for a folder. In some of these cases a XML is returned that does not contain any data + * @static + */ +EwsClientUtils.callPlugin = function (pPluginInput) +{ + if (pPluginInput && typeof(pPluginInput) != "string")//for better compability with legacy code expect a string or a XML object + pPluginInput = pPluginInput.toString(); + var pluginPath = null; + var res = plugin.run(pluginPath, "de.adito.plugin.ewsclient.EwsClientPlugin", [pPluginInput])[0]; + return new XML(res); +}; + +/*this is right now (2020-04-15) the only way to get something like a constant with + - a prober name + - autocomplete support within the ADITO Designer + - and proper packageing all constants together +This may change in the future, if there is something better feel free to improve this */ +function $EwsClientTaskDescriptions(){} +$EwsClientTaskDescriptions.GET_EMAIL_IDS = function(){return "GET_EMAIL_IDS"}; +$EwsClientTaskDescriptions.GET_EMAIL_BY_ID = function(){return "GET_EMAIL_BY_ID"}; +$EwsClientTaskDescriptions.GET_EMAILS = function(){return "GET_EMAILS"}; +$EwsClientTaskDescriptions.DELETE_EMAIL_BY_ID = function(){return "DELETE_EMAIL_BY_ID"}; +$EwsClientTaskDescriptions.INSERT_EMAIL = function(){return "INSERT_EMAIL"}; +$EwsClientTaskDescriptions.GET_CALENDAR_TASKS_PERMISSIONS = function(){return "GET_CALENDAR_TASKS_PERMISSIONS"}; +$EwsClientTaskDescriptions.DELETE_CONTACT = function(){return "DELETE_CONTACT"}; +$EwsClientTaskDescriptions.DELETE_CONTACT_BY_ID = function(){return "DELETE_CONTACT_BY_ID"}; +$EwsClientTaskDescriptions.INSERT_CONTACT = function(){return "INSERT_CONTACT"}; +$EwsClientTaskDescriptions.INSERT_CONTACT_TO_FOLDER = function(){return "INSERT_CONTACT_TO_FOLDER"}; +$EwsClientTaskDescriptions.GET_CONTACT_BY_ID = function(){return "GET_CONTACT_BY_ID"}; +$EwsClientTaskDescriptions.GET_CONTACTS = function(){return "GET_CONTACTS"}; +$EwsClientTaskDescriptions.GET_CONTACTS_BY_CATEGORIE = function(){return "GET_CONTACTS_BY_CATEGORIE"}; +$EwsClientTaskDescriptions.GET_CONTACTS_BY_FOLDERS = function(){return "GET_CONTACTS_BY_FOLDERS"}; +$EwsClientTaskDescriptions.GET_CONTACTSDEFAULTFOLDER = function(){return "GET_CONTACTSDEFAULTFOLDER"}; +$EwsClientTaskDescriptions.GET_CONTACTFOLDERS = function(){return "GET_CONTACTFOLDERS"}; +$EwsClientTaskDescriptions.UPDATE_CONTACT = function(){return "UPDATE_CONTACT"}; + +function $EwsClientImpersonationModes(){} +/** + * Impersonation mode NONE should be set if no impersonation user is used and every user is authenticated per user-data + */ +$EwsClientImpersonationModes.NONE = function(){return "NONE"}; +/** + * Impersonation mode SINGLE should be set if an impersonation user is used that impersonates ONE user (e.g. for syncing a contact folder) + */ +$EwsClientImpersonationModes.SINGLE = function(){return "SINGLE"}; +/** + * Impersonation mode LIST should be set if an impersonation user is used that impersonates SEVERAL users (e.g. for loading the calendar permissions) + */ +$EwsClientImpersonationModes.LIST = function(){return "LIST"}; + +/** + * Provides static methods for handling and creating XMLs to interact with the EWS plugin + * + * @class + */ +function EwsClientXMLUtils(){} + +/** + * builds a request XML that can be given to the EWS client plugin + * uses basic auth with user and password for authentication + * + * @param {String} pUrl <p/> The complete URL that points to the Exchange server, this has to point at the Exchange.asmx + * <br/>e.g.: "https://exchange.mycustomer.com:443/ews/Exchange.asmx" + * @param {String} pDomain <p/> Domain that is used for the connection, this may differ to the domain in pUrl (e.g. Exchange online) + * @param {String} pImpersonatedUserMode <p/> Specifies if the pUser is a impersonation user or not. This has to be a value of + * <pre>$EwsClientImpersonationModes.***</pre> + * <br/>See the description of the values there for more information + * @param {String} pTaskDescription <p/> type of the task that the ews client plugin is performing, this has to be a value of + * <pre>$EwsClientTaskDescriptions.***</pre> + * @param {XML} pTaskXML <p/> Depending on the pTaskDescription different information have to be provided to the plugin. + * <br/>In the pTaskXML param all data that is needed for a given task type has to be provided as XML object + * @param {String} pUser <p/> Exchange user that is used for authenticating + * <br/>Keep in mind that you have to set the pImpersonatedUserMode depending on if the pUser is a + * impersonation user or not. + * @param {String} pPassword <p/> Matching password to authenticate the pUser + * + * @return {XML} <p/> Ready to use XML request that can be provided to the EWS client plugin. + * <br/><i>Remember that if you want to log the XML-object you need to call .toString() onto the result</i> + * + * @static + */ +EwsClientXMLUtils.getRequestXMLbasicAuth = function (pUrl, pDomain, pImpersonatedUserMode, pTaskDescription, pTaskXML, pUser, pPassword) +{ + //use xml syntax with placeholders so that the placeholder values are automatically escaped (this is necessary for complex passwords) + var request = <ewsClientPlugin> + <connection> + <connectionURL>{pUrl}</connectionURL> + <connectionUser>{pUser}</connectionUser> + <connectionPassword>{pPassword}</connectionPassword> + <connectionDomain>{pDomain}</connectionDomain> + <impersonatedUserMode>{pImpersonatedUserMode}</impersonatedUserMode> + </connection> + <task> + <description>{pTaskDescription}</description> + </task> + </ewsClientPlugin>; + + //since pTaskXML is of type XML we cannot just use the template mechanism to add the content since the XML would be escaped + //so instead inject it direct as part of XML with the appendChild method of XML-objects + request.task.appendChild(pTaskXML); + + return request; +}; + +/** + * builds a request XML that can be given to the EWS client plugin + * uses basic auth with user and password for authentication, the data is automatically loaded from a given exchange (web service) alias + * + * @param {String} pTaskDescription <p/> type of the task that the ews client plugin is performing, this has to be a value of + * <pre>$EwsClientTaskDescriptions.***</pre> + * @param {XML} pTaskXML <p/> Depending on the pTaskDescription different information have to be provided to the plugin. + * <br/>In the pTaskXML param all data that is needed for a given task type has to be provided as XML object + * @param {String} pImpersonatedUserMode <p/> Specifies if impersonation (when yes: which one) is used for authentication or not. + * This has to be a value of <pre>$EwsClientImpersonationModes.***</pre> + * <br/>See the description of the values there for more information + * @param {String} pAliasName <p/> name of the alias where to load the data for authentication and the host, port, etc. + * + * @return {XML} <p/> Ready to use XML request that can be provided to the EWS client plugin. + * <br/><i>Remember that if you want to log the XML-object you need to call .toString() onto the result</i> + * + * @static + */ +EwsClientXMLUtils.getRequestXMLforAlias = function (pTaskDescription, pTaskXML, pImpersonatedUserMode, pAliasName) +{ + var alias = project.getAliasModel(pAliasName); + var url; + if( alias[project.ALIAS_PROPERTIES]["security"] == 2 ) + { + url = "https://" + alias[project.ALIAS_PROPERTIES]["host"] + ":" + alias[project.ALIAS_PROPERTIES]["port"] + "/ews/Exchange.asmx"; + } + else + { + url = "http://" + alias[project.ALIAS_PROPERTIES]["host"] + ":" + alias[project.ALIAS_PROPERTIES]["port"] + "/ews/Exchange.asmx"; + } + var connectionUser = alias[project.ALIAS_PROPERTIES]["user"]; + var connectionPassword = alias[project.ALIAS_PROPERTIES]["password"]; + var connectionDomain = alias[project.ALIAS_PROPERTIES]["domain"]; + + return EwsClientXMLUtils.getRequestXMLbasicAuth(url, connectionDomain, pImpersonatedUserMode, pTaskDescription, pTaskXML, + connectionUser, connectionPassword); +}; + +/** + * Provides static methods for calendar permission interactions with the EWS client plugin + * + * @class + */ +function EwsClientCalendarPermissionUtils(){} + +/** + * builds a request XML that can be given to the EWS client plugin + * uses basic auth with user and password for authentication, the data is automatically loaded from a given exchange (web service) alias + * + * @param {String} pAliasName <p/> name of the alias where to load the data for authentication and the host, port, etc. + * @param {String} pRequestedMailAddresses <p/> type of the task that the ews client plugin is performing, this has to be a value of + * <pre>$EwsClientTaskDescriptions.***</pre> + * + * @return {XML} <p/> Ready to use XML request that can be provided to the EWS client plugin. + * <br/><i>Remember that if you want to log the XML-object you need to call .toString() onto the result</i> + * + * @static + */ +EwsClientCalendarPermissionUtils.getRequestXMLforAlias = function (pAliasName, pRequestedMailAddresses) +{ + var task = <requesteds> + <requested>CALENDAR</requested> + </requesteds>; + + for (var i = 0, l = pRequestedMailAddresses.length; i < l; i++) + { + var emailAddr = pRequestedMailAddresses[i]; + task.mails += <mail>{emailAddr}</mail>; + } + + var taskDescription = $EwsClientTaskDescriptions.GET_CALENDAR_TASKS_PERMISSIONS(); + var impersonationMode = $EwsClientImpersonationModes.LIST(); + var request = EwsClientXMLUtils.getRequestXMLforAlias(taskDescription, task, impersonationMode, pAliasName); + return request; +}; + + +/** + * builds a request XML that can be given to the EWS client plugin + * uses basic auth with user and password for authentication, the data is automatically loaded from a given exchange (web service) alias + * + * This function will create records in AB_PERMISSIONCALENDAR or update them if they are existant, but it will *NOT* remove entries thar are not any + * more returned from the plugin. + * + * @param {String} pExchangeAliasName <p/> name of the EWS-alias where the permissions are loaded + * + * @return {null} <p/> returns currently nothing + * + * @static + */ +EwsClientCalendarPermissionUtils.writePermissions = function(pExchangeAliasName) +{ + //TODO: refactor this function since this is basically an adjusted version of the legacy-ews-clientsync-code + //e.g. sqls in loops or the readability of the code, etc. could be improved here + + //load all users and then filter for exchange-users + var storedUsers = tools.getStoredUsers(); + var exchangeUserMap = {}; + var requestedUsers = [];//users that a requested within exchange via a plugin call + for( var i = 0; i < storedUsers.length; i++) + { + var storedUser = storedUsers[i]; + var title = storedUser[1]; + var aditoUser = tools.getUser(title); + var userId = EmployeeUtils.sliceUserId(aditoUser[tools.NAME]); + var userParams = aditoUser[tools.PARAMS]; + var exchangeMail = userParams[tools.EXCHANGE_EMAIL];//maybe alternative is: >>userParams[tools.CALENDARID]<<? + if( exchangeMail == undefined || exchangeMail.length == 0 || exchangeMail.search("@exchange.intern") == -1) + continue; + exchangeUserMap[exchangeMail] = userId; + requestedUsers.push(exchangeMail); + } + + var pluginRequest = EwsClientCalendarPermissionUtils.getRequestXMLforAlias(pExchangeAliasName, requestedUsers); + //logging.log("INPUT:\n" + pluginRequest.toString()); + var xmlOutput = EwsClientUtils.callPlugin(pluginRequest); + //logging.log("OUTPUT:\n" + xmlOutput.toString()); + + // read explicit and default permissions and buffer them in maps + var owners = xmlOutput.folderUsers.folderUser; + var owner; + var explicitMap = {}; + var defaultMap = {}; + for each( owner in owners )//XML objects need a "for each (x in y)" loop and not a "for (x in y)" loop + { + var ownerMail = owner.mail; + var folders = owner.folders.folder; + var folderMapDef = {}; + var folderMapEx = {}; + for each( var folder in folders )//XML objects need a "for each (x in y)" loop and not a "for (x in y)" loop + { + var folderName = folder.name;//in therory it is possible read other folder permissions too (e.g. tasks) so let's keep the code generic + var qualifiedUsers = folder.qualifiedUsers.qualifiedUser + var qualifiedUserMapEx = {}; + for each( var qualifiedUser in qualifiedUsers )//XML objects need a "for each (x in y)" loop and not a "for (x in y)" loop + { + var qualifiedUserMail = qualifiedUser.mail + var permissions = qualifiedUser.permissions; + if( "Anonymous" == qualifiedUserMail ) + { + continue + } + else if( "Default" == qualifiedUserMail ) + { + folderMapDef[folderName] = permissions; + defaultMap[ownerMail] = folderMapDef; + } + else + { + qualifiedUserMapEx[qualifiedUserMail] = permissions; + folderMapEx[folderName] = qualifiedUserMapEx; + explicitMap[ownerMail] = folderMapEx; + } + } + } + } + + var dbChangeUser = "server";//vars.get("$sys.user") does not work on the serverside (executing from the manager) //todo: check if this is a bug + var updateCalCols = new Array("USER_EDIT", "DATE_EDIT", "PERMISSION"); + var updateCalTypes = db.getColumnTypes("AB_PERMISSIONCALENDAR", updateCalCols); + var insertCalCols = new Array("AB_PERMISSIONCALENDARID", "DATE_NEW","USER_NEW", + "PERMISSIONPROCURER_ROWID", "PERMISSIONPROCURER_TYPE", "PERMISSIONDEALER_ROWID", "PERMISSIONDEALER_TYPE", "PERMISSION"); + var insertCalTypes = db.getColumnTypes("AB_PERMISSIONCALENDAR", insertCalCols); + var vals; + var right; + + for (var j = 0, l = requestedUsers.length; j < l; j++) + { + owner = requestedUsers[j]; + if (defaultMap[owner] == undefined) //maybe more was requested than actually exists on the exchange server; skip these + continue; + var defaultCalendarPermission = EwsClientCalendarPermissionUtils._getCalendarPermissionFromResult(defaultMap[owner]["CALENDAR"]); + for (var jj = 0, ll = requestedUsers.length; jj < ll; jj++) + { + var qualified = requestedUsers[jj]; + if( qualified == owner ) + { + continue; + } + right = defaultCalendarPermission; + if( explicitMap[owner] !== undefined && explicitMap[owner]["CALENDAR"] !== undefined && explicitMap[owner]["CALENDAR"][qualified] !== undefined ) + { + right = EwsClientCalendarPermissionUtils._getCalendarPermissionFromResult(explicitMap[owner]["CALENDAR"][qualified]); + } + + // combination of owner und User existant? -> update, otherwise insert + + var existingPermissionQuery = newSelect("AB_PERMISSIONCALENDAR.AB_PERMISSIONCALENDARID, AB_PERMISSIONCALENDAR.PERMISSION") + .from("AB_PERMISSIONCALENDAR") + .where("AB_PERMISSIONCALENDAR.PERMISSIONPROCURER_ROWID", exchangeUserMap[qualified]) //this user... + .and("AB_PERMISSIONCALENDAR.PERMISSIONPROCURER_TYPE", $KeywordRegistry.permissionCalendarType$user()) + .and("AB_PERMISSIONCALENDAR.PERMISSIONDEALER_ROWID", exchangeUserMap[owner]) //...has right for this user + .and("AB_PERMISSIONCALENDAR.PERMISSIONDEALER_TYPE", $KeywordRegistry.permissionCalendarType$user()); + var existingPermission = existingPermissionQuery.arrayRow(); + + if (existingPermission.length > 0) + { + if (right != existingPermission[1]) + { + vals = [dbChangeUser, datetime.date(), right]; + newWhere("AB_PERMISSIONCALENDAR.AB_PERMISSIONCALENDARID", existingPermission[0]) + .updateData(true, "AB_PERMISSIONCALENDAR", updateCalCols, updateCalTypes, vals); + } + } + else + { + vals = [util.getNewUUID(), datetime.date(), dbChangeUser, exchangeUserMap[qualified], $KeywordRegistry.permissionCalendarType$user(), + exchangeUserMap[owner], $KeywordRegistry.permissionCalendarType$user(), right]; + db.insertData("AB_PERMISSIONCALENDAR", insertCalCols, insertCalTypes, vals); + } + } + } +}; + + +/** + * Reads a <pre><permissions></pre> node from the ews client plugin result (for calendar permissions) and transforms the exchange grant into the grant value + * of ADITO + * The result of the plugin always contains 2 elements, one for read and one for write + * + * + * @param {XML} pPermissionXML <p/> XML snippet that was returned by the EWS client plugin call + * + * @return {String} <p/> Permission value that is used within PermissionCalendar-module (@see PermissionCalendar_lib) + * @static + */ +EwsClientCalendarPermissionUtils._getCalendarPermissionFromResult = function (pPermissionXML) +{ + var permissions = pPermissionXML.permission; + var readPermission = false; + var writePermission = false; + + /* + The permission.value is on of these: + NO_WRITE, WRITE, READ, NO_READ , TimeOnly, TimeAndSubjectAndLocation + There are always two entires delivered from the plugin that contain any of these values (one for read, one for write) + */ + for each( var permission in permissions )//XML objects need a "for each (x in y)" loop and not a "for (x in y)" loop + { + var inputValue = permission.value; + /* Overview of the values that are retrieved by the EWS plugin: + * "FullDetails" is returned if you've got the grants for: + * - Full details + * - Editor + * - Delegage + * "Timeonly" is returned if the grant is "Availability only" + * "TimeAndSubjectAndLocation" is returned if the grant is "Limited details" + */ + if (inputValue == "TimeOnly") + return $PermissionCalendarCategories.freeBusy(); + else if(inputValue == "TimeAndSubjectAndLocation") + return $PermissionCalendarCategories.limitedRead(); + else if( inputValue == "READ" || inputValue == "FullDetails") + { + readPermission = true; + } + else if( "WRITE" == inputValue ) + { + writePermission = true; + } + } + var retVal = $PermissionCalendarCategories.nothing(); + if (readPermission && writePermission) + retVal = $PermissionCalendarCategories.readWrite(); + else if (readPermission && !writePermission) + retVal = $PermissionCalendarCategories.fullRead(); + else if (!readPermission && writePermission)//write but no read has no representator in adito currently + throw new Error("EwsClientCalendarPermissionUtils._getCalendarPermissionFromResult: Error while determining the calendar permission; " + + "there exists a write but no read permission"); + + return retVal; +} \ No newline at end of file diff --git a/process/KeywordRegistry_basic/process.js b/process/KeywordRegistry_basic/process.js index bd18dea7a2..e8e257f78f 100644 --- a/process/KeywordRegistry_basic/process.js +++ b/process/KeywordRegistry_basic/process.js @@ -248,10 +248,9 @@ $KeywordRegistry.workflowSignalTrigger$create = function(){return "TRIGGEREVENTI $KeywordRegistry.workflowSignalTrigger$update = function(){return "TRIGGEREVENTUPDATE";}; $KeywordRegistry.workflowSignalTrigger$delete = function(){return "TRIGGEREVENTDELETE";}; -$KeywordRegistry.permissionCalendarCategory = function(){return "PermissionCalendarCategory";}; -$KeywordRegistry.permissionCalendarCategory$readwrite = function(){return "READWRITE";}; -$KeywordRegistry.permissionCalendarCategory$nothing = function(){return "NOTHING";}; $KeywordRegistry.permissionCalendarType = function(){return "PermissionCalendarType";}; +$KeywordRegistry.permissionCalendarType$user = function(){return "USER";}; +$KeywordRegistry.permissionCalendarType$department = function(){return "DEPARTMENT";}; $KeywordRegistry.workflowActivityType = function(){return "WorkflowActivityType";}; $KeywordRegistry.workflowActivityType$sequenceFlow = function(){return "sequenceFlow";}; diff --git a/process/PermissionCalendar_lib/PermissionCalendar_lib.aod b/process/PermissionCalendar_lib/PermissionCalendar_lib.aod index 2bb834eb6e..8f5c6970ce 100644 --- a/process/PermissionCalendar_lib/PermissionCalendar_lib.aod +++ b/process/PermissionCalendar_lib/PermissionCalendar_lib.aod @@ -3,6 +3,7 @@ <name>PermissionCalendar_lib</name> <majorModelMode>DISTRIBUTED</majorModelMode> <process>%aditoprj%/process/PermissionCalendar_lib/process.js</process> + <alias>Data_alias</alias> <variants> <element>LIBRARY</element> </variants> diff --git a/process/PermissionCalendar_lib/process.js b/process/PermissionCalendar_lib/process.js index dd64cacccb..453eced128 100644 --- a/process/PermissionCalendar_lib/process.js +++ b/process/PermissionCalendar_lib/process.js @@ -1,3 +1,8 @@ +import("system.vars"); +import("system.util"); +import("system.db"); +import("system.project"); +import("system.plugin"); import("system.translate"); import("system.logging"); import("AttributeRegistry_basic"); @@ -8,23 +13,25 @@ import("KeywordRegistry_basic"); import("system.tools"); import("system.calendars") +/** + * provides static functionality for categories of calendar permissions + * + * @class + */ +function $PermissionCalendarCategories(){} -function PermissionCalendar() {} +$PermissionCalendarCategories.nothing = function (){return "NOTHING";}; +$PermissionCalendarCategories.freeBusy = function (){return "FREEBUSY";}; +$PermissionCalendarCategories.limitedRead = function (){return "LIMITEDREAD";}; +$PermissionCalendarCategories.fullRead = function (){return "FULLREAD";}; +$PermissionCalendarCategories.readWrite = function (){return "READWRITE";}; -PermissionCalendar.objectTypeDepartment = function() -{ - return "DEPARTMENT"; -} - -PermissionCalendar.objectTypeUser = function() -{ - return "USER"; -} +function PermissionCalendar(){} PermissionCalendar.getAlias = function() { return "Data_alias"; -} +}; /** * Returns the permission which is set to those without permissions @@ -33,33 +40,85 @@ PermissionCalendar.getAlias = function() */ PermissionCalendar.getDefaultPermission = function() { - return $KeywordRegistry.permissionCalendarCategory$nothing(); -} + return $PermissionCalendarCategories.nothing(); +}; + + +/** + * Returns the ids of categories that may be set for a specific backendType + * + * @param {bool} [pBackendType=current calendar backend] <p/> type as constant of calendars.BACKEND_***; e.g. calendars.BACKEND_EXCHANGEWS + * + * @return {Array} List of the category ids in the way they are returned by $PermissionCalendarCategories.***, e.g. "NOTHING" + */ +PermissionCalendar.getSetableCategories = function(pBackendType) +{ + var calendarBackendType = pBackendType || calendars.getBackendType(); + //different setable categories may be returned here for different backendtypes + //for example for Lotus Domino or Microsoft Exchange + + //default (ADITO DB Calendar Backend) is currently the same as MS Exchange: + return [$PermissionCalendarCategories.nothing(), + $PermissionCalendarCategories.freeBusy(), + $PermissionCalendarCategories.limitedRead(), + $PermissionCalendarCategories.fullRead(), + $PermissionCalendarCategories.readWrite()]; +}; /** * Returns the categorys with the corresponding fields. If fields is null, every field is allowed to be read. */ -PermissionCalendar.getCategories = function() +PermissionCalendar.getCategories = function(pBackendType) { + var calendarBackendType = pBackendType || calendars.getBackendType(); + var categories = []; - categories["NOTHING"] = {}; - categories["NOTHING"].fields = []; - categories["NOTHING"].writeable = false; + categories[$PermissionCalendarCategories.nothing()] = {}; + categories[$PermissionCalendarCategories.nothing()].fields = []; + categories[$PermissionCalendarCategories.nothing()].writeable = false; + categories[$PermissionCalendarCategories.nothing()].getTitle = function(){ + return translate.text("No permissions"); + }; + + categories[$PermissionCalendarCategories.freeBusy()] = {}; + categories[$PermissionCalendarCategories.freeBusy()].fields = [calendars.ATTENDEES, calendars.DTSTART, calendars.DTEND, calendars.DUE, calendars.DURATION]; + categories[$PermissionCalendarCategories.freeBusy()].writeable = false; + categories[$PermissionCalendarCategories.freeBusy()].getTitle = function(){ + if (calendarBackendType == calendars.BACKEND_EXCHANGEWS) + return translate.text("Availability only"); + return translate.text("Free or Busy Permission"); + }; - categories["LIMITEDREAD"] = {}; - categories["LIMITEDREAD"].fields = [calendars.ATTENDEES, calendars.DTSTART, calendars.DTEND, calendars.DUE, calendars.DURATION]; - categories["LIMITEDREAD"].writeable = false; + categories[$PermissionCalendarCategories.limitedRead()] = {}; + categories[$PermissionCalendarCategories.limitedRead()].fields = [calendars.ATTENDEES, calendars.DTSTART, calendars.DTEND, calendars.DUE, calendars.DURATION, + calendars.SUMMARY, calendars.LOCATION]; + categories[$PermissionCalendarCategories.limitedRead()].writeable = false; + categories[$PermissionCalendarCategories.limitedRead()].getTitle = function(){ + if (calendarBackendType == calendars.BACKEND_EXCHANGEWS) + return translate.text("Limited details"); + return translate.text("Limited Read Permission"); + }; - categories["FULLREAD"] = {}; - categories["FULLREAD"].fields = null; - categories["FULLREAD"].writeable = false; + categories[$PermissionCalendarCategories.fullRead()] = {}; + categories[$PermissionCalendarCategories.fullRead()].fields = null; + categories[$PermissionCalendarCategories.fullRead()].writeable = false; + categories[$PermissionCalendarCategories.fullRead()].getTitle = function(){ + if (calendarBackendType == calendars.BACKEND_EXCHANGEWS) + return translate.text("Full details"); + return translate.text("Full Read Permission"); + }; - categories["READWRITE"] = {}; - categories["READWRITE"].fields = null; - categories["READWRITE"].writeable = true; + categories[$PermissionCalendarCategories.readWrite()] = {}; + categories[$PermissionCalendarCategories.readWrite()].fields = null; + categories[$PermissionCalendarCategories.readWrite()].writeable = true; + categories[$PermissionCalendarCategories.readWrite()].getTitle = function(){ + if (calendarBackendType == calendars.BACKEND_EXCHANGEWS) + return translate.text("Editor"); + return translate.text("Read and Write Permission"); + }; return categories; -} +}; /** * Returns the objecttype of the passed rowId. @@ -71,10 +130,10 @@ PermissionCalendar.getCategories = function() PermissionCalendar.getObjectType = function(pObjectRowId) { if(pObjectRowId.length > 36) - return PermissionCalendar.objectTypeUser(); + return $KeywordRegistry.permissionCalendarType$user(); else - return PermissionCalendar.objectTypeDepartment(); -} + return $KeywordRegistry.permissionCalendarType$department(); +}; /** * Returns for a permission-value the responding view-value. @@ -84,8 +143,12 @@ PermissionCalendar.getObjectType = function(pObjectRowId) */ PermissionCalendar.getPermissionDisplay = function(pPermissionId) { - return KeywordUtils.getViewValue($KeywordRegistry.permissionCalendarCategory(), pPermissionId.trim()); -} + var properties = PermissionCalendar.getCategories(null)[pPermissionId.trim()]; + if (!properties) + return pPermissionId; + var title = properties.getTitle(); + return title; +}; /** * Returns the display-value for a rowId. Attention: If the type is User, the rowId must be without the prefix. @@ -96,7 +159,7 @@ PermissionCalendar.getPermissionDisplay = function(pPermissionId) */ PermissionCalendar.getNameDisplay = function(pRowId, pType) { - if(pType == PermissionCalendar.objectTypeUser()) + if(pType == $KeywordRegistry.permissionCalendarType$user()) { let user = tools.getUserByAttribute(tools.NAME, EmployeeUtils.prefixUserId(pRowId), tools.PROFILE_TITLE); if(user != null) @@ -104,7 +167,7 @@ PermissionCalendar.getNameDisplay = function(pRowId, pType) else return "undefined"; } - else if(pType == PermissionCalendar.objectTypeDepartment()) + else if(pType == $KeywordRegistry.permissionCalendarType$department()) { let dept = new SqlBuilder().select("AB_Attribute.ATTRIBUTE_NAME") .from("AB_Attribute") @@ -119,7 +182,7 @@ PermissionCalendar.getNameDisplay = function(pRowId, pType) } else return "undefined"; -} +}; /** * Checks, if an permission for the passed combination of parameters exists. @@ -142,7 +205,7 @@ PermissionCalendar.isPermissionExisting = function(pPermissionDealer_RowId, pPer return true; else return false; -} +}; /** * Sets the permissions of the passed user. It is highly recommend to use this function for the autostart. @@ -156,7 +219,7 @@ PermissionCalendar.setPermissions = function(pUserId) let tree = PermissionCalendar.getTree(pUserId); tree.forEach(function(item, i) { - if(item[1] == PermissionCalendar.objectTypeUser()) + if(item[1] == $KeywordRegistry.permissionCalendarType$user()) { if(!res[item[3]]) { @@ -181,7 +244,7 @@ PermissionCalendar.setPermissions = function(pUserId) } // User itself can read and write his own calendar calendars.addPermissions([EmployeeUtils.getCurrentUserName()], calendars.VEVENT, ["READ", "WRITE"], categories["READWRITE"].fields , false, calendars.SORTSTRATEGY_NATURAL); -} +}; /** * Builds the tree with all departments, users and permissions for the passed userId. @@ -201,7 +264,7 @@ PermissionCalendar.getTree = function(pCurrentUser) return resultArr; resultArr = []; -} +}; /** * Get all Permissions of the Departments and Users recursive @@ -223,7 +286,7 @@ PermissionCalendar._getDataRecursive = function(pRoot, pCurrentUser, pPermission { PermissionCalendar._getDataRecursive(item, pCurrentUser, pPermissions, pUser, pResultArr); }); -} +}; /** * Checks the permissions of the User and whether the user inherits permissions @@ -256,12 +319,12 @@ PermissionCalendar._createRowUser = function(pDept, inheritedPermission, pCurren } if(flag) { - pResultArr.push([user[0], PermissionCalendar.objectTypeUser(), user[1], inheritedPermission]); + pResultArr.push([user[0], $KeywordRegistry.permissionCalendarType$user(), user[1], inheritedPermission]); } } } }); -} +}; /** * Get the root-Department with the permissions @@ -283,7 +346,7 @@ PermissionCalendar._getDepartment = function(pAttributeId, pPermissions, pResult // If there is no permission set for the Root-deparment, then the default-permission shoud be used let inherited = PermissionCalendar.getDefaultPermission(); return PermissionCalendar._createRowDept(d, inherited, pPermissions, pResultArr); -} +}; /** * Returns all subordinate departments of pParentId @@ -304,7 +367,7 @@ PermissionCalendar._getDepartments = function(pParentId, inheritedPermission, pP .table(); return PermissionCalendar._createRowDept(dept, inheritedPermission, pPermissions, pResultArr); -} +}; /** * Checks the Permissions of the Departments and whether the departments inherits permissions @@ -333,12 +396,12 @@ PermissionCalendar._createRowDept = function(pTable, inheritedPermission, pPermi } if(!flag) { - temp.push([pTable[i][0], PermissionCalendar.objectTypeDepartment(), pTable[i][2], inheritedPermission]); + temp.push([pTable[i][0], $KeywordRegistry.permissionCalendarType$department(), pTable[i][2], inheritedPermission]); } } pResultArr = pResultArr.concat(temp); return temp; -} +}; /** * Returns all permisisons of the passed user. @@ -354,7 +417,7 @@ PermissionCalendar.getPermissions = function(pCurrentUser) .where("AB_PERMISSIONCALENDAR.PERMISSIONPROCURER_ROWID", pCurrentUser) .orderBy("PERMISSIONDEALER_ROWID ASC") .table(); -} +}; /* * Returns all active users @@ -370,7 +433,7 @@ PermissionCalendar._getUser = function() user[tools.PARAMS].department ]; }); -} +}; /* * Returns all departments over the User @@ -394,7 +457,5 @@ PermissionCalendar.getAllParents = function(pUserId) .arrayColumn()[0]; } - logging.log(JSON.stringify(departments)); return departments; - -} +}; \ No newline at end of file diff --git a/process/ewsSyncCalendarPermissions_serverProcess/ewsSyncCalendarPermissions_serverProcess.aod b/process/ewsSyncCalendarPermissions_serverProcess/ewsSyncCalendarPermissions_serverProcess.aod new file mode 100644 index 0000000000..703deab522 --- /dev/null +++ b/process/ewsSyncCalendarPermissions_serverProcess/ewsSyncCalendarPermissions_serverProcess.aod @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.2.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.2.1"> + <name>ewsSyncCalendarPermissions_serverProcess</name> + <title>Synchronize calendar permissions from Exchange to ADITO</title> + <majorModelMode>DISTRIBUTED</majorModelMode> + <process>%aditoprj%/process/ewsSyncCalendarPermissions_serverProcess/process.js</process> + <alias>Data_alias</alias> + <variants> + <element>EXECUTABLE</element> + </variants> +</process> diff --git a/process/ewsSyncCalendarPermissions_serverProcess/process.js b/process/ewsSyncCalendarPermissions_serverProcess/process.js new file mode 100644 index 0000000000..21565f9c37 --- /dev/null +++ b/process/ewsSyncCalendarPermissions_serverProcess/process.js @@ -0,0 +1,3 @@ +import("EwsClient_lib"); + +EwsClientCalendarPermissionUtils.writePermissions("Exchange_devIntern"); \ No newline at end of file -- GitLab